add macros to the doc
This commit is contained in:
parent
2a0b05f59f
commit
2936c0363b
44 changed files with 935 additions and 98 deletions
|
|
@ -92,7 +92,7 @@ Features</h1>
|
|||
<p>Additionally, Clutchlog will do its best to allow the compiler to optimize out calls, for instance debug messages in "Release" builds.</p>
|
||||
<h1><a class="anchor" id="autotoc_md1"></a>
|
||||
Example</h1>
|
||||
<p>Adding a message is a simple as calling a macro (which is declutched in Debug build type, when <code>NDEBUG</code> is not defined): </p><div class="fragment"><div class="line">CLUTCHLOG(info, <span class="stringliteral">"matrix size: "</span> << m << <span class="stringliteral">"x"</span> << n);</div></div><!-- fragment --><p>To configure the display, you indicate the three types of locations, for example in your <code>main</code> function: </p><div class="fragment"><div class="line"><span class="keyword">auto</span>& log = <a class="code" href="classclutchlog.html#acfaceb77da01503b432644a3efaee4fa">clutchlog::logger</a>();</div><div class="line">log.depth(2); <span class="comment">// Log functions called from "main" but not below.</span></div><div class="line">log.threshold(clutchlog::level::info); <span class="comment">// Log only "info", "warning", "error" or "critical" messages.</span></div><div class="line">log.file(<span class="stringliteral">"algebra/.*"</span>); <span class="comment">// Will match any file in the "algebra" directory.</span></div><div class="line">log.func(<span class="stringliteral">"(mul|add|sub|div)"</span>); <span class="comment">// Will match "multiply", for instance.</span></div></div><!-- fragment --><p>For more detailled examples, see the "API documentation" section below and the <code>tests</code> directory.</p>
|
||||
<p>Adding a message is a simple as calling a macro (which is declutched in Debug build type, when <code>NDEBUG</code> is not defined): </p><div class="fragment"><div class="line"><a class="code" href="group__UseMacros.html#ga6f86187e2b35e7e1907d688f504a197d">CLUTCHLOG</a>(info, <span class="stringliteral">"matrix size: "</span> << m << <span class="stringliteral">"x"</span> << n);</div></div><!-- fragment --><p>To configure the display, you indicate the three types of locations, for example in your <code>main</code> function: </p><div class="fragment"><div class="line"><span class="keyword">auto</span>& log = <a class="code" href="classclutchlog.html#acfaceb77da01503b432644a3efaee4fa">clutchlog::logger</a>();</div><div class="line">log.depth(2); <span class="comment">// Log functions called from "main" but not below.</span></div><div class="line">log.threshold(clutchlog::level::info); <span class="comment">// Log only "info", "warning", "error" or "critical" messages.</span></div><div class="line">log.file(<span class="stringliteral">"algebra/.*"</span>); <span class="comment">// Will match any file in the "algebra" directory.</span></div><div class="line">log.func(<span class="stringliteral">"(mul|add|sub|div)"</span>); <span class="comment">// Will match "multiply", for instance.</span></div></div><!-- fragment --><p>For more detailled examples, see the "API documentation" section below and the <code>tests</code> directory.</p>
|
||||
<h1><a class="anchor" id="autotoc_md2"></a>
|
||||
Rationale</h1>
|
||||
<p>Most of existing logging systems targets service events storage, like fast queuing of transactions in a round-robin database. Their aim is to provide a simple interface to efficiently store messages somewhere, which is appropriated when you have a well known service running and you want to be able to trace complex users interactions across its states.</p>
|
||||
|
|
@ -103,7 +103,7 @@ Rationale</h1>
|
|||
API documentation</h1>
|
||||
<h2><a class="anchor" id="autotoc_md4"></a>
|
||||
Calls</h2>
|
||||
<p>The main entrypoint is the <code>CLUTCHLOG</code> macro, which takes the desired log level and message. The message can be anything which can be output in an <code>ostringstream</code>. </p><div class="fragment"><div class="line"><span class="comment">// Simple string:</span></div><div class="line">CLUTCHLOG(info, <span class="stringliteral">"hello world"</span>);</div><div class="line"></div><div class="line"><span class="comment">// Serialisable variable:</span></div><div class="line"><span class="keywordtype">double</span> value = 0;</div><div class="line">CLUTCHLOG(error, value);</div><div class="line"></div><div class="line"><span class="comment">// passed using inline output stream operators:</span></div><div class="line">CLUTCHLOG(debug, <span class="stringliteral">"hello "</span> << value << <span class="stringliteral">" world"</span>);</div></div><!-- fragment --><p>There is also a macro to dump the content of an iterable within a separate file: <code>CLUTCHDUMP</code>. This function takes care of incrementing a numeric suffix in the file name, if an existing file with this name exists. </p><div class="fragment"><div class="line">std::vector<int> v(10);</div><div class="line">std::generate(v.begin(), v.end(), std::rand);</div><div class="line">CLUTCHLOG(debug, vec, <span class="stringliteral">"test_{n}.dat"</span>);</div><div class="line"><span class="comment">/* Will output in cat "rand_0.dat"</span></div><div class="line"><span class="comment">* # [t-dump] Info in main (at depth 5) @ /home/nojhan/code/clutchlog/tests/t-dump.cpp:22</span></div><div class="line"><span class="comment">* 1804289383</span></div><div class="line"><span class="comment">* 846930886</span></div><div class="line"><span class="comment">* 1681692777</span></div><div class="line"><span class="comment">*/</span></div></div><!-- fragment --><p> Note that if you pass a file name without the <code>{n}</code> tag, the file will be overwritten as is.</p>
|
||||
<p>The main entrypoint is the <code>CLUTCHLOG</code> macro, which takes the desired log level and message. The message can be anything which can be output in an <code>ostringstream</code>. </p><div class="fragment"><div class="line"><span class="comment">// Simple string:</span></div><div class="line"><a class="code" href="group__UseMacros.html#ga6f86187e2b35e7e1907d688f504a197d">CLUTCHLOG</a>(info, <span class="stringliteral">"hello world"</span>);</div><div class="line"></div><div class="line"><span class="comment">// Serialisable variable:</span></div><div class="line"><span class="keywordtype">double</span> value = 0;</div><div class="line"><a class="code" href="group__UseMacros.html#ga6f86187e2b35e7e1907d688f504a197d">CLUTCHLOG</a>(error, value);</div><div class="line"></div><div class="line"><span class="comment">// passed using inline output stream operators:</span></div><div class="line"><a class="code" href="group__UseMacros.html#ga6f86187e2b35e7e1907d688f504a197d">CLUTCHLOG</a>(debug, <span class="stringliteral">"hello "</span> << value << <span class="stringliteral">" world"</span>);</div></div><!-- fragment --><p>There is also a macro to dump the content of an iterable within a separate file: <code>CLUTCHDUMP</code>. This function takes care of incrementing a numeric suffix in the file name, if an existing file with this name exists. </p><div class="fragment"><div class="line">std::vector<int> v(10);</div><div class="line">std::generate(v.begin(), v.end(), std::rand);</div><div class="line"><a class="code" href="group__UseMacros.html#ga6f86187e2b35e7e1907d688f504a197d">CLUTCHLOG</a>(debug, vec, <span class="stringliteral">"test_{n}.dat"</span>);</div><div class="line"><span class="comment">/* Will output in cat "rand_0.dat"</span></div><div class="line"><span class="comment">* # [t-dump] Info in main (at depth 5) @ /home/nojhan/code/clutchlog/tests/t-dump.cpp:22</span></div><div class="line"><span class="comment">* 1804289383</span></div><div class="line"><span class="comment">* 846930886</span></div><div class="line"><span class="comment">* 1681692777</span></div><div class="line"><span class="comment">*/</span></div></div><!-- fragment --><p> Note that if you pass a file name without the <code>{n}</code> tag, the file will be overwritten as is.</p>
|
||||
<h2><a class="anchor" id="autotoc_md5"></a>
|
||||
Location filtering</h2>
|
||||
<p>To configure the global behaviour of the logger, you must first get a reference on its (singleton) instance: </p><div class="fragment"><div class="line"><span class="keyword">auto</span>& log = <a class="code" href="classclutchlog.html#acfaceb77da01503b432644a3efaee4fa">clutchlog::logger</a>();</div></div><!-- fragment --><p>One can configure the location(s) at which messages should actually be logged: </p><div class="fragment"><div class="line">log.depth(3); <span class="comment">// Depth of the call stack, defaults to the maximum possible value.</span></div><div class="line">log.threshold(clutchlog::level::error); <span class="comment">// Log level, defaults to error.</span></div></div><!-- fragment --><p> Current levels are defined in an enumeration as <code><a class="el" href="classclutchlog.html#a10fd25a1b51c8c95bd6d876ce1b4b928" title="Available log levels. ">clutchlog::level</a></code>: </p><div class="fragment"><div class="line"><span class="keyword">enum</span> level {critical=0, error=1, warning=2, progress=3, note=4, info=5, debug=6, xdebug=7};</div></div><!-- fragment --><p>File, function and line filters are indicated using (ECMAScript) regular expressions: </p><div class="fragment"><div class="line">log.file(<span class="stringliteral">".*"</span>); <span class="comment">// File location, defaults to any.</span></div><div class="line">log.func(<span class="stringliteral">".*"</span>); <span class="comment">// Function location, defaults to any.</span></div><div class="line">log.line(<span class="stringliteral">".*"</span>); <span class="comment">// Line location, defaults to any.</span></div></div><!-- fragment --><p> A shortcut function can be used to filter all at once: </p><div class="fragment"><div class="line">log.location(file, func, line); <span class="comment">// Defaults to any, second and last parameters being optional.</span></div></div><!-- fragment --><p>Strings may be used to set up the threshold, using <code>level_of</code>: </p><div class="fragment"><div class="line">log.threshold( log.level_of(<span class="stringliteral">"XDebug"</span>) ); <span class="comment">// You have to know the exact string.</span></div></div><!-- fragment --><p> Note that the case of the log levels strings matters (see below).</p>
|
||||
|
|
@ -162,7 +162,7 @@ Disabled calls</h2>
|
|||
<p>This behavior intend to remove as many conditional statements as possible when not debugging, without having to use preprocessor guards around calls to clutchlog, thus saving run time at no readability cost.</p>
|
||||
<h2><a class="anchor" id="autotoc_md9"></a>
|
||||
Low-level API</h2>
|
||||
<p>All configuration setters have a getters counterpart, with the same name but taking no parameter, for example: </p><div class="fragment"><div class="line">std::string mark = log.depth_mark();</div></div><!-- fragment --><p>To control more precisely the logging, one can use the low-level <code>log</code> method: </p><div class="fragment"><div class="line">log.log(clutchlog::level::xdebug, <span class="stringliteral">"hello world"</span>, <span class="stringliteral">"main.cpp"</span>, <span class="stringliteral">"main"</span>, 122);</div></div><!-- fragment --><p> A helper macro can helps to fill in the location with the actual one, as seen by the compiler: </p><div class="fragment"><div class="line">log.log(clutchlog::level::xdebug, <span class="stringliteral">"hello world"</span>, CLUTCHLOC);</div></div><!-- fragment --><p> A similar <code>dump</code> method exists: </p><div class="fragment"><div class="line">log.dump(clutchlog::level::xdebug, cont.begin(), cont.end(), CLUTCHLOC, <span class="stringliteral">"dumped_{n}.dat"</span>, <span class="stringliteral">"\n"</span>);</div><div class="line">log.dump(clutchlog::level::xdebug, cont.begin(), cont.end(), <span class="stringliteral">"main.cpp"</span>, <span class="stringliteral">"main"</span>, 122, <span class="stringliteral">"dumped.dat"</span>, <span class="stringliteral">"\n\n"</span>);</div></div><!-- fragment --><h1><a class="anchor" id="autotoc_md10"></a>
|
||||
<p>All configuration setters have a getters counterpart, with the same name but taking no parameter, for example: </p><div class="fragment"><div class="line">std::string mark = log.depth_mark();</div></div><!-- fragment --><p>To control more precisely the logging, one can use the low-level <code>log</code> method: </p><div class="fragment"><div class="line">log.log(clutchlog::level::xdebug, <span class="stringliteral">"hello world"</span>, <span class="stringliteral">"main.cpp"</span>, <span class="stringliteral">"main"</span>, 122);</div></div><!-- fragment --><p> A helper macro can helps to fill in the location with the actual one, as seen by the compiler: </p><div class="fragment"><div class="line">log.log(clutchlog::level::xdebug, <span class="stringliteral">"hello world"</span>, <a class="code" href="group__UseMacros.html#gae8911119d726a43b77f5781cb5a72813">CLUTCHLOC</a>);</div></div><!-- fragment --><p> A similar <code>dump</code> method exists: </p><div class="fragment"><div class="line">log.dump(clutchlog::level::xdebug, cont.begin(), cont.end(), <a class="code" href="group__UseMacros.html#gae8911119d726a43b77f5781cb5a72813">CLUTCHLOC</a>, <span class="stringliteral">"dumped_{n}.dat"</span>, <span class="stringliteral">"\n"</span>);</div><div class="line">log.dump(clutchlog::level::xdebug, cont.begin(), cont.end(), <span class="stringliteral">"main.cpp"</span>, <span class="stringliteral">"main"</span>, 122, <span class="stringliteral">"dumped.dat"</span>, <span class="stringliteral">"\n\n"</span>);</div></div><!-- fragment --><h1><a class="anchor" id="autotoc_md10"></a>
|
||||
Log level semantics</h1>
|
||||
<p>Log levels use a classical semantics for a human skilled in the art, in decreasing order of importance:</p>
|
||||
<ul>
|
||||
|
|
@ -175,7 +175,7 @@ Log level semantics</h1>
|
|||
<li><em>Debug</em>: data which would help debugging the program if there was a bug later on.</li>
|
||||
<li><em>XDebug</em>: debugging information which would be heavy to read.</li>
|
||||
</ul>
|
||||
<p>Note: the log levels constants are lower case (for example: <code><a class="el" href="classclutchlog.html#a10fd25a1b51c8c95bd6d876ce1b4b928" title="Available log levels. ">clutchlog::level</a>:xdebug</code>), but their string representation is not (e.g. "XDebug", this should be taken into account when using <code>level_of</code>).</p>
|
||||
<p>Note: the log levels constants are lower case (for example: <code>clutchlog::level::xdebug</code>), but their string representation is not (e.g. "XDebug", this should be taken into account when using <code>level_of</code>).</p>
|
||||
<h1><a class="anchor" id="autotoc_md11"></a>
|
||||
Limitations</h1>
|
||||
<p>Because the call stack depth and program name access are system-dependent, the features relying on the depth of the call stack and the display of the program name are only available for operating systems having the following headers: <code>execinfo.h</code>, <code>stdlib.h</code> and <code>libgen.h</code> (so far, tested with Linux).</p>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue