Imported Upstream version 1.64.0
[platform/upstream/boost.git] / libs / log / doc / html / log / detailed / sink_backends.html
1 <html>
2 <head>
3 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
4 <title>Sink backends</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&#160;1.&#160;Boost.Log v2">
8 <link rel="up" href="../detailed.html" title="Detailed features description">
9 <link rel="prev" href="sink_frontends.html" title="Sink frontends">
10 <link rel="next" href="expressions.html" title="Lambda expressions">
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="sink_frontends.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../detailed.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="expressions.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.detailed.sink_backends"></a><a class="link" href="sink_backends.html" title="Sink backends">Sink backends</a>
21 </h3></div></div></div>
22 <div class="toc"><dl class="toc">
23 <dt><span class="section"><a href="sink_backends.html#log.detailed.sink_backends.text_ostream">Text stream
24         backend</a></span></dt>
25 <dt><span class="section"><a href="sink_backends.html#log.detailed.sink_backends.text_file">Text file backend</a></span></dt>
26 <dt><span class="section"><a href="sink_backends.html#log.detailed.sink_backends.text_multifile">Text multi-file
27         backend</a></span></dt>
28 <dt><span class="section"><a href="sink_backends.html#log.detailed.sink_backends.text_ipc_message_queue">Text
29         IPC message queue backend</a></span></dt>
30 <dt><span class="section"><a href="sink_backends.html#log.detailed.sink_backends.syslog">Syslog backend</a></span></dt>
31 <dt><span class="section"><a href="sink_backends.html#log.detailed.sink_backends.debugger">Windows debugger
32         output backend</a></span></dt>
33 <dt><span class="section"><a href="sink_backends.html#log.detailed.sink_backends.event_log">Windows event
34         log backends</a></span></dt>
35 </dl></div>
36 <div class="section">
37 <div class="titlepage"><div><div><h4 class="title">
38 <a name="log.detailed.sink_backends.text_ostream"></a><a class="link" href="sink_backends.html#log.detailed.sink_backends.text_ostream" title="Text stream backend">Text stream
39         backend</a>
40 </h4></div></div></div>
41 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../sinks.html#header.boost.log.sinks.text_ostream_backend_hpp" title="Header &lt;boost/log/sinks/text_ostream_backend.hpp&gt;">boost/log/sinks/text_ostream_backend.hpp</a></code><span class="special">&gt;</span>
42 </pre>
43 <p>
44           The text output stream sink backend is the most generic backend provided
45           by the library out of the box. The backend is implemented in the <code class="computeroutput"><a class="link" href="../../boost/log/sinks/basic_text_ostream_backend.html" title="Class template basic_text_ostream_backend">basic_text_ostream_backend</a></code>
46           class template (<code class="computeroutput"><span class="identifier">text_ostream_backend</span></code>
47           and <code class="computeroutput"><span class="identifier">wtext_ostream_backend</span></code>
48           convenience typedefs provided for narrow and wide character support). It
49           supports formatting log records into strings and putting into one or several
50           streams. Each attached stream gets the same result of formatting, so if
51           you need to format log records differently for different streams, you will
52           need to create several sinks - each with its own formatter.
53         </p>
54 <p>
55           The backend also provides a feature that may come useful when debugging
56           your application. With the <code class="computeroutput"><span class="identifier">auto_flush</span></code>
57           method one can tell the sink to automatically flush the buffers of all
58           attached streams after each log record is written. This will, of course,
59           degrade logging performance, but in case of an application crash there
60           is a good chance that last log records will not be lost.
61         </p>
62 <p>
63 </p>
64 <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">init_logging</span><span class="special">()</span>
65 <span class="special">{</span>
66     <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span> <span class="special">&gt;</span> <span class="identifier">core</span> <span class="special">=</span> <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">();</span>
67
68     <span class="comment">// Create a backend and attach a couple of streams to it</span>
69     <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</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">backend</span> <span class="special">=</span>
70         <span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_shared</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>
71     <span class="identifier">backend</span><span class="special">-&gt;</span><span class="identifier">add_stream</span><span class="special">(</span>
72         <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;(&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>
73     <span class="identifier">backend</span><span class="special">-&gt;</span><span class="identifier">add_stream</span><span class="special">(</span>
74         <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="keyword">new</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ofstream</span><span class="special">(</span><span class="string">"sample.log"</span><span class="special">)));</span>
75
76     <span class="comment">// Enable auto-flushing after each log record written</span>
77     <span class="identifier">backend</span><span class="special">-&gt;</span><span class="identifier">auto_flush</span><span class="special">(</span><span class="keyword">true</span><span class="special">);</span>
78
79     <span class="comment">// Wrap it into the frontend and register in the core.</span>
80     <span class="comment">// The backend requires synchronization in the frontend.</span>
81     <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">sink_t</span><span class="special">;</span>
82     <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">sink_t</span> <span class="special">&gt;</span> <span class="identifier">sink</span><span class="special">(</span><span class="keyword">new</span> <span class="identifier">sink_t</span><span class="special">(</span><span class="identifier">backend</span><span class="special">));</span>
83     <span class="identifier">core</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>
84 <span class="special">}</span>
85 </pre>
86 <p>
87         </p>
88 </div>
89 <div class="section">
90 <div class="titlepage"><div><div><h4 class="title">
91 <a name="log.detailed.sink_backends.text_file"></a><a class="link" href="sink_backends.html#log.detailed.sink_backends.text_file" title="Text file backend">Text file backend</a>
92 </h4></div></div></div>
93 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../sinks.html#header.boost.log.sinks.text_file_backend_hpp" title="Header &lt;boost/log/sinks/text_file_backend.hpp&gt;">boost/log/sinks/text_file_backend.hpp</a></code><span class="special">&gt;</span>
94 </pre>
95 <p>
96           Although it is possible to write logs into files with the <a class="link" href="sink_backends.html#log.detailed.sink_backends.text_ostream" title="Text stream backend">text
97           stream backend</a> the library also offers a special sink backend with
98           an extended set of features suitable for file-based logging. The features
99           include:
100         </p>
101 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
102 <li class="listitem">
103               Log file rotation based on file size and/or time
104             </li>
105 <li class="listitem">
106               Flexible log file naming
107             </li>
108 <li class="listitem">
109               Placing the rotated files into a special location in the file system
110             </li>
111 <li class="listitem">
112               Deleting the oldest files in order to free more space on the file system
113             </li>
114 </ul></div>
115 <p>
116           The backend is called <code class="computeroutput"><a class="link" href="../../boost/log/sinks/text_file_backend.html" title="Class text_file_backend">text_file_backend</a></code>.
117         </p>
118 <div class="warning"><table border="0" summary="Warning">
119 <tr>
120 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../../doc/src/images/warning.png"></td>
121 <th align="left">Warning</th>
122 </tr>
123 <tr><td align="left" valign="top"><p>
124             This sink uses <a href="http://www.boost.org/doc/libs/release/libs/filesystem/doc/index.htm" target="_top">Boost.Filesystem</a>
125             internally, which may cause problems on process termination. See <a class="link" href="../rationale/why_crash_on_term.html" title="Why my application crashes on process termination when file sinks are used?">here</a> for more details.
126           </p></td></tr>
127 </table></div>
128 <h6>
129 <a name="log.detailed.sink_backends.text_file.h0"></a>
130           <span class="phrase"><a name="log.detailed.sink_backends.text_file.file_rotation"></a></span><a class="link" href="sink_backends.html#log.detailed.sink_backends.text_file.file_rotation">File rotation</a>
131         </h6>
132 <p>
133           File rotation is implemented by the sink backend itself. The file name
134           pattern and rotation thresholds can be specified when the <code class="computeroutput"><a class="link" href="../../boost/log/sinks/text_file_backend.html" title="Class text_file_backend">text_file_backend</a></code>
135           backend is constructed.
136         </p>
137 <p>
138 </p>
139 <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">init_logging</span><span class="special">()</span>
140 <span class="special">{</span>
141     <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span> <span class="special">&gt;</span> <span class="identifier">core</span> <span class="special">=</span> <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">();</span>
142
143     <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">text_file_backend</span> <span class="special">&gt;</span> <span class="identifier">backend</span> <span class="special">=</span>
144         <span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">text_file_backend</span> <span class="special">&gt;(</span>
145             <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">file_name</span> <span class="special">=</span> <span class="string">"file_%5N.log"</span><span class="special">,</span>                                          <a class="co" name="log.detailed.sink_backends.text_file.c0" href="sink_backends.html#log.detailed.sink_backends.text_file.c1"><img src="../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a>
146             <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">rotation_size</span> <span class="special">=</span> <span class="number">5</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.detailed.sink_backends.text_file.c2" href="sink_backends.html#log.detailed.sink_backends.text_file.c3"><img src="../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a>
147             <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">12</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.detailed.sink_backends.text_file.c4" href="sink_backends.html#log.detailed.sink_backends.text_file.c5"><img src="../../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a>
148         <span class="special">);</span>
149
150     <span class="comment">// Wrap it into the frontend and register in the core.</span>
151     <span class="comment">// The backend requires synchronization in the frontend.</span>
152     <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_file_backend</span> <span class="special">&gt;</span> <span class="identifier">sink_t</span><span class="special">;</span>
153     <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">sink_t</span> <span class="special">&gt;</span> <span class="identifier">sink</span><span class="special">(</span><span class="keyword">new</span> <span class="identifier">sink_t</span><span class="special">(</span><span class="identifier">backend</span><span class="special">));</span>
154
155     <span class="identifier">core</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>
156 <span class="special">}</span>
157 </pre>
158 <p>
159         </p>
160 <div class="calloutlist"><table border="0" summary="Callout list">
161 <tr>
162 <td width="5%" valign="top" align="left"><p><a name="log.detailed.sink_backends.text_file.c1"></a><a href="#log.detailed.sink_backends.text_file.c0"><img src="../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a> </p></td>
163 <td valign="top" align="left"><p>
164               file name pattern
165             </p></td>
166 </tr>
167 <tr>
168 <td width="5%" valign="top" align="left"><p><a name="log.detailed.sink_backends.text_file.c3"></a><a href="#log.detailed.sink_backends.text_file.c2"><img src="../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a> </p></td>
169 <td valign="top" align="left"><p>
170               rotate the file upon reaching 5 MiB size...
171             </p></td>
172 </tr>
173 <tr>
174 <td width="5%" valign="top" align="left"><p><a name="log.detailed.sink_backends.text_file.c5"></a><a href="#log.detailed.sink_backends.text_file.c4"><img src="../../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a> </p></td>
175 <td valign="top" align="left"><p>
176               ...or every day, at noon, whichever comes first
177             </p></td>
178 </tr>
179 </table></div>
180 <div class="note"><table border="0" summary="Note">
181 <tr>
182 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
183 <th align="left">Note</th>
184 </tr>
185 <tr><td align="left" valign="top"><p>
186             The file size at rotation can be imprecise. The implementation counts
187             the number of characters written to the file, but the underlying API
188             can introduce additional auxiliary data, which would increase the log
189             file's actual size on disk. For instance, it is well known that Windows
190             and DOS operating systems have a special treatment with regard to new-line
191             characters. Each new-line character is written as a two byte sequence
192             0x0D 0x0A instead of a single 0x0A. Other platform-specific character
193             translations are also known. The actual size on disk can also be less
194             than the number of written characters on compressed filesystems.
195           </p></td></tr>
196 </table></div>
197 <p>
198           The time-based rotation is not limited by only time points. There are following
199           options available out of the box:
200         </p>
201 <div class="orderedlist"><ol class="orderedlist" type="1">
202 <li class="listitem">
203               Time point rotations: <code class="computeroutput"><a class="link" href="../../boost/log/sinks/file/rotation_at_time_point.html" title="Class rotation_at_time_point">rotation_at_time_point</a></code>
204               class. This kind of rotation takes place whenever the specified time
205               point is reached. The following variants are available:
206               <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
207 <li class="listitem">
208                     Every day rotation, at the specified time. This is what was presented
209                     in the code snippet above:
210 <pre class="programlisting"><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">12</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">)</span>
211 </pre>
212                   </li>
213 <li class="listitem">
214                     Rotation on the specified day of every week, at the specified
215                     time. For instance, this will make file rotation to happen every
216                     Tuesday, at midnight:
217 <pre class="programlisting"><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="identifier">date_time</span><span class="special">::</span><span class="identifier">Tuesday</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>
218 </pre>
219                     in case of midnight, the time can be omitted:
220 <pre class="programlisting"><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="identifier">date_time</span><span class="special">::</span><span class="identifier">Tuesday</span><span class="special">)</span>
221 </pre>
222                   </li>
223 <li class="listitem">
224                     Rotation on the specified day of each month, at the specified
225                     time. For example, this is how to rotate files on the 1-st of
226                     every month:
227 <pre class="programlisting"><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="identifier">gregorian</span><span class="special">::</span><span class="identifier">greg_day</span><span class="special">(</span><span class="number">1</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>
228 </pre>
229                     like with weekdays, midnight is implied:
230 <pre class="programlisting"><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="identifier">gregorian</span><span class="special">::</span><span class="identifier">greg_day</span><span class="special">(</span><span class="number">1</span><span class="special">))</span>
231 </pre>
232                   </li>
233 </ul></div>
234             </li>
235 <li class="listitem">
236               Time interval rotations: <code class="computeroutput"><a class="link" href="../../boost/log/sinks/file/rotation_at_time_interval.html" title="Class rotation_at_time_interval">rotation_at_time_interval</a></code>
237               class. With this predicate the rotation is not bound to any time points
238               and happens as soon as the specified time interval since the previous
239               rotation elapses. This is how to make rotations every hour:
240 <pre class="programlisting"><span class="identifier">sinks</span><span class="special">::</span><span class="identifier">file</span><span class="special">::</span><span class="identifier">rotation_at_time_interval</span><span class="special">(</span><span class="identifier">posix_time</span><span class="special">::</span><span class="identifier">hours</span><span class="special">(</span><span class="number">1</span><span class="special">))</span>
241 </pre>
242             </li>
243 </ol></div>
244 <p>
245           If none of the above applies, one can specify his own predicate for time-based
246           rotation. The predicate should take no arguments and return <code class="computeroutput"><span class="keyword">bool</span></code> (the <code class="computeroutput"><span class="keyword">true</span></code>
247           value indicates that the rotation should take place). The predicate will
248           be called for every log record being written to the file.
249         </p>
250 <pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">is_it_time_to_rotate</span><span class="special">();</span>
251
252 <span class="keyword">void</span> <span class="identifier">init_logging</span><span class="special">()</span>
253 <span class="special">{</span>
254     <span class="comment">// ...</span>
255
256     <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">text_file_backend</span> <span class="special">&gt;</span> <span class="identifier">backend</span> <span class="special">=</span>
257         <span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">text_file_backend</span> <span class="special">&gt;(</span>
258             <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">file_name</span> <span class="special">=</span> <span class="string">"file_%5N.log"</span><span class="special">,</span>
259             <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">time_based_rotation</span> <span class="special">=</span> <span class="special">&amp;</span><span class="identifier">is_it_time_to_rotate</span>
260         <span class="special">);</span>
261
262     <span class="comment">// ...</span>
263 <span class="special">}</span>
264 </pre>
265 <div class="note"><table border="0" summary="Note">
266 <tr>
267 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
268 <th align="left">Note</th>
269 </tr>
270 <tr><td align="left" valign="top"><p>
271             The log file rotation takes place on an attempt to write a new log record
272             to the file. Thus the time-based rotation is not a strict threshold,
273             either. The rotation will take place as soon as the library detects that
274             the rotation should have happened.
275           </p></td></tr>
276 </table></div>
277 <p>
278           In addition to time and size-based file rotation the backend also performs
279           rotation on its destruction by default. This is done in order to maintain
280           all log files collected in the target directory after program termination
281           and ensure that temporary log files don't pile up in the directory the
282           sink backend writes to. This behavior can be disabled with the <code class="computeroutput"><span class="identifier">enable_final_rotation</span></code> parameter of the
283           backend constructor or the similarly named method of the backend:
284         </p>
285 <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">init_logging</span><span class="special">()</span>
286 <span class="special">{</span>
287     <span class="comment">// ...</span>
288
289     <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">text_file_backend</span> <span class="special">&gt;</span> <span class="identifier">backend</span> <span class="special">=</span>
290         <span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">text_file_backend</span> <span class="special">&gt;(</span>
291             <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">file_name</span> <span class="special">=</span> <span class="string">"file_%5N.log"</span><span class="special">,</span>
292             <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">enable_final_rotation</span> <span class="special">=</span> <span class="keyword">false</span>
293         <span class="special">);</span>
294
295     <span class="comment">// ...</span>
296 <span class="special">}</span>
297 </pre>
298 <p>
299           The file name pattern may contain a number of wildcards, like the one you
300           can see in the example above. Supported placeholders are:
301         </p>
302 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
303 <li class="listitem">
304               Current date and time components. The placeholders conform to the ones
305               specified by <a href="http://www.boost.org/doc/libs/release/doc/html/date_time.html" target="_top">Boost.DateTime</a>
306               library.
307             </li>
308 <li class="listitem">
309               File counter (<code class="computeroutput"><span class="special">%</span><span class="identifier">N</span></code>)
310               with an optional width specification in the <code class="computeroutput"><span class="identifier">printf</span></code>-like
311               format. The file counter will always be decimal, zero filled to the
312               specified width.
313             </li>
314 <li class="listitem">
315               A percent sign (<code class="computeroutput"><span class="special">%%</span></code>).
316             </li>
317 </ul></div>
318 <p>
319           A few quick examples:
320         </p>
321 <div class="informaltable"><table class="table">
322 <colgroup>
323 <col>
324 <col>
325 </colgroup>
326 <thead><tr>
327 <th>
328                   <p>
329                     Template
330                   </p>
331                 </th>
332 <th>
333                   <p>
334                     Expands to
335                   </p>
336                 </th>
337 </tr></thead>
338 <tbody>
339 <tr>
340 <td>
341                   <p>
342                     file_%N.log
343                   </p>
344                 </td>
345 <td>
346                   <p>
347                     file_1.log, file_2.log...
348                   </p>
349                 </td>
350 </tr>
351 <tr>
352 <td>
353                   <p>
354                     file_%3N.log
355                   </p>
356                 </td>
357 <td>
358                   <p>
359                     file_001.log, file_002.log...
360                   </p>
361                 </td>
362 </tr>
363 <tr>
364 <td>
365                   <p>
366                     file_%Y%m%d.log
367                   </p>
368                 </td>
369 <td>
370                   <p>
371                     file_20080705.log, file_20080706.log...
372                   </p>
373                 </td>
374 </tr>
375 <tr>
376 <td>
377                   <p>
378                     file_%Y-%m-%d_%H-%M-%S.%N.log
379                   </p>
380                 </td>
381 <td>
382                   <p>
383                     file_2008-07-05_13-44-23.1.log, file_2008-07-06_16-00-10.2.log...
384                   </p>
385                 </td>
386 </tr>
387 </tbody>
388 </table></div>
389 <div class="important"><table border="0" summary="Important">
390 <tr>
391 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../../doc/src/images/important.png"></td>
392 <th align="left">Important</th>
393 </tr>
394 <tr><td align="left" valign="top"><p>
395             Although all <a href="http://www.boost.org/doc/libs/release/doc/html/date_time.html" target="_top">Boost.DateTime</a>
396             format specifiers will work, there are restrictions on some of them,
397             if you intend to scan for old log files. This functionality is discussed
398             in the next section.
399           </p></td></tr>
400 </table></div>
401 <p>
402           The sink backend allows hooking into the file rotation process in order
403           to perform pre- and post-rotation actions. This can be useful to maintain
404           log file validity by writing headers and footers. For example, this is
405           how we could modify the <code class="computeroutput"><span class="identifier">init_logging</span></code>
406           function in order to write logs into XML files:
407         </p>
408 <p>
409 </p>
410 <pre class="programlisting"><span class="comment">// Complete file sink type</span>
411 <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_file_backend</span> <span class="special">&gt;</span> <span class="identifier">file_sink</span><span class="special">;</span>
412
413 <span class="keyword">void</span> <span class="identifier">write_header</span><span class="special">(</span><span class="identifier">sinks</span><span class="special">::</span><span class="identifier">text_file_backend</span><span class="special">::</span><span class="identifier">stream_type</span><span class="special">&amp;</span> <span class="identifier">file</span><span class="special">)</span>
414 <span class="special">{</span>
415     <span class="identifier">file</span> <span class="special">&lt;&lt;</span> <span class="string">"&lt;?xml version=\"1.0\"?&gt;\n&lt;log&gt;\n"</span><span class="special">;</span>
416 <span class="special">}</span>
417
418 <span class="keyword">void</span> <span class="identifier">write_footer</span><span class="special">(</span><span class="identifier">sinks</span><span class="special">::</span><span class="identifier">text_file_backend</span><span class="special">::</span><span class="identifier">stream_type</span><span class="special">&amp;</span> <span class="identifier">file</span><span class="special">)</span>
419 <span class="special">{</span>
420     <span class="identifier">file</span> <span class="special">&lt;&lt;</span> <span class="string">"&lt;/log&gt;\n"</span><span class="special">;</span>
421 <span class="special">}</span>
422
423 <span class="keyword">void</span> <span class="identifier">init_logging</span><span class="special">()</span>
424 <span class="special">{</span>
425     <span class="comment">// Create a text file sink</span>
426     <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">file_sink</span> <span class="special">&gt;</span> <span class="identifier">sink</span><span class="special">(</span><span class="keyword">new</span> <span class="identifier">file_sink</span><span class="special">(</span>
427         <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">file_name</span> <span class="special">=</span> <span class="string">"%Y%m%d_%H%M%S_%5N.xml"</span><span class="special">,</span>  <a class="co" name="log.detailed.sink_backends.text_file.c6" href="sink_backends.html#log.detailed.sink_backends.text_file.c7"><img src="../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a>
428         <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">rotation_size</span> <span class="special">=</span> <span class="number">16384</span>                 <a class="co" name="log.detailed.sink_backends.text_file.c8" href="sink_backends.html#log.detailed.sink_backends.text_file.c9"><img src="../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a>
429     <span class="special">));</span>
430
431     <span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_formatter</span>
432     <span class="special">(</span>
433         <span class="identifier">expr</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"\t&lt;record id=\"%1%\" timestamp=\"%2%\"&gt;%3%&lt;/record&gt;"</span><span class="special">)</span>
434             <span class="special">%</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="string">"RecordID"</span><span class="special">)</span>
435             <span class="special">%</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">posix_time</span><span class="special">::</span><span class="identifier">ptime</span> <span class="special">&gt;(</span><span class="string">"TimeStamp"</span><span class="special">)</span>
436             <span class="special">%</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">xml_decor</span><span class="special">[</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">smessage</span> <span class="special">]</span>            <a class="co" name="log.detailed.sink_backends.text_file.c10" href="sink_backends.html#log.detailed.sink_backends.text_file.c11"><img src="../../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a>
437     <span class="special">);</span>
438
439     <span class="comment">// Set header and footer writing functors</span>
440     <span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">locked_backend</span><span class="special">()-&gt;</span><span class="identifier">set_open_handler</span><span class="special">(&amp;</span><span class="identifier">write_header</span><span class="special">);</span>
441     <span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">locked_backend</span><span class="special">()-&gt;</span><span class="identifier">set_close_handler</span><span class="special">(&amp;</span><span class="identifier">write_footer</span><span class="special">);</span>
442
443     <span class="comment">// Add the sink to the core</span>
444     <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>
445 <span class="special">}</span>
446 </pre>
447 <p>
448         </p>
449 <div class="calloutlist"><table border="0" summary="Callout list">
450 <tr>
451 <td width="5%" valign="top" align="left"><p><a name="log.detailed.sink_backends.text_file.c7"></a><a href="#log.detailed.sink_backends.text_file.c6"><img src="../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a> </p></td>
452 <td valign="top" align="left"><p>
453               the resulting file name pattern
454             </p></td>
455 </tr>
456 <tr>
457 <td width="5%" valign="top" align="left"><p><a name="log.detailed.sink_backends.text_file.c9"></a><a href="#log.detailed.sink_backends.text_file.c8"><img src="../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a> </p></td>
458 <td valign="top" align="left"><p>
459               rotation size, in characters
460             </p></td>
461 </tr>
462 <tr>
463 <td width="5%" valign="top" align="left"><p><a name="log.detailed.sink_backends.text_file.c11"></a><a href="#log.detailed.sink_backends.text_file.c10"><img src="../../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a> </p></td>
464 <td valign="top" align="left"><p>
465               the log message has to be decorated, if it contains special characters
466             </p></td>
467 </tr>
468 </table></div>
469 <p>
470           <a href="../../../../../../libs/log/example/doc/sinks_xml_file.cpp" target="_top">See the complete
471           code</a>.
472         </p>
473 <p>
474           Finally, the sink backend also supports the auto-flush feature, like the
475           <a class="link" href="sink_backends.html#log.detailed.sink_backends.text_ostream" title="Text stream backend">text stream backend</a>
476           does.
477         </p>
478 <h6>
479 <a name="log.detailed.sink_backends.text_file.h1"></a>
480           <span class="phrase"><a name="log.detailed.sink_backends.text_file.managing_rotated_files"></a></span><a class="link" href="sink_backends.html#log.detailed.sink_backends.text_file.managing_rotated_files">Managing
481           rotated files</a>
482         </h6>
483 <p>
484           After being closed, the rotated files can be collected. In order to do
485           so one has to set up a file collector by specifying the target directory
486           where to collect the rotated files and, optionally, size thresholds. For
487           example, we can modify the <code class="computeroutput"><span class="identifier">init_logging</span></code>
488           function to place rotated files into a distinct directory and limit total
489           size of the files. Let's assume the following function is called by <code class="computeroutput"><span class="identifier">init_logging</span></code> with the constructed sink:
490         </p>
491 <p>
492 </p>
493 <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">init_file_collecting</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">file_sink</span> <span class="special">&gt;</span> <span class="identifier">sink</span><span class="special">)</span>
494 <span class="special">{</span>
495     <span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">locked_backend</span><span class="special">()-&gt;</span><span class="identifier">set_file_collector</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">make_collector</span><span class="special">(</span>
496         <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">target</span> <span class="special">=</span> <span class="string">"logs"</span><span class="special">,</span>                      <a class="co" name="log.detailed.sink_backends.text_file.c12" href="sink_backends.html#log.detailed.sink_backends.text_file.c13"><img src="../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a>
497         <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">max_size</span> <span class="special">=</span> <span class="number">16</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.detailed.sink_backends.text_file.c14" href="sink_backends.html#log.detailed.sink_backends.text_file.c15"><img src="../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a>
498         <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">min_free_space</span> <span class="special">=</span> <span class="number">100</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.detailed.sink_backends.text_file.c16" href="sink_backends.html#log.detailed.sink_backends.text_file.c17"><img src="../../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a>
499         <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">max_files</span> <span class="special">=</span> <span class="number">512</span>                       <a class="co" name="log.detailed.sink_backends.text_file.c18" href="sink_backends.html#log.detailed.sink_backends.text_file.c19"><img src="../../../../../../doc/src/images/callouts/4.png" alt="4" border="0"></a>
500     <span class="special">));</span>
501 <span class="special">}</span>
502 </pre>
503 <p>
504         </p>
505 <div class="calloutlist"><table border="0" summary="Callout list">
506 <tr>
507 <td width="5%" valign="top" align="left"><p><a name="log.detailed.sink_backends.text_file.c13"></a><a href="#log.detailed.sink_backends.text_file.c12"><img src="../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a> </p></td>
508 <td valign="top" align="left"><p>
509               the target directory
510             </p></td>
511 </tr>
512 <tr>
513 <td width="5%" valign="top" align="left"><p><a name="log.detailed.sink_backends.text_file.c15"></a><a href="#log.detailed.sink_backends.text_file.c14"><img src="../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a> </p></td>
514 <td valign="top" align="left"><p>
515               maximum total size of the stored files, in bytes
516             </p></td>
517 </tr>
518 <tr>
519 <td width="5%" valign="top" align="left"><p><a name="log.detailed.sink_backends.text_file.c17"></a><a href="#log.detailed.sink_backends.text_file.c16"><img src="../../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a> </p></td>
520 <td valign="top" align="left"><p>
521               minimum free space on the drive, in bytes
522             </p></td>
523 </tr>
524 <tr>
525 <td width="5%" valign="top" align="left"><p><a name="log.detailed.sink_backends.text_file.c19"></a><a href="#log.detailed.sink_backends.text_file.c18"><img src="../../../../../../doc/src/images/callouts/4.png" alt="4" border="0"></a> </p></td>
526 <td valign="top" align="left"><p>
527               maximum number of stored files
528             </p></td>
529 </tr>
530 </table></div>
531 <p>
532           The <code class="computeroutput"><span class="identifier">max_size</span></code>, <code class="computeroutput"><span class="identifier">min_free_space</span></code> and <code class="computeroutput"><span class="identifier">max_files</span></code>
533           parameters are optional, the corresponding threshold will not be taken
534           into account if the parameter is not specified.
535         </p>
536 <p>
537           One can create multiple file sink backends that collect files into the
538           same target directory. In this case the most strict thresholds are combined
539           for this target directory. The files from this directory will be erased
540           without regard for which sink backend wrote it, i.e. in the strict chronological
541           order.
542         </p>
543 <div class="warning"><table border="0" summary="Warning">
544 <tr>
545 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../../doc/src/images/warning.png"></td>
546 <th align="left">Warning</th>
547 </tr>
548 <tr><td align="left" valign="top"><p>
549             The collector does not resolve log file name clashes between different
550             sink backends, so if the clash occurs the behavior is undefined, in general.
551             Depending on the circumstances, the files may overwrite each other or
552             the operation may fail entirely.
553           </p></td></tr>
554 </table></div>
555 <p>
556           The file collector provides another useful feature. Suppose you ran your
557           application 5 times and you have 5 log files in the "logs" directory.
558           The file sink backend and file collector provide a <code class="computeroutput"><span class="identifier">scan_for_files</span></code>
559           method that searches the target directory for these files and takes them
560           into account. So, if it comes to deleting files, these files are not forgotten.
561           What's more, if the file name pattern in the backend involves a file counter,
562           scanning for older files allows updating the counter to the most recent
563           value. Here is the final version of our <code class="computeroutput"><span class="identifier">init_logging</span></code>
564           function:
565         </p>
566 <p>
567 </p>
568 <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">init_logging</span><span class="special">()</span>
569 <span class="special">{</span>
570     <span class="comment">// Create a text file sink</span>
571     <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">file_sink</span> <span class="special">&gt;</span> <span class="identifier">sink</span><span class="special">(</span><span class="keyword">new</span> <span class="identifier">file_sink</span><span class="special">(</span>
572         <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">file_name</span> <span class="special">=</span> <span class="string">"%Y%m%d_%H%M%S_%5N.xml"</span><span class="special">,</span>
573         <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">rotation_size</span> <span class="special">=</span> <span class="number">16384</span>
574     <span class="special">));</span>
575
576     <span class="comment">// Set up where the rotated files will be stored</span>
577     <span class="identifier">init_file_collecting</span><span class="special">(</span><span class="identifier">sink</span><span class="special">);</span>
578
579     <span class="comment">// Upon restart, scan the directory for files matching the file_name pattern</span>
580     <span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">locked_backend</span><span class="special">()-&gt;</span><span class="identifier">scan_for_files</span><span class="special">();</span>
581
582     <span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_formatter</span>
583     <span class="special">(</span>
584         <span class="identifier">expr</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"\t&lt;record id=\"%1%\" timestamp=\"%2%\"&gt;%3%&lt;/record&gt;"</span><span class="special">)</span>
585             <span class="special">%</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="string">"RecordID"</span><span class="special">)</span>
586             <span class="special">%</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">posix_time</span><span class="special">::</span><span class="identifier">ptime</span> <span class="special">&gt;(</span><span class="string">"TimeStamp"</span><span class="special">)</span>
587             <span class="special">%</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">xml_decor</span><span class="special">[</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">smessage</span> <span class="special">]</span>
588     <span class="special">);</span>
589
590     <span class="comment">// Set header and footer writing functors</span>
591     <span class="keyword">namespace</span> <span class="identifier">bll</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">lambda</span><span class="special">;</span>
592
593     <span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">locked_backend</span><span class="special">()-&gt;</span><span class="identifier">set_open_handler</span>
594     <span class="special">(</span>
595         <span class="identifier">bll</span><span class="special">::</span><span class="identifier">_1</span> <span class="special">&lt;&lt;</span> <span class="string">"&lt;?xml version=\"1.0\"?&gt;\n&lt;log&gt;\n"</span>
596     <span class="special">);</span>
597     <span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">locked_backend</span><span class="special">()-&gt;</span><span class="identifier">set_close_handler</span>
598     <span class="special">(</span>
599         <span class="identifier">bll</span><span class="special">::</span><span class="identifier">_1</span> <span class="special">&lt;&lt;</span> <span class="string">"&lt;/log&gt;\n"</span>
600     <span class="special">);</span>
601
602     <span class="comment">// Add the sink to the core</span>
603     <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>
604 <span class="special">}</span>
605 </pre>
606 <p>
607         </p>
608 <p>
609           There are two methods of file scanning: the scan that involves file name
610           matching with the file name pattern (the default) and the scan that assumes
611           that all files in the target directory are log files. The former applies
612           certain restrictions on the placeholders that can be used within the file
613           name pattern, in particular only file counter placeholder and these placeholders
614           of <a href="http://www.boost.org/doc/libs/release/doc/html/date_time.html" target="_top">Boost.DateTime</a>
615           are supported: <code class="computeroutput"><span class="special">%</span><span class="identifier">y</span></code>,
616           <code class="computeroutput"><span class="special">%</span><span class="identifier">Y</span></code>,
617           <code class="computeroutput"><span class="special">%</span><span class="identifier">m</span></code>,
618           <code class="computeroutput"><span class="special">%</span><span class="identifier">d</span></code>,
619           <code class="computeroutput"><span class="special">%</span><span class="identifier">H</span></code>,
620           <code class="computeroutput"><span class="special">%</span><span class="identifier">M</span></code>,
621           <code class="computeroutput"><span class="special">%</span><span class="identifier">S</span></code>,
622           <code class="computeroutput"><span class="special">%</span><span class="identifier">f</span></code>.
623           The latter scanning method, in its turn, has its own drawback: it does
624           not allow updating the file counter in the backend. It is also considered
625           to be more dangerous as it may result in unintended file deletion, so be
626           cautious. The all-files scanning method can be enabled by passing it as
627           an additional parameter to the <code class="computeroutput"><span class="identifier">scan_for_files</span></code>
628           call:
629         </p>
630 <pre class="programlisting"><span class="comment">// Look for all files in the target directory</span>
631 <span class="identifier">backend</span><span class="special">-&gt;</span><span class="identifier">scan_for_files</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">scan_all</span><span class="special">);</span>
632 </pre>
633 </div>
634 <div class="section">
635 <div class="titlepage"><div><div><h4 class="title">
636 <a name="log.detailed.sink_backends.text_multifile"></a><a class="link" href="sink_backends.html#log.detailed.sink_backends.text_multifile" title="Text multi-file backend">Text multi-file
637         backend</a>
638 </h4></div></div></div>
639 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../sinks.html#header.boost.log.sinks.text_multifile_backend_hpp" title="Header &lt;boost/log/sinks/text_multifile_backend.hpp&gt;">boost/log/sinks/text_multifile_backend.hpp</a></code><span class="special">&gt;</span>
640 </pre>
641 <p>
642           While the text stream and file backends are aimed to store all log records
643           into a single file/stream, this backend serves a different purpose. Assume
644           we have a banking request processing application and we want logs related
645           to every single request to be placed into a separate file. If we can associate
646           some attribute with the request identity then the <code class="computeroutput"><a class="link" href="../../boost/log/sinks/text_multifile_backend.html" title="Class text_multifile_backend">text_multifile_backend</a></code>
647           backend is the way to go.
648         </p>
649 <p>
650 </p>
651 <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">init_logging</span><span class="special">()</span>
652 <span class="special">{</span>
653     <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span> <span class="special">&gt;</span> <span class="identifier">core</span> <span class="special">=</span> <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">();</span>
654
655     <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">text_multifile_backend</span> <span class="special">&gt;</span> <span class="identifier">backend</span> <span class="special">=</span>
656         <span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">text_multifile_backend</span> <span class="special">&gt;();</span>
657
658     <span class="comment">// Set up the file naming pattern</span>
659     <span class="identifier">backend</span><span class="special">-&gt;</span><span class="identifier">set_file_name_composer</span>
660     <span class="special">(</span>
661         <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">file</span><span class="special">::</span><span class="identifier">as_file_name_composer</span><span class="special">(</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="string">"logs/"</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;(</span><span class="string">"RequestID"</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">".log"</span><span class="special">)</span>
662     <span class="special">);</span>
663
664     <span class="comment">// Wrap it into the frontend and register in the core.</span>
665     <span class="comment">// The backend requires synchronization in the frontend.</span>
666     <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_multifile_backend</span> <span class="special">&gt;</span> <span class="identifier">sink_t</span><span class="special">;</span>
667     <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">sink_t</span> <span class="special">&gt;</span> <span class="identifier">sink</span><span class="special">(</span><span class="keyword">new</span> <span class="identifier">sink_t</span><span class="special">(</span><span class="identifier">backend</span><span class="special">));</span>
668
669     <span class="comment">// Set the formatter</span>
670     <span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_formatter</span>
671     <span class="special">(</span>
672         <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span>
673             <span class="special">&lt;&lt;</span> <span class="string">"[RequestID: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;(</span><span class="string">"RequestID"</span><span class="special">)</span>
674             <span class="special">&lt;&lt;</span> <span class="string">"] "</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">smessage</span>
675     <span class="special">);</span>
676
677     <span class="identifier">core</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>
678 <span class="special">}</span>
679 </pre>
680 <p>
681         </p>
682 <p>
683           You can see we used a regular <a class="link" href="expressions.html#log.detailed.expressions.formatters" title="Formatting expressions">formatter</a>
684           in order to specify file naming pattern. Now, every log record with a distinct
685           value of the "RequestID" attribute will be stored in a separate
686           file, no matter how many different requests are being processed by the
687           application concurrently. You can also find the <a href="../../../../../../libs/log/example/multiple_files/main.cpp" target="_top"><code class="computeroutput"><span class="identifier">multiple_files</span></code></a> example in the
688           library distribution, which shows a similar technique to separate logs
689           generated by different threads of the application.
690         </p>
691 <p>
692           If using formatters is not appropriate for some reason, you can provide
693           your own file name composer. The composer is a mere function object that
694           accepts a log record as a single argument and returns a value of the <code class="computeroutput"><span class="identifier">text_multifile_backend</span><span class="special">::</span><span class="identifier">path_type</span></code> type.
695         </p>
696 <div class="note"><table border="0" summary="Note">
697 <tr>
698 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
699 <th align="left">Note</th>
700 </tr>
701 <tr><td align="left" valign="top"><p>
702             The multi-file backend has no knowledge of whether a particular file
703             is going to be used or not. That is, if a log record has been written
704             into file A, the library cannot tell whether there will be more records
705             that fit into the file A or not. This makes it impossible to implement
706             file rotation and removing unused files to free space on the file system.
707             The user will have to implement such functionality himself.
708           </p></td></tr>
709 </table></div>
710 </div>
711 <div class="section">
712 <div class="titlepage"><div><div><h4 class="title">
713 <a name="log.detailed.sink_backends.text_ipc_message_queue"></a><a class="link" href="sink_backends.html#log.detailed.sink_backends.text_ipc_message_queue" title="Text IPC message queue backend">Text
714         IPC message queue backend</a>
715 </h4></div></div></div>
716 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../sinks.html#header.boost.log.sinks.text_ipc_message_queue_backend_hpp" title="Header &lt;boost/log/sinks/text_ipc_message_queue_backend.hpp&gt;">boost/log/sinks/text_ipc_message_queue_backend.hpp</a></code><span class="special">&gt;</span>
717 </pre>
718 <p>
719           Sometimes, it is convenient to pass log records between different processes
720           on a local machine. For example, one could collect logs from multiple processes
721           into a common logger process. Or create a log viewer which is able to monitor
722           running processes. To implement this idea, a sink backend that sends logs
723           across processes is needed. The text interprocess sink backend puts formatted
724           log messages to an <a class="link" href="utilities.html#log.detailed.utilities.ipc.reliable_message_queue" title="Reliable message queue">interprocess
725           message queue</a>, which can then be retrieved and processed by another
726           process. In particular, one may choose to encode a log record with various
727           attribute values into a JSON or XML formatted text message, and then decode
728           the message at the receiving side for processing such as filtering and
729           displaying.
730         </p>
731 <p>
732           The backend is implemented by the <code class="computeroutput"><a class="link" href="../../boost/log/sinks/text_ipc_messa_idp65138288.html" title="Class template text_ipc_message_queue_backend">text_ipc_message_queue_backend</a></code>
733           class template which should be instantiated with an interprocess message
734           queue such as <code class="computeroutput"><a class="link" href="../../boost/log/ipc/reliable_message_queue.html" title="Class reliable_message_queue">reliable_message_queue</a></code>.
735           The following example program illustrates a logger process.
736         </p>
737 <p>
738 </p>
739 <pre class="programlisting"><span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">a_timestamp</span><span class="special">,</span> <span class="string">"TimeStamp"</span><span class="special">,</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">local_clock</span><span class="special">::</span><span class="identifier">value_type</span><span class="special">)</span>
740 <span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">a_process_id</span><span class="special">,</span> <span class="string">"ProcessID"</span><span class="special">,</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">current_process_id</span><span class="special">::</span><span class="identifier">value_type</span><span class="special">)</span>
741 <span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">a_thread_id</span><span class="special">,</span> <span class="string">"ThreadID"</span><span class="special">,</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">current_thread_id</span><span class="special">::</span><span class="identifier">value_type</span><span class="special">)</span>
742
743 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
744 <span class="special">{</span>
745     <span class="keyword">try</span>
746     <span class="special">{</span>
747         <span class="keyword">typedef</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">ipc</span><span class="special">::</span><span class="identifier">reliable_message_queue</span> <span class="identifier">queue_t</span><span class="special">;</span>
748         <span class="keyword">typedef</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">text_ipc_message_queue_backend</span><span class="special">&lt;</span> <span class="identifier">queue_t</span> <span class="special">&gt;</span> <span class="identifier">backend_t</span><span class="special">;</span>
749         <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">backend_t</span> <span class="special">&gt;</span> <span class="identifier">sink_t</span><span class="special">;</span>
750
751         <span class="comment">// Create a sink that is associated with the interprocess message queue</span>
752         <span class="comment">// named "ipc_message_queue".</span>
753         <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">sink_t</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">sink_t</span> <span class="special">&gt;</span>
754         <span class="special">(</span>
755             <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">name</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">ipc</span><span class="special">::</span><span class="identifier">object_name</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">ipc</span><span class="special">::</span><span class="identifier">object_name</span><span class="special">::</span><span class="identifier">user</span><span class="special">,</span> <span class="string">"ipc_message_queue"</span><span class="special">),</span>
756             <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">open_mode</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">open_mode</span><span class="special">::</span><span class="identifier">open_or_create</span><span class="special">,</span>
757             <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">capacity</span> <span class="special">=</span> <span class="number">256</span><span class="special">,</span>
758             <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">block_size</span> <span class="special">=</span> <span class="number">1024</span><span class="special">,</span>
759             <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">overflow_policy</span> <span class="special">=</span> <span class="identifier">queue_t</span><span class="special">::</span><span class="identifier">block_on_overflow</span>
760         <span class="special">);</span>
761
762         <span class="comment">// Set the formatter</span>
763         <span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_formatter</span>
764         <span class="special">(</span>
765             <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special">&lt;&lt;</span> <span class="string">"["</span> <span class="special">&lt;&lt;</span> <span class="identifier">a_timestamp</span> <span class="special">&lt;&lt;</span> <span class="string">"] ["</span> <span class="special">&lt;&lt;</span> <span class="identifier">a_process_id</span> <span class="special">&lt;&lt;</span> <span class="string">":"</span> <span class="special">&lt;&lt;</span> <span class="identifier">a_thread_id</span> <span class="special">&lt;&lt;</span> <span class="string">"] "</span> <span class="special">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">smessage</span>
766         <span class="special">);</span>
767
768         <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>
769
770         <span class="comment">// Add the commonly used attributes, including TimeStamp, ProcessID and ThreadID</span>
771         <span class="identifier">logging</span><span class="special">::</span><span class="identifier">add_common_attributes</span><span class="special">();</span>
772
773         <span class="comment">// Do some logging</span>
774         <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger</span> <span class="identifier">logger</span><span class="special">;</span>
775         <span class="keyword">for</span> <span class="special">(</span><span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span> <span class="identifier">i</span> <span class="special">&lt;=</span> <span class="number">10</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span>
776         <span class="special">{</span>
777             <span class="identifier">BOOST_LOG</span><span class="special">(</span><span class="identifier">logger</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">"Message #"</span> <span class="special">&lt;&lt;</span> <span class="identifier">i</span><span class="special">;</span>
778         <span class="special">}</span>
779     <span class="special">}</span>
780     <span class="keyword">catch</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">exception</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span>
781     <span class="special">{</span>
782         <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Failure: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
783     <span class="special">}</span>
784
785     <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
786 <span class="special">}</span>
787 </pre>
788 <p>
789         </p>
790 <p>
791           <a href="../../../../../../libs/log/example/doc/sinks_ipc_logger.cpp" target="_top">See the complete
792           code</a>.
793         </p>
794 <p>
795           The same interprocess queue can be used to implement the receiving side
796           as well. The following code displays the received log messages on the console.
797         </p>
798 <p>
799 </p>
800 <pre class="programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
801 <span class="special">{</span>
802     <span class="keyword">try</span>
803     <span class="special">{</span>
804         <span class="keyword">typedef</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">ipc</span><span class="special">::</span><span class="identifier">reliable_message_queue</span> <span class="identifier">queue_t</span><span class="special">;</span>
805
806         <span class="comment">// Create a message_queue_type object that is associated with the interprocess</span>
807         <span class="comment">// message queue named "ipc_message_queue".</span>
808         <span class="identifier">queue_t</span> <span class="identifier">queue</span>
809         <span class="special">(</span>
810             <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">name</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">ipc</span><span class="special">::</span><span class="identifier">object_name</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">ipc</span><span class="special">::</span><span class="identifier">object_name</span><span class="special">::</span><span class="identifier">user</span><span class="special">,</span> <span class="string">"ipc_message_queue"</span><span class="special">),</span>
811             <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">open_mode</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">open_mode</span><span class="special">::</span><span class="identifier">open_or_create</span><span class="special">,</span>
812             <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">capacity</span> <span class="special">=</span> <span class="number">256</span><span class="special">,</span>
813             <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">block_size</span> <span class="special">=</span> <span class="number">1024</span><span class="special">,</span>
814             <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">overflow_policy</span> <span class="special">=</span> <span class="identifier">queue_t</span><span class="special">::</span><span class="identifier">block_on_overflow</span>
815         <span class="special">);</span>
816
817         <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Viewer process running..."</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
818
819         <span class="comment">// Keep reading log messages from the associated message queue and print them on the console.</span>
820         <span class="comment">// queue.receive() will block if the queue is empty.</span>
821         <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">message</span><span class="special">;</span>
822         <span class="keyword">while</span> <span class="special">(</span><span class="identifier">queue</span><span class="special">.</span><span class="identifier">receive</span><span class="special">(</span><span class="identifier">message</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">queue_t</span><span class="special">::</span><span class="identifier">succeeded</span><span class="special">)</span>
823         <span class="special">{</span>
824             <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">message</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
825
826             <span class="comment">// Clear the buffer for the next message</span>
827             <span class="identifier">message</span><span class="special">.</span><span class="identifier">clear</span><span class="special">();</span>
828         <span class="special">}</span>
829     <span class="special">}</span>
830     <span class="keyword">catch</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">exception</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span>
831     <span class="special">{</span>
832         <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Failure: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
833     <span class="special">}</span>
834
835     <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
836 <span class="special">}</span>
837 </pre>
838 <p>
839         </p>
840 <p>
841           <a href="../../../../../../libs/log/example/doc/sinks_ipc_receiver.cpp" target="_top">See the
842           complete code</a>.
843         </p>
844 </div>
845 <div class="section">
846 <div class="titlepage"><div><div><h4 class="title">
847 <a name="log.detailed.sink_backends.syslog"></a><a class="link" href="sink_backends.html#log.detailed.sink_backends.syslog" title="Syslog backend">Syslog backend</a>
848 </h4></div></div></div>
849 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../sinks.html#header.boost.log.sinks.syslog_backend_hpp" title="Header &lt;boost/log/sinks/syslog_backend.hpp&gt;">boost/log/sinks/syslog_backend.hpp</a></code><span class="special">&gt;</span>
850 </pre>
851 <p>
852           The syslog backend, as comes from its name, provides support for the syslog
853           API that is available on virtually any UNIX-like platform. On Windows there
854           exists at least <a href="http://syslog-win32.sourceforge.net" target="_top">one</a>
855           public implementation of the syslog client API. However, in order to provide
856           maximum flexibility and better portability the library offers built-in
857           support for the syslog protocol described in <a href="http://tools.ietf.org/html/rfc3164" target="_top">RFC
858           3164</a>. Thus on Windows only the built-in implementation is supported,
859           while on UNIX-like systems both built-in and system API based implementations
860           are supported.
861         </p>
862 <p>
863           The backend is implemented in the <code class="computeroutput"><a class="link" href="../../boost/log/sinks/syslog_backend.html" title="Class syslog_backend">syslog_backend</a></code>
864           class. The backend supports formatting log records, and therefore requires
865           thread synchronization in the frontend. The backend also supports severity
866           level translation from the application-specific values to the syslog-defined
867           values. This is achieved with an additional function object, level mapper,
868           that receives a set of attribute values of each log record and returns
869           the appropriate syslog level value. This value is used by the backend to
870           construct the final priority value of the syslog record. The other component
871           of the syslog priority value, the facility, is constant for each backend
872           object and can be specified in the backend constructor arguments.
873         </p>
874 <p>
875           Level mappers can be written by library users to translate the application
876           log levels to the syslog levels in the best way. However, the library provides
877           two mappers that would fit this need in obvious cases. The <code class="computeroutput"><a class="link" href="../../boost/log/sinks/syslog/direct_severity_mapping.html" title="Class template direct_severity_mapping">direct_severity_mapping</a></code>
878           class template provides a way to directly map values of some integral attribute
879           to syslog levels, without any value conversion. The <code class="computeroutput"><a class="link" href="../../boost/log/sinks/syslog/custom_severity_mapping.html" title="Class template custom_severity_mapping">custom_severity_mapping</a></code>
880           class template adds some flexibility and allows to map arbitrary values
881           of some attribute to syslog levels.
882         </p>
883 <p>
884           Anyway, one example is better than a thousand words.
885         </p>
886 <p>
887 </p>
888 <pre class="programlisting"><span class="comment">// Complete sink type</span>
889 <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">syslog_backend</span> <span class="special">&gt;</span> <span class="identifier">sink_t</span><span class="special">;</span>
890
891 <span class="keyword">void</span> <span class="identifier">init_native_syslog</span><span class="special">()</span>
892 <span class="special">{</span>
893     <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span> <span class="special">&gt;</span> <span class="identifier">core</span> <span class="special">=</span> <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">();</span>
894
895     <span class="comment">// Create a backend</span>
896     <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">syslog_backend</span> <span class="special">&gt;</span> <span class="identifier">backend</span><span class="special">(</span><span class="keyword">new</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">syslog_backend</span><span class="special">(</span>
897         <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">facility</span> <span class="special">=</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">syslog</span><span class="special">::</span><span class="identifier">user</span><span class="special">,</span>               <a class="co" name="log.detailed.sink_backends.syslog.c0" href="sink_backends.html#log.detailed.sink_backends.syslog.c1"><img src="../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a>
898         <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">use_impl</span> <span class="special">=</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">syslog</span><span class="special">::</span><span class="identifier">native</span>              <a class="co" name="log.detailed.sink_backends.syslog.c2" href="sink_backends.html#log.detailed.sink_backends.syslog.c3"><img src="../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a>
899     <span class="special">));</span>
900
901     <span class="comment">// Set the straightforward level translator for the "Severity" attribute of type int</span>
902     <span class="identifier">backend</span><span class="special">-&gt;</span><span class="identifier">set_severity_mapper</span><span class="special">(</span><span class="identifier">sinks</span><span class="special">::</span><span class="identifier">syslog</span><span class="special">::</span><span class="identifier">direct_severity_mapping</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="string">"Severity"</span><span class="special">));</span>
903
904     <span class="comment">// Wrap it into the frontend and register in the core.</span>
905     <span class="comment">// The backend requires synchronization in the frontend.</span>
906     <span class="identifier">core</span><span class="special">-&gt;</span><span class="identifier">add_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">sink_t</span> <span class="special">&gt;(</span><span class="identifier">backend</span><span class="special">));</span>
907 <span class="special">}</span>
908
909 <span class="keyword">void</span> <span class="identifier">init_builtin_syslog</span><span class="special">()</span>
910 <span class="special">{</span>
911     <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span> <span class="special">&gt;</span> <span class="identifier">core</span> <span class="special">=</span> <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">();</span>
912
913     <span class="comment">// Create a new backend</span>
914     <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">syslog_backend</span> <span class="special">&gt;</span> <span class="identifier">backend</span><span class="special">(</span><span class="keyword">new</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">syslog_backend</span><span class="special">(</span>
915         <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">facility</span> <span class="special">=</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">syslog</span><span class="special">::</span><span class="identifier">local0</span><span class="special">,</span>             <a class="co" name="log.detailed.sink_backends.syslog.c4" href="sink_backends.html#log.detailed.sink_backends.syslog.c5"><img src="../../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a>
916         <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">use_impl</span> <span class="special">=</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">syslog</span><span class="special">::</span><span class="identifier">udp_socket_based</span>    <a class="co" name="log.detailed.sink_backends.syslog.c6" href="sink_backends.html#log.detailed.sink_backends.syslog.c7"><img src="../../../../../../doc/src/images/callouts/4.png" alt="4" border="0"></a>
917     <span class="special">));</span>
918
919     <span class="comment">// Setup the target address and port to send syslog messages to</span>
920     <span class="identifier">backend</span><span class="special">-&gt;</span><span class="identifier">set_target_address</span><span class="special">(</span><span class="string">"192.164.1.10"</span><span class="special">,</span> <span class="number">514</span><span class="special">);</span>
921
922     <span class="comment">// Create and fill in another level translator for "MyLevel" attribute of type string</span>
923     <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">syslog</span><span class="special">::</span><span class="identifier">custom_severity_mapping</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;</span> <span class="identifier">mapping</span><span class="special">(</span><span class="string">"MyLevel"</span><span class="special">);</span>
924     <span class="identifier">mapping</span><span class="special">[</span><span class="string">"debug"</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">syslog</span><span class="special">::</span><span class="identifier">debug</span><span class="special">;</span>
925     <span class="identifier">mapping</span><span class="special">[</span><span class="string">"normal"</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">syslog</span><span class="special">::</span><span class="identifier">info</span><span class="special">;</span>
926     <span class="identifier">mapping</span><span class="special">[</span><span class="string">"warning"</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">syslog</span><span class="special">::</span><span class="identifier">warning</span><span class="special">;</span>
927     <span class="identifier">mapping</span><span class="special">[</span><span class="string">"failure"</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">syslog</span><span class="special">::</span><span class="identifier">critical</span><span class="special">;</span>
928     <span class="identifier">backend</span><span class="special">-&gt;</span><span class="identifier">set_severity_mapper</span><span class="special">(</span><span class="identifier">mapping</span><span class="special">);</span>
929
930     <span class="comment">// Wrap it into the frontend and register in the core.</span>
931     <span class="identifier">core</span><span class="special">-&gt;</span><span class="identifier">add_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">sink_t</span> <span class="special">&gt;(</span><span class="identifier">backend</span><span class="special">));</span>
932 <span class="special">}</span>
933 </pre>
934 <p>
935         </p>
936 <div class="calloutlist"><table border="0" summary="Callout list">
937 <tr>
938 <td width="5%" valign="top" align="left"><p><a name="log.detailed.sink_backends.syslog.c1"></a><a href="#log.detailed.sink_backends.syslog.c0"><img src="../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a> </p></td>
939 <td valign="top" align="left"><p>
940               the logging facility
941             </p></td>
942 </tr>
943 <tr>
944 <td width="5%" valign="top" align="left"><p><a name="log.detailed.sink_backends.syslog.c3"></a><a href="#log.detailed.sink_backends.syslog.c2"><img src="../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a> </p></td>
945 <td valign="top" align="left"><p>
946               the native syslog API should be used
947             </p></td>
948 </tr>
949 <tr>
950 <td width="5%" valign="top" align="left"><p><a name="log.detailed.sink_backends.syslog.c5"></a><a href="#log.detailed.sink_backends.syslog.c4"><img src="../../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a> </p></td>
951 <td valign="top" align="left"><p>
952               the logging facility
953             </p></td>
954 </tr>
955 <tr>
956 <td width="5%" valign="top" align="left"><p><a name="log.detailed.sink_backends.syslog.c7"></a><a href="#log.detailed.sink_backends.syslog.c6"><img src="../../../../../../doc/src/images/callouts/4.png" alt="4" border="0"></a> </p></td>
957 <td valign="top" align="left"><p>
958               the built-in socket-based implementation should be used
959             </p></td>
960 </tr>
961 </table></div>
962 <p>
963           Please note that all syslog constants, as well as level extractors, are
964           declared within a nested namespace <code class="computeroutput"><span class="identifier">syslog</span></code>.
965           The library will not accept (and does not declare in the backend interface)
966           native syslog constants, which are macros, actually.
967         </p>
968 <p>
969           Also note that the backend will default to the built-in implementation
970           and <code class="computeroutput"><span class="identifier">user</span></code> logging facility,
971           if the corresponding constructor parameters are not specified.
972         </p>
973 <div class="tip"><table border="0" summary="Tip">
974 <tr>
975 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td>
976 <th align="left">Tip</th>
977 </tr>
978 <tr><td align="left" valign="top"><p>
979             The <code class="computeroutput"><span class="identifier">set_target_address</span></code>
980             method will also accept DNS names, which it will resolve to the actual
981             IP address. This feature, however, is not available in single threaded
982             builds.
983           </p></td></tr>
984 </table></div>
985 </div>
986 <div class="section">
987 <div class="titlepage"><div><div><h4 class="title">
988 <a name="log.detailed.sink_backends.debugger"></a><a class="link" href="sink_backends.html#log.detailed.sink_backends.debugger" title="Windows debugger output backend">Windows debugger
989         output backend</a>
990 </h4></div></div></div>
991 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../sinks.html#header.boost.log.sinks.debug_output_backend_hpp" title="Header &lt;boost/log/sinks/debug_output_backend.hpp&gt;">boost/log/sinks/debug_output_backend.hpp</a></code><span class="special">&gt;</span>
992 </pre>
993 <p>
994           Windows API has an interesting feature: a process, being run under a debugger,
995           is able to emit messages that will be intercepted and displayed in the
996           debugger window. For example, if an application is run under the Visual
997           Studio IDE it is able to write debug messages to the IDE window. The <code class="computeroutput"><a class="link" href="../../boost/log/sinks/basic_debug_output_backend.html" title="Class template basic_debug_output_backend">basic_debug_output_backend</a></code>
998           backend provides a simple way of emitting such messages. Additionally,
999           in order to optimize application performance, a <a class="link" href="expressions.html#log.detailed.expressions.predicates.is_debugger_present" title="Debugger presence filter">special
1000           filter</a> is available that checks whether the application is being
1001           run under a debugger. Like many other sink backends, this backend also
1002           supports setting a formatter in order to compose the message text.
1003         </p>
1004 <p>
1005           The usage is quite simple and straightforward:
1006         </p>
1007 <p>
1008 </p>
1009 <pre class="programlisting"><span class="comment">// Complete sink type</span>
1010 <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">debug_output_backend</span> <span class="special">&gt;</span> <span class="identifier">sink_t</span><span class="special">;</span>
1011
1012 <span class="keyword">void</span> <span class="identifier">init_logging</span><span class="special">()</span>
1013 <span class="special">{</span>
1014     <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span> <span class="special">&gt;</span> <span class="identifier">core</span> <span class="special">=</span> <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">();</span>
1015
1016     <span class="comment">// Create the sink. The backend requires synchronization in the frontend.</span>
1017     <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">sink_t</span> <span class="special">&gt;</span> <span class="identifier">sink</span><span class="special">(</span><span class="keyword">new</span> <span class="identifier">sink_t</span><span class="special">());</span>
1018
1019     <span class="comment">// Set the special filter to the frontend</span>
1020     <span class="comment">// in order to skip the sink when no debugger is available</span>
1021     <span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_filter</span><span class="special">(</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">is_debugger_present</span><span class="special">());</span>
1022
1023     <span class="identifier">core</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>
1024 <span class="special">}</span>
1025 </pre>
1026 <p>
1027         </p>
1028 <p>
1029           Note that the sink backend is templated on the character type. This type
1030           defines the Windows API version that is used to emit messages. Also, <code class="computeroutput"><span class="identifier">debug_output_backend</span></code> and <code class="computeroutput"><span class="identifier">wdebug_output_backend</span></code> convenience typedefs
1031           are provided.
1032         </p>
1033 </div>
1034 <div class="section">
1035 <div class="titlepage"><div><div><h4 class="title">
1036 <a name="log.detailed.sink_backends.event_log"></a><a class="link" href="sink_backends.html#log.detailed.sink_backends.event_log" title="Windows event log backends">Windows event
1037         log backends</a>
1038 </h4></div></div></div>
1039 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../../sinks.html#header.boost.log.sinks.event_log_backend_hpp" title="Header &lt;boost/log/sinks/event_log_backend.hpp&gt;">boost/log/sinks/event_log_backend.hpp</a></code><span class="special">&gt;</span>
1040 </pre>
1041 <p>
1042           Windows operating system provides a special API for publishing events related
1043           to application execution. A wide range of applications, including Windows
1044           components, use this facility to provide the user with all essential information
1045           about computer health in a single place - an event log. There can be more
1046           than one event log. However, typically all user-space applications use
1047           the common Application log. Records from different applications or their
1048           parts can be selected from the log by a record source name. Event logs
1049           can be read with a standard utility, an Event Viewer, that comes with Windows.
1050         </p>
1051 <p>
1052           Although it looks very tempting, the API is quite complicated and intrusive,
1053           which makes it difficult to support. The application is required to provide
1054           a dynamic library with special resources that describe all events the application
1055           supports. This library must be registered in the Windows registry, which
1056           pins its location in the file system. The Event Viewer uses this registration
1057           to find the resources and compose and display messages. The positive feature
1058           of this approach is that since event resources can describe events differently
1059           for different languages, it allows the application to support event internationalization
1060           in a quite transparent manner: the application simply provides event identifiers
1061           and non-localizable event parameters to the API, and it does the rest of
1062           the work.
1063         </p>
1064 <p>
1065           In order to support both the simplistic approach "it just works"
1066           and the more elaborate event composition, including internationalization
1067           support, the library provides two sink backends that work with event log
1068           API.
1069         </p>
1070 <h6>
1071 <a name="log.detailed.sink_backends.event_log.h0"></a>
1072           <span class="phrase"><a name="log.detailed.sink_backends.event_log.simple_event_log_backend"></a></span><a class="link" href="sink_backends.html#log.detailed.sink_backends.event_log.simple_event_log_backend">Simple
1073           event log backend</a>
1074         </h6>
1075 <p>
1076           The <code class="computeroutput"><a class="link" href="../../boost/log/sinks/basic_simple_e_idp64628096.html" title="Class template basic_simple_event_log_backend">basic_simple_event_log_backend</a></code>
1077           backend is intended to encapsulate as much of the event log API as possible,
1078           leaving interface and usage model very similar to other sink backends.
1079           It contains all resources that are needed for the Event Viewer to function
1080           properly, and registers the Boost.Log library in the Windows registry in
1081           order to populate itself as the container of these resources.
1082         </p>
1083 <div class="important"><table border="0" summary="Important">
1084 <tr>
1085 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../../doc/src/images/important.png"></td>
1086 <th align="left">Important</th>
1087 </tr>
1088 <tr><td align="left" valign="top"><p>
1089             The library must be built as a dynamic library in order to use this backend
1090             flawlessly. Otherwise event description resources are not linked into
1091             the executable, and the Event Viewer is not able to display events properly.
1092           </p></td></tr>
1093 </table></div>
1094 <p>
1095           The only thing user has to do to add Windows event log support to his application
1096           is to provide event source and log names (which are optional and can be
1097           automatically suggested by the library), set up an appropriate filter,
1098           formatter and event severity mapping.
1099         </p>
1100 <p>
1101 </p>
1102 <pre class="programlisting"><span class="comment">// Complete sink type</span>
1103 <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">simple_event_log_backend</span> <span class="special">&gt;</span> <span class="identifier">sink_t</span><span class="special">;</span>
1104
1105 <span class="comment">// Define application-specific severity levels</span>
1106 <span class="keyword">enum</span> <span class="identifier">severity_level</span>
1107 <span class="special">{</span>
1108     <span class="identifier">normal</span><span class="special">,</span>
1109     <span class="identifier">warning</span><span class="special">,</span>
1110     <span class="identifier">error</span>
1111 <span class="special">};</span>
1112
1113 <span class="keyword">void</span> <span class="identifier">init_logging</span><span class="special">()</span>
1114 <span class="special">{</span>
1115     <span class="comment">// Create an event log sink</span>
1116     <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">sink_t</span> <span class="special">&gt;</span> <span class="identifier">sink</span><span class="special">(</span><span class="keyword">new</span> <span class="identifier">sink_t</span><span class="special">());</span>
1117
1118     <span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_formatter</span>
1119     <span class="special">(</span>
1120         <span class="identifier">expr</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"%1%: [%2%] - %3%"</span><span class="special">)</span>
1121             <span class="special">%</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="string">"LineID"</span><span class="special">)</span>
1122             <span class="special">%</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">posix_time</span><span class="special">::</span><span class="identifier">ptime</span> <span class="special">&gt;(</span><span class="string">"TimeStamp"</span><span class="special">)</span>
1123             <span class="special">%</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">smessage</span>
1124     <span class="special">);</span>
1125
1126     <span class="comment">// We'll have to map our custom levels to the event log event types</span>
1127     <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">event_log</span><span class="special">::</span><span class="identifier">custom_event_type_mapping</span><span class="special">&lt;</span> <span class="identifier">severity_level</span> <span class="special">&gt;</span> <span class="identifier">mapping</span><span class="special">(</span><span class="string">"Severity"</span><span class="special">);</span>
1128     <span class="identifier">mapping</span><span class="special">[</span><span class="identifier">normal</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">event_log</span><span class="special">::</span><span class="identifier">info</span><span class="special">;</span>
1129     <span class="identifier">mapping</span><span class="special">[</span><span class="identifier">warning</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">event_log</span><span class="special">::</span><span class="identifier">warning</span><span class="special">;</span>
1130     <span class="identifier">mapping</span><span class="special">[</span><span class="identifier">error</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">event_log</span><span class="special">::</span><span class="identifier">error</span><span class="special">;</span>
1131
1132     <span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">locked_backend</span><span class="special">()-&gt;</span><span class="identifier">set_event_type_mapper</span><span class="special">(</span><span class="identifier">mapping</span><span class="special">);</span>
1133
1134     <span class="comment">// Add the sink to the core</span>
1135     <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>
1136 <span class="special">}</span>
1137 </pre>
1138 <p>
1139         </p>
1140 <p>
1141           Having done that, all logging records that pass to the sink will be formatted
1142           the same way they are in the other sinks. The formatted message will be
1143           displayed in the Event Viewer as the event description.
1144         </p>
1145 <h6>
1146 <a name="log.detailed.sink_backends.event_log.h1"></a>
1147           <span class="phrase"><a name="log.detailed.sink_backends.event_log.advanced_event_log_backend"></a></span><a class="link" href="sink_backends.html#log.detailed.sink_backends.event_log.advanced_event_log_backend">Advanced
1148           event log backend</a>
1149         </h6>
1150 <p>
1151           The <code class="computeroutput"><a class="link" href="../../boost/log/sinks/basic_event_log_backend.html" title="Class template basic_event_log_backend">basic_event_log_backend</a></code>
1152           allows more detailed control over the logging API, but requires considerably
1153           more scaffolding during initialization and usage.
1154         </p>
1155 <p>
1156           First, the user has to build his own library with the event resources (the
1157           process is described in <a href="http://msdn.microsoft.com/en-us/library/aa363681(VS.85).aspx" target="_top">MSDN</a>).
1158           As a part of this process one has to create a message file that describes
1159           all events. For the sake of example, let's assume the following contents
1160           were used as the message file:
1161         </p>
1162 <pre class="programlisting">; /* --------------------------------------------------------
1163 ; HEADER SECTION
1164 ; */
1165 SeverityNames=(Debug=0x0:MY_SEVERITY_DEBUG
1166             Info=0x1:MY_SEVERITY_INFO
1167             Warning=0x2:MY_SEVERITY_WARNING
1168             Error=0x3:MY_SEVERITY_ERROR
1169             )
1170
1171 ; /* --------------------------------------------------------
1172 ; MESSAGE DEFINITION SECTION
1173 ; */
1174
1175 MessageIdTypedef=WORD
1176
1177 MessageId=0x1
1178 SymbolicName=MY_CATEGORY_1
1179 Language=English
1180 Category 1
1181 .
1182
1183 MessageId=0x2
1184 SymbolicName=MY_CATEGORY_2
1185 Language=English
1186 Category 2
1187 .
1188
1189 MessageId=0x3
1190 SymbolicName=MY_CATEGORY_3
1191 Language=English
1192 Category 3
1193 .
1194
1195 MessageIdTypedef=DWORD
1196
1197 MessageId=0x100
1198 Severity=Warning
1199 Facility=Application
1200 SymbolicName=LOW_DISK_SPACE_MSG
1201 Language=English
1202 The drive %1 has low free disk space. At least %2 Mb of free space is recommended.
1203 .
1204
1205 MessageId=0x101
1206 Severity=Error
1207 Facility=Application
1208 SymbolicName=DEVICE_INACCESSIBLE_MSG
1209 Language=English
1210 The drive %1 is not accessible.
1211 .
1212
1213 MessageId=0x102
1214 Severity=Info
1215 Facility=Application
1216 SymbolicName=SUCCEEDED_MSG
1217 Language=English
1218 Operation finished successfully in %1 seconds.
1219 .
1220 </pre>
1221 <p>
1222           After compiling the resource library, the path to this library must be
1223           provided to the sink backend constructor, among other parameters used with
1224           the simple backend. The path may contain placeholders that will be expanded
1225           with the appropriate environment variables.
1226         </p>
1227 <p>
1228 </p>
1229 <pre class="programlisting"><span class="comment">// Create an event log sink</span>
1230 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">event_log_backend</span> <span class="special">&gt;</span> <span class="identifier">backend</span><span class="special">(</span>
1231     <span class="keyword">new</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">event_log_backend</span><span class="special">((</span>
1232         <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">message_file</span> <span class="special">=</span> <span class="string">"%SystemDir%\\event_log_messages.dll"</span><span class="special">,</span>
1233         <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">log_name</span> <span class="special">=</span> <span class="string">"My Application"</span><span class="special">,</span>
1234         <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">log_source</span> <span class="special">=</span> <span class="string">"My Source"</span>
1235     <span class="special">))</span>
1236 <span class="special">);</span>
1237 </pre>
1238 <p>
1239         </p>
1240 <p>
1241           Like the simple backend, <code class="computeroutput"><a class="link" href="../../boost/log/sinks/basic_event_log_backend.html" title="Class template basic_event_log_backend">basic_event_log_backend</a></code>
1242           will register itself in the Windows registry, which will enable the Event
1243           Viewer to display the emitted events.
1244         </p>
1245 <p>
1246           Next, the user will have to provide the mapping between the application
1247           logging attributes and event identifiers. These identifiers were provided
1248           in the message compiler output as a result of compiling the message file.
1249           One can use <code class="computeroutput"><a class="link" href="../../boost/log/sinks/event_log/basic_event_composer.html" title="Class template basic_event_composer">basic_event_composer</a></code>
1250           and one of the event ID mappings, like in the following example:
1251         </p>
1252 <p>
1253 </p>
1254 <pre class="programlisting"><span class="comment">// Create an event composer. It is initialized with the event identifier mapping.</span>
1255 <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">event_log</span><span class="special">::</span><span class="identifier">event_composer</span> <span class="identifier">composer</span><span class="special">(</span>
1256     <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">event_log</span><span class="special">::</span><span class="identifier">direct_event_id_mapping</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="string">"EventID"</span><span class="special">));</span>
1257
1258 <span class="comment">// For each event described in the message file, set up the insertion string formatters</span>
1259 <span class="identifier">composer</span><span class="special">[</span><span class="identifier">LOW_DISK_SPACE_MSG</span><span class="special">]</span>
1260     <span class="comment">// the first placeholder in the message</span>
1261     <span class="comment">// will be replaced with contents of the "Drive" attribute</span>
1262     <span class="special">%</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;(</span><span class="string">"Drive"</span><span class="special">)</span>
1263     <span class="comment">// the second placeholder in the message</span>
1264     <span class="comment">// will be replaced with contents of the "Size" attribute</span>
1265     <span class="special">%</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span> <span class="special">&gt;(</span><span class="string">"Size"</span><span class="special">);</span>
1266
1267 <span class="identifier">composer</span><span class="special">[</span><span class="identifier">DEVICE_INACCESSIBLE_MSG</span><span class="special">]</span>
1268     <span class="special">%</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;(</span><span class="string">"Drive"</span><span class="special">);</span>
1269
1270 <span class="identifier">composer</span><span class="special">[</span><span class="identifier">SUCCEEDED_MSG</span><span class="special">]</span>
1271     <span class="special">%</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="string">"Duration"</span><span class="special">);</span>
1272
1273 <span class="comment">// Then put the composer to the backend</span>
1274 <span class="identifier">backend</span><span class="special">-&gt;</span><span class="identifier">set_event_composer</span><span class="special">(</span><span class="identifier">composer</span><span class="special">);</span>
1275 </pre>
1276 <p>
1277         </p>
1278 <p>
1279           As you can see, one can use regular <a class="link" href="expressions.html#log.detailed.expressions.formatters" title="Formatting expressions">formatters</a>
1280           to specify which attributes will be inserted instead of placeholders in
1281           the final event message. Aside from that, one can specify mappings of attribute
1282           values to event types and categories. Suppose our application has the following
1283           severity levels:
1284         </p>
1285 <p>
1286 </p>
1287 <pre class="programlisting"><span class="comment">// Define application-specific severity levels</span>
1288 <span class="keyword">enum</span> <span class="identifier">severity_level</span>
1289 <span class="special">{</span>
1290     <span class="identifier">normal</span><span class="special">,</span>
1291     <span class="identifier">warning</span><span class="special">,</span>
1292     <span class="identifier">error</span>
1293 <span class="special">};</span>
1294 </pre>
1295 <p>
1296         </p>
1297 <p>
1298           Then these levels can be mapped onto the values in the message description
1299           file:
1300         </p>
1301 <p>
1302 </p>
1303 <pre class="programlisting"><span class="comment">// We'll have to map our custom levels to the event log event types</span>
1304 <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">event_log</span><span class="special">::</span><span class="identifier">custom_event_type_mapping</span><span class="special">&lt;</span> <span class="identifier">severity_level</span> <span class="special">&gt;</span> <span class="identifier">type_mapping</span><span class="special">(</span><span class="string">"Severity"</span><span class="special">);</span>
1305 <span class="identifier">type_mapping</span><span class="special">[</span><span class="identifier">normal</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">event_log</span><span class="special">::</span><span class="identifier">make_event_type</span><span class="special">(</span><span class="identifier">MY_SEVERITY_INFO</span><span class="special">);</span>
1306 <span class="identifier">type_mapping</span><span class="special">[</span><span class="identifier">warning</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">event_log</span><span class="special">::</span><span class="identifier">make_event_type</span><span class="special">(</span><span class="identifier">MY_SEVERITY_WARNING</span><span class="special">);</span>
1307 <span class="identifier">type_mapping</span><span class="special">[</span><span class="identifier">error</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">event_log</span><span class="special">::</span><span class="identifier">make_event_type</span><span class="special">(</span><span class="identifier">MY_SEVERITY_ERROR</span><span class="special">);</span>
1308
1309 <span class="identifier">backend</span><span class="special">-&gt;</span><span class="identifier">set_event_type_mapper</span><span class="special">(</span><span class="identifier">type_mapping</span><span class="special">);</span>
1310
1311 <span class="comment">// Same for event categories.</span>
1312 <span class="comment">// Usually event categories can be restored by the event identifier.</span>
1313 <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">event_log</span><span class="special">::</span><span class="identifier">custom_event_category_mapping</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;</span> <span class="identifier">cat_mapping</span><span class="special">(</span><span class="string">"EventID"</span><span class="special">);</span>
1314 <span class="identifier">cat_mapping</span><span class="special">[</span><span class="identifier">LOW_DISK_SPACE_MSG</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">event_log</span><span class="special">::</span><span class="identifier">make_event_category</span><span class="special">(</span><span class="identifier">MY_CATEGORY_1</span><span class="special">);</span>
1315 <span class="identifier">cat_mapping</span><span class="special">[</span><span class="identifier">DEVICE_INACCESSIBLE_MSG</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">event_log</span><span class="special">::</span><span class="identifier">make_event_category</span><span class="special">(</span><span class="identifier">MY_CATEGORY_2</span><span class="special">);</span>
1316 <span class="identifier">cat_mapping</span><span class="special">[</span><span class="identifier">SUCCEEDED_MSG</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">event_log</span><span class="special">::</span><span class="identifier">make_event_category</span><span class="special">(</span><span class="identifier">MY_CATEGORY_3</span><span class="special">);</span>
1317
1318 <span class="identifier">backend</span><span class="special">-&gt;</span><span class="identifier">set_event_category_mapper</span><span class="special">(</span><span class="identifier">cat_mapping</span><span class="special">);</span>
1319 </pre>
1320 <p>
1321         </p>
1322 <div class="tip"><table border="0" summary="Tip">
1323 <tr>
1324 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td>
1325 <th align="left">Tip</th>
1326 </tr>
1327 <tr><td align="left" valign="top"><p>
1328             As of Windows NT 6 (Vista, Server 2008) it is not needed to specify event
1329             type mappings. This information is available in the message definition
1330             resources and need not be duplicated in the API call.
1331           </p></td></tr>
1332 </table></div>
1333 <p>
1334           Now that initialization is done, the sink can be registered into the core.
1335         </p>
1336 <p>
1337 </p>
1338 <pre class="programlisting"><span class="comment">// Create the frontend for the sink</span>
1339 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</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">event_log_backend</span> <span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">sink</span><span class="special">(</span>
1340     <span class="keyword">new</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">event_log_backend</span> <span class="special">&gt;(</span><span class="identifier">backend</span><span class="special">));</span>
1341
1342 <span class="comment">// Set up filter to pass only records that have the necessary attribute</span>
1343 <span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_filter</span><span class="special">(</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">has_attr</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="string">"EventID"</span><span class="special">));</span>
1344
1345 <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>
1346 </pre>
1347 <p>
1348         </p>
1349 <p>
1350           In order to emit events it is convenient to create a set of functions that
1351           will accept all needed parameters for the corresponding events and announce
1352           that the event has occurred.
1353         </p>
1354 <p>
1355 </p>
1356 <pre class="programlisting"><span class="identifier">BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT</span><span class="special">(</span><span class="identifier">event_logger</span><span class="special">,</span> <span class="identifier">src</span><span class="special">::</span><span class="identifier">severity_logger_mt</span><span class="special">&lt;</span> <span class="identifier">severity_level</span> <span class="special">&gt;)</span>
1357
1358 <span class="comment">// The function raises an event of the disk space depletion</span>
1359 <span class="keyword">void</span> <span class="identifier">announce_low_disk_space</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">drive</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span> <span class="identifier">size</span><span class="special">)</span>
1360 <span class="special">{</span>
1361     <span class="identifier">BOOST_LOG_SCOPED_THREAD_TAG</span><span class="special">(</span><span class="string">"EventID"</span><span class="special">,</span> <span class="special">(</span><span class="keyword">int</span><span class="special">)</span><span class="identifier">LOW_DISK_SPACE_MSG</span><span class="special">);</span>
1362     <span class="identifier">BOOST_LOG_SCOPED_THREAD_TAG</span><span class="special">(</span><span class="string">"Drive"</span><span class="special">,</span> <span class="identifier">drive</span><span class="special">);</span>
1363     <span class="identifier">BOOST_LOG_SCOPED_THREAD_TAG</span><span class="special">(</span><span class="string">"Size"</span><span class="special">,</span> <span class="identifier">size</span><span class="special">);</span>
1364     <span class="comment">// Since this record may get accepted by other sinks,</span>
1365     <span class="comment">// this message is not completely useless</span>
1366     <span class="identifier">BOOST_LOG_SEV</span><span class="special">(</span><span class="identifier">event_logger</span><span class="special">::</span><span class="identifier">get</span><span class="special">(),</span> <span class="identifier">warning</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">"Low disk "</span> <span class="special">&lt;&lt;</span> <span class="identifier">drive</span>
1367         <span class="special">&lt;&lt;</span> <span class="string">" space, "</span> <span class="special">&lt;&lt;</span> <span class="identifier">size</span> <span class="special">&lt;&lt;</span> <span class="string">" Mb is recommended"</span><span class="special">;</span>
1368 <span class="special">}</span>
1369
1370 <span class="comment">// The function raises an event of inaccessible disk drive</span>
1371 <span class="keyword">void</span> <span class="identifier">announce_device_inaccessible</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">drive</span><span class="special">)</span>
1372 <span class="special">{</span>
1373     <span class="identifier">BOOST_LOG_SCOPED_THREAD_TAG</span><span class="special">(</span><span class="string">"EventID"</span><span class="special">,</span> <span class="special">(</span><span class="keyword">int</span><span class="special">)</span><span class="identifier">DEVICE_INACCESSIBLE_MSG</span><span class="special">);</span>
1374     <span class="identifier">BOOST_LOG_SCOPED_THREAD_TAG</span><span class="special">(</span><span class="string">"Drive"</span><span class="special">,</span> <span class="identifier">drive</span><span class="special">);</span>
1375     <span class="identifier">BOOST_LOG_SEV</span><span class="special">(</span><span class="identifier">event_logger</span><span class="special">::</span><span class="identifier">get</span><span class="special">(),</span> <span class="identifier">error</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">"Cannot access drive "</span> <span class="special">&lt;&lt;</span> <span class="identifier">drive</span><span class="special">;</span>
1376 <span class="special">}</span>
1377
1378 <span class="comment">// The structure is an activity guard that will emit an event upon the activity completion</span>
1379 <span class="keyword">struct</span> <span class="identifier">activity_guard</span>
1380 <span class="special">{</span>
1381     <span class="identifier">activity_guard</span><span class="special">()</span>
1382     <span class="special">{</span>
1383         <span class="comment">// Add a stop watch attribute to measure the activity duration</span>
1384         <span class="identifier">m_it</span> <span class="special">=</span> <span class="identifier">event_logger</span><span class="special">::</span><span class="identifier">get</span><span class="special">().</span><span class="identifier">add_attribute</span><span class="special">(</span><span class="string">"Duration"</span><span class="special">,</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">timer</span><span class="special">()).</span><span class="identifier">first</span><span class="special">;</span>
1385     <span class="special">}</span>
1386     <span class="special">~</span><span class="identifier">activity_guard</span><span class="special">()</span>
1387     <span class="special">{</span>
1388         <span class="identifier">BOOST_LOG_SCOPED_THREAD_TAG</span><span class="special">(</span><span class="string">"EventID"</span><span class="special">,</span> <span class="special">(</span><span class="keyword">int</span><span class="special">)</span><span class="identifier">SUCCEEDED_MSG</span><span class="special">);</span>
1389         <span class="identifier">BOOST_LOG_SEV</span><span class="special">(</span><span class="identifier">event_logger</span><span class="special">::</span><span class="identifier">get</span><span class="special">(),</span> <span class="identifier">normal</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">"Activity ended"</span><span class="special">;</span>
1390         <span class="identifier">event_logger</span><span class="special">::</span><span class="identifier">get</span><span class="special">().</span><span class="identifier">remove_attribute</span><span class="special">(</span><span class="identifier">m_it</span><span class="special">);</span>
1391     <span class="special">}</span>
1392
1393 <span class="keyword">private</span><span class="special">:</span>
1394     <span class="identifier">logging</span><span class="special">::</span><span class="identifier">attribute_set</span><span class="special">::</span><span class="identifier">iterator</span> <span class="identifier">m_it</span><span class="special">;</span>
1395 <span class="special">};</span>
1396 </pre>
1397 <p>
1398         </p>
1399 <p>
1400           Now you are able to call these helper functions to emit events. The complete
1401           code from this section is available in the <a href="../../../../../../libs/log/example/event_log/main.cpp" target="_top"><code class="computeroutput"><span class="identifier">event_log</span></code></a> example in the library
1402           distribution.
1403         </p>
1404 </div>
1405 </div>
1406 <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
1407 <td align="left"></td>
1408 <td align="right"><div class="copyright-footer">Copyright &#169; 2007-2016 Andrey Semashev<p>
1409         Distributed under the Boost Software License, Version 1.0. (See accompanying
1410         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>).
1411       </p>
1412 </div></td>
1413 </tr></table>
1414 <hr>
1415 <div class="spirit-nav">
1416 <a accesskey="p" href="sink_frontends.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../detailed.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="expressions.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
1417 </div>
1418 </body>
1419 </html>