1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 4<title>Creating loggers and writing logs</title> 5<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css"> 6<meta name="generator" content="DocBook XSL Stylesheets V1.79.1"> 7<link rel="home" href="../../index.html" title="Chapter 1. Boost.Log v2"> 8<link rel="up" href="../tutorial.html" title="Tutorial"> 9<link rel="prev" href="sinks.html" title="Setting up sinks"> 10<link rel="next" href="attributes.html" title="Adding more information to log: Attributes"> 11</head> 12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> 13<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td></tr></table> 14<hr> 15<div class="spirit-nav"> 16<a accesskey="p" href="sinks.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="attributes.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> 17</div> 18<div class="section"> 19<div class="titlepage"><div><div><h3 class="title"> 20<a name="log.tutorial.sources"></a><a class="link" href="sources.html" title="Creating loggers and writing logs">Creating loggers and writing logs</a> 21</h3></div></div></div> 22<h5> 23<a name="log.tutorial.sources.h0"></a> 24 <span class="phrase"><a name="log.tutorial.sources.dedicated_logger_objects"></a></span><a class="link" href="sources.html#log.tutorial.sources.dedicated_logger_objects">Dedicated 25 logger objects</a> 26 </h5> 27<p> 28 Now that we have defined where and how the log is to be stored, it's time 29 to go on and try logging. In order to do this one has to create a logging 30 source. This would be a logger object in our case and it is as simple as 31 that: 32 </p> 33<pre class="programlisting"><span class="identifier">src</span><span class="special">::</span><span class="identifier">logger</span> <span class="identifier">lg</span><span class="special">;</span> 34</pre> 35<div class="note"><table border="0" summary="Note"> 36<tr> 37<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td> 38<th align="left">Note</th> 39</tr> 40<tr><td align="left" valign="top"><p> 41 A curious reader could have noticed that we did not create any loggers 42 for trivial logging. In fact the logger is provided by the library and 43 is used behind the scenes. 44 </p></td></tr> 45</table></div> 46<p> 47 Unlike sinks, sources need not be registered anywhere since they interact 48 directly with the logging core. Also note that there are two versions of 49 loggers provided by the library: the thread-safe ones and the non-thread-safe 50 ones. For the non-thread-safe loggers it is safe for different threads to 51 write logs through different instances of loggers and thus there should be 52 a separate logger for each thread that writes logs. The thread-safe counterparts 53 can be accessed from different threads concurrently, but this will involve 54 locking and may slow things down in case of intense logging. The thread-safe 55 logger types have the <code class="computeroutput"><span class="identifier">_mt</span></code> 56 suffix in their name. 57 </p> 58<p> 59 Regardless of the thread safety, all loggers provided by the library are 60 default and copy-constructible and support swapping, so there should be no 61 problem in making a logger a member of your class. As you will see later, 62 such approach can give you additional benefits. 63 </p> 64<p> 65 The library provides a number of loggers with different features, such as 66 severity and channel support. These features can be combined with each other 67 in order to construct more complex loggers. See <a class="link" href="../detailed/sources.html" title="Logging sources">here</a> 68 for more details. 69 </p> 70<h5> 71<a name="log.tutorial.sources.h1"></a> 72 <span class="phrase"><a name="log.tutorial.sources.global_logger_objects"></a></span><a class="link" href="sources.html#log.tutorial.sources.global_logger_objects">Global 73 logger objects</a> 74 </h5> 75<p> 76 In case you cannot put a logger into your class (suppose you don't have one), 77 the library provides a way of declaring global loggers like this: 78 </p> 79<pre class="programlisting"><span class="identifier">BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT</span><span class="special">(</span><span class="identifier">my_logger</span><span class="special">,</span> <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger_mt</span><span class="special">)</span> 80</pre> 81<p> 82 Here <code class="computeroutput"><span class="identifier">my_logger</span></code> is a user-defined 83 tag name that will be used later to retrieve the logger instance and <code class="computeroutput"><span class="identifier">logger_mt</span></code> is the logger type. Any logger 84 type provided by the library or defined by the user can participate in such 85 declaration. However, since the logger will have a single instance, you will 86 normally want to use thread-safe loggers in a multithreaded application as 87 global ones. 88 </p> 89<div class="tip"><table border="0" summary="Tip"> 90<tr> 91<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td> 92<th align="left">Tip</th> 93</tr> 94<tr><td align="left" valign="top"><p> 95 There are other macros for more sophisticated cases available. The detailed 96 description is in <a class="link" href="../detailed/sources.html#log.detailed.sources.global_storage" title="Global storage for loggers">this</a> 97 section. 98 </p></td></tr> 99</table></div> 100<p> 101 Later on you can acquire the logger like this: 102 </p> 103<pre class="programlisting"><span class="identifier">src</span><span class="special">::</span><span class="identifier">logger_mt</span><span class="special">&</span> <span class="identifier">lg</span> <span class="special">=</span> <span class="identifier">my_logger</span><span class="special">::</span><span class="identifier">get</span><span class="special">();</span> 104</pre> 105<p> 106 The <code class="computeroutput"><span class="identifier">lg</span></code> will refer to the 107 one and only instance of the logger throughout the application, even if the 108 application consists of multiple modules. The <code class="computeroutput"><span class="identifier">get</span></code> 109 function itself is thread-safe, so there is no need in additional synchronization 110 around it. 111 </p> 112<h5> 113<a name="log.tutorial.sources.h2"></a> 114 <span class="phrase"><a name="log.tutorial.sources.writing_logs"></a></span><a class="link" href="sources.html#log.tutorial.sources.writing_logs">Writing 115 logs</a> 116 </h5> 117<p> 118 No matter what kind of logger you use (class member or global, thread-safe 119 or not), to write a log record into a logger you can write something like 120 this: 121 </p> 122<p> 123</p> 124<pre class="programlisting"><span class="identifier">logging</span><span class="special">::</span><span class="identifier">record</span> <span class="identifier">rec</span> <span class="special">=</span> <span class="identifier">lg</span><span class="special">.</span><span class="identifier">open_record</span><span class="special">();</span> 125<span class="keyword">if</span> <span class="special">(</span><span class="identifier">rec</span><span class="special">)</span> 126<span class="special">{</span> 127 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">record_ostream</span> <span class="identifier">strm</span><span class="special">(</span><span class="identifier">rec</span><span class="special">);</span> 128 <span class="identifier">strm</span> <span class="special"><<</span> <span class="string">"Hello, World!"</span><span class="special">;</span> 129 <span class="identifier">strm</span><span class="special">.</span><span class="identifier">flush</span><span class="special">();</span> 130 <span class="identifier">lg</span><span class="special">.</span><span class="identifier">push_record</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">rec</span><span class="special">));</span> 131<span class="special">}</span> 132</pre> 133<p> 134 </p> 135<p> 136 Here the <code class="computeroutput"><span class="identifier">open_record</span></code> function 137 call determines if the record to be constructed is going to be consumed by 138 at least one sink. Filtering is applied at this stage. If the record is to 139 be consumed, the function returns a valid record object, and one can fill 140 in the record message string. After that the record processing can be completed 141 with the call to <code class="computeroutput"><span class="identifier">push_record</span></code>. 142 </p> 143<p> 144 Of course, the above syntax can easily be wrapped in a macro and, in fact, 145 users are encouraged to write their own macros instead of using the C++ logger 146 interface directly. The log record above can be written like this: 147 </p> 148<pre class="programlisting"><span class="identifier">BOOST_LOG</span><span class="special">(</span><span class="identifier">lg</span><span class="special">)</span> <span class="special"><<</span> <span class="string">"Hello, World!"</span><span class="special">;</span> 149</pre> 150<p> 151 Looks a bit shorter, doesn't it? The <code class="computeroutput"><span class="identifier">BOOST_LOG</span></code> 152 macro, along with other similar ones, is defined by the library. It automatically 153 provides an STL-like stream in order to format the message with ordinary 154 insertion expressions. Having all that code written, compiled and executed 155 you should be able to see the "Hello, World!" record in the "sample.log" 156 file. You will find the full code of this section <a href="../../../../../../libs/log/example/doc/tutorial_logging.cpp" target="_top">here</a>. 157 </p> 158</div> 159<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 160<td align="left"></td> 161<td align="right"><div class="copyright-footer">Copyright © 2007-2019 Andrey Semashev<p> 162 Distributed under the Boost Software License, Version 1.0. (See accompanying 163 file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>). 164 </p> 165</div></td> 166</tr></table> 167<hr> 168<div class="spirit-nav"> 169<a accesskey="p" href="sinks.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="attributes.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> 170</div> 171</body> 172</html> 173