• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4<title>Setting up sinks</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="trivial_filtering.html" title="Trivial logging with filters">
10<link rel="next" href="sources.html" title="Creating loggers and writing logs">
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="trivial_filtering.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="sources.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.sinks"></a><a class="link" href="sinks.html" title="Setting up sinks">Setting up sinks</a>
21</h3></div></div></div>
22<p>
23        Sometimes trivial logging doesn't provide enough flexibility. For example,
24        one may want a more sophisticated logic of log processing, rather than simply
25        printing it on the console. In order to customize this, you have to construct
26        logging sinks and register them with the logging core. This should normally
27        be done only once somewhere in the startup code of your application.
28      </p>
29<div class="note"><table border="0" summary="Note">
30<tr>
31<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
32<th align="left">Note</th>
33</tr>
34<tr><td align="left" valign="top"><p>
35          It must be mentioned that in the previous sections we did not initialize
36          any sinks, and trivial logging worked somehow anyway. This is because the
37          library contains a <span class="emphasis"><em>default</em></span> sink that is used as a
38          fallback when the user did not set up any sinks. This sink always prints
39          log records to the console in a fixed format which we saw in our previous
40          examples. The default sink is mostly provided to allow trivial logging
41          to be used right away, without any library initialization whatsoever. Once
42          you add any sinks to the logging core, the default sink will no longer
43          be used. You will still be able to use trivial logging macros though.
44        </p></td></tr>
45</table></div>
46<h5>
47<a name="log.tutorial.sinks.h0"></a>
48        <span class="phrase"><a name="log.tutorial.sinks.file_logging_unleashed"></a></span><a class="link" href="sinks.html#log.tutorial.sinks.file_logging_unleashed">File
49        logging unleashed</a>
50      </h5>
51<p>
52        As a starting point, here is how you would initialize logging to a file:
53      </p>
54<p>
55</p>
56<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">init</span><span class="special">()</span>
57<span class="special">{</span>
58    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">add_file_log</span><span class="special">(</span><span class="string">"sample.log"</span><span class="special">);</span>
59
60    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">()-&gt;</span><span class="identifier">set_filter</span>
61    <span class="special">(</span>
62        <span class="identifier">logging</span><span class="special">::</span><span class="identifier">trivial</span><span class="special">::</span><span class="identifier">severity</span> <span class="special">&gt;=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">trivial</span><span class="special">::</span><span class="identifier">info</span>
63    <span class="special">);</span>
64<span class="special">}</span>
65</pre>
66<p>
67      </p>
68<p>
69        The added piece is the call to the <a class="link" href="../detailed/utilities.html#log.detailed.utilities.setup.convenience" title="Convenience functions"><code class="computeroutput"><span class="identifier">add_file_log</span></code></a> function. As the name
70        implies, the function initializes a logging sink that stores log records
71        into a text file. The function also accepts a number of customization options,
72        such as the file rotation interval and size limits. For instance:
73      </p>
74<p>
75</p>
76<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">init</span><span class="special">()</span>
77<span class="special">{</span>
78    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">add_file_log</span>
79    <span class="special">(</span>
80        <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">file_name</span> <span class="special">=</span> <span class="string">"sample_%N.log"</span><span class="special">,</span>                                        <a class="co" name="log.tutorial.sinks.c0" href="sinks.html#log.tutorial.sinks.c1"><img src="../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a>
81        <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">rotation_size</span> <span class="special">=</span> <span class="number">10</span> <span class="special">*</span> <span class="number">1024</span> <span class="special">*</span> <span class="number">1024</span><span class="special">,</span>                                   <a class="co" name="log.tutorial.sinks.c2" href="sinks.html#log.tutorial.sinks.c3"><img src="../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a>
82        <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">time_based_rotation</span> <span class="special">=</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">file</span><span class="special">::</span><span class="identifier">rotation_at_time_point</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">),</span> <a class="co" name="log.tutorial.sinks.c4" href="sinks.html#log.tutorial.sinks.c5"><img src="../../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a>
83        <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">format</span> <span class="special">=</span> <span class="string">"[%TimeStamp%]: %Message%"</span>                                 <a class="co" name="log.tutorial.sinks.c6" href="sinks.html#log.tutorial.sinks.c7"><img src="../../../../../../doc/src/images/callouts/4.png" alt="4" border="0"></a>
84    <span class="special">);</span>
85
86    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">()-&gt;</span><span class="identifier">set_filter</span>
87    <span class="special">(</span>
88        <span class="identifier">logging</span><span class="special">::</span><span class="identifier">trivial</span><span class="special">::</span><span class="identifier">severity</span> <span class="special">&gt;=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">trivial</span><span class="special">::</span><span class="identifier">info</span>
89    <span class="special">);</span>
90<span class="special">}</span>
91</pre>
92<p>
93      </p>
94<div class="calloutlist"><table border="0" summary="Callout list">
95<tr>
96<td width="5%" valign="top" align="left"><p><a name="log.tutorial.sinks.c1"></a><a href="#log.tutorial.sinks.c0"><img src="../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a> </p></td>
97<td valign="top" align="left"><p>
98            file name pattern
99          </p></td>
100</tr>
101<tr>
102<td width="5%" valign="top" align="left"><p><a name="log.tutorial.sinks.c3"></a><a href="#log.tutorial.sinks.c2"><img src="../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a> </p></td>
103<td valign="top" align="left"><p>
104            rotate files every 10 MiB...
105          </p></td>
106</tr>
107<tr>
108<td width="5%" valign="top" align="left"><p><a name="log.tutorial.sinks.c5"></a><a href="#log.tutorial.sinks.c4"><img src="../../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a> </p></td>
109<td valign="top" align="left"><p>
110            ...or at midnight
111          </p></td>
112</tr>
113<tr>
114<td width="5%" valign="top" align="left"><p><a name="log.tutorial.sinks.c7"></a><a href="#log.tutorial.sinks.c6"><img src="../../../../../../doc/src/images/callouts/4.png" alt="4" border="0"></a> </p></td>
115<td valign="top" align="left"><p>
116            log record format
117          </p></td>
118</tr>
119</table></div>
120<p>
121        <a href="../../../../../../libs/log/example/doc/tutorial_file.cpp" target="_top">See the complete
122        code</a>.
123      </p>
124<p>
125        You can see that the options are passed to the function in the named form.
126        This approach is also taken in many other places of the library. You'll get
127        used to it. The meaning of the parameters is mostly self-explaining and is
128        documented in this manual (see <a class="link" href="../detailed/sink_backends.html#log.detailed.sink_backends.text_file" title="Text file backend">here</a>
129        for what regards the text file sink). This and other convenience initialization
130        functions are described in <a class="link" href="../detailed/utilities.html#log.detailed.utilities.setup.convenience" title="Convenience functions">this</a>
131        section.
132      </p>
133<div class="note"><table border="0" summary="Note">
134<tr>
135<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
136<th align="left">Note</th>
137</tr>
138<tr><td align="left" valign="top"><p>
139          You can register more than one sink. Each sink will receive and process
140          log records as you emit them independently from others.
141        </p></td></tr>
142</table></div>
143<h5>
144<a name="log.tutorial.sinks.h1"></a>
145        <span class="phrase"><a name="log.tutorial.sinks.sinks_in_depth__more_sinks"></a></span><a class="link" href="sinks.html#log.tutorial.sinks.sinks_in_depth__more_sinks">Sinks
146        in depth: More sinks</a>
147      </h5>
148<p>
149        If you don't want to go into details, you can skip this section and continue
150        reading from the next one. Otherwise, if you need more comprehensive control
151        over sink configuration or want to use more sinks than those available through
152        helper functions, you can register sinks manually.
153      </p>
154<p>
155        In the simplest form, the call to the <code class="computeroutput"><span class="identifier">add_file_log</span></code>
156        function in the section above is nearly equivalent to this:
157      </p>
158<p>
159</p>
160<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">init</span><span class="special">()</span>
161<span class="special">{</span>
162    <span class="comment">// Construct the sink</span>
163    <span class="keyword">typedef</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">synchronous_sink</span><span class="special">&lt;</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">text_ostream_backend</span> <span class="special">&gt;</span> <span class="identifier">text_sink</span><span class="special">;</span>
164    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">text_sink</span> <span class="special">&gt;</span> <span class="identifier">sink</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">text_sink</span> <span class="special">&gt;();</span>
165
166    <span class="comment">// Add a stream to write log to</span>
167    <span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">locked_backend</span><span class="special">()-&gt;</span><span class="identifier">add_stream</span><span class="special">(</span>
168        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ofstream</span> <span class="special">&gt;(</span><span class="string">"sample.log"</span><span class="special">));</span>
169
170    <span class="comment">// Register the sink in the logging core</span>
171    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">()-&gt;</span><span class="identifier">add_sink</span><span class="special">(</span><span class="identifier">sink</span><span class="special">);</span>
172<span class="special">}</span>
173</pre>
174<p>
175      </p>
176<p>
177        <a href="../../../../../../libs/log/example/doc/tutorial_file_manual.cpp" target="_top">See the
178        complete code</a>.
179      </p>
180<p>
181        Ok, the first thing you may have noticed about sinks is that they are composed
182        of two classes: the frontend and the backend. The frontend (which is the
183        <a class="link" href="../detailed/sink_frontends.html#log.detailed.sink_frontends.sync" title="Synchronous sink frontend"><code class="computeroutput"><span class="identifier">synchronous_sink</span></code></a>
184        class template in the snippet above) is responsible for various common tasks
185        for all sinks, such as thread synchronization model, filtering and, for text-based
186        sinks, formatting. The backend (the <a class="link" href="../detailed/sink_backends.html#log.detailed.sink_backends.text_ostream" title="Text stream backend"><code class="computeroutput"><span class="identifier">text_ostream_backend</span></code></a> class above)
187        implements everything specific to the sink, such as writing to a file in
188        this case. The library provides a number of frontends and backends that can
189        be used with each other out of the box.
190      </p>
191<p>
192        The <a class="link" href="../detailed/sink_frontends.html#log.detailed.sink_frontends.sync" title="Synchronous sink frontend"><code class="computeroutput"><span class="identifier">synchronous_sink</span></code></a>
193        class template above indicates that the sink is synchronous, that is, it
194        allows for several threads to log simultaneously and will block in case of
195        contention. This means that the backend <a class="link" href="../detailed/sink_backends.html#log.detailed.sink_backends.text_ostream" title="Text stream backend"><code class="computeroutput"><span class="identifier">text_ostream_backend</span></code></a> doesn't have
196        to worry about multithreading at all. There are other sink frontends available,
197        you can read more about them <a class="link" href="../detailed/sink_frontends.html" title="Sink frontends">here</a>.
198      </p>
199<p>
200        The <a class="link" href="../detailed/sink_backends.html#log.detailed.sink_backends.text_ostream" title="Text stream backend"><code class="computeroutput"><span class="identifier">text_ostream_backend</span></code></a> class writes
201        formatted log records into STL-compatible streams. We have used a file stream
202        above but we could have used any type of stream. For example, adding output
203        to console could look as follows:
204      </p>
205<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">core</span><span class="special">/</span><span class="identifier">null_deleter</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
206
207<span class="comment">// We have to provide an empty deleter to avoid destroying the global stream object</span>
208<span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&gt;</span> <span class="identifier">stream</span><span class="special">(&amp;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">clog</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">null_deleter</span><span class="special">());</span>
209<span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">locked_backend</span><span class="special">()-&gt;</span><span class="identifier">add_stream</span><span class="special">(</span><span class="identifier">stream</span><span class="special">);</span>
210</pre>
211<p>
212        The <a class="link" href="../detailed/sink_backends.html#log.detailed.sink_backends.text_ostream" title="Text stream backend"><code class="computeroutput"><span class="identifier">text_ostream_backend</span></code></a> supports adding
213        several streams. In that case its output will be duplicated to all added
214        streams. It can be useful to duplicate the output to console and file since
215        all the filtering, formatting and other overhead of the library happen only
216        once per record for the sink.
217      </p>
218<div class="note"><table border="0" summary="Note">
219<tr>
220<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
221<th align="left">Note</th>
222</tr>
223<tr><td align="left" valign="top"><p>
224          Please note the difference between registering several distinct sinks and
225          registering one sink with several target streams. While the former allows
226          for independently customizing output to each sink, the latter would work
227          considerably faster if such customization is not needed. This feature is
228          specific to this particular backend.
229        </p></td></tr>
230</table></div>
231<p>
232        The library provides a number of <a class="link" href="../detailed/sink_backends.html" title="Sink backends">backends</a>
233        that provide different log processing logic. For instance, by specifying
234        the <a class="link" href="../detailed/sink_backends.html#log.detailed.sink_backends.syslog" title="Syslog backend">syslog</a> backend
235        you can send log records over the network to the syslog server, or by setting
236        up the <a class="link" href="../detailed/sink_backends.html#log.detailed.sink_backends.event_log" title="Windows event log backends">Windows NT event
237        log</a> backend you can monitor your application run time with the standard
238        Windows tools.
239      </p>
240<p>
241        The last thing worth noting here is the <code class="computeroutput"><span class="identifier">locked_backend</span></code>
242        member function call to access the sink backend. It is used to get thread-safe
243        access to the backend and is provided by all sink frontends. This function
244        returns a smart-pointer to the backend and as long as it exists the backend
245        is locked (which means even if another thread tries to log and the log record
246        is passed to the sink, it will not be logged until you release the backend).
247        The only exception is the <a class="link" href="../detailed/sink_frontends.html#log.detailed.sink_frontends.unlocked" title="Unlocked sink frontend"><code class="computeroutput"><span class="identifier">unlocked_sink</span></code></a> frontend which does
248        not synchronize at all and simply returns an unlocked pointer to the backend.
249      </p>
250</div>
251<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
252<td align="left"></td>
253<td align="right"><div class="copyright-footer">Copyright © 2007-2019 Andrey Semashev<p>
254        Distributed under the Boost Software License, Version 1.0. (See accompanying
255        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>).
256      </p>
257</div></td>
258</tr></table>
259<hr>
260<div class="spirit-nav">
261<a accesskey="p" href="trivial_filtering.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="sources.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
262</div>
263</body>
264</html>
265