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