• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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">&amp;</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">&lt;&lt;</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">&lt;&lt;</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