1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 4<title>Log record formatting</title> 5<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css"> 6<meta name="generator" content="DocBook XSL Stylesheets V1.79.1"> 7<link rel="home" href="../../index.html" title="Chapter 1. Boost.Log v2"> 8<link rel="up" href="../tutorial.html" title="Tutorial"> 9<link rel="prev" href="attributes.html" title="Adding more information to log: Attributes"> 10<link rel="next" href="advanced_filtering.html" title="Filtering revisited"> 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="attributes.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="advanced_filtering.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> 17</div> 18<div class="section"> 19<div class="titlepage"><div><div><h3 class="title"> 20<a name="log.tutorial.formatters"></a><a class="link" href="formatters.html" title="Log record formatting">Log record formatting</a> 21</h3></div></div></div> 22<p> 23 If you tried running examples from the previous sections, you may have noticed 24 that only log record messages are written to the files. This is the default 25 behavior of the library when no formatter is set. Even if you added attributes 26 to the logging core or a logger, the attribute values will not reach the 27 output unless you specify a formatter that will use these values. 28 </p> 29<p> 30 Returning to one of the examples in previous tutorial sections: 31 </p> 32<p> 33</p> 34<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">init</span><span class="special">()</span> 35<span class="special">{</span> 36 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">add_file_log</span> 37 <span class="special">(</span> 38 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">file_name</span> <span class="special">=</span> <span class="string">"sample_%N.log"</span><span class="special">,</span> 39 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">rotation_size</span> <span class="special">=</span> <span class="number">10</span> <span class="special">*</span> <span class="number">1024</span> <span class="special">*</span> <span class="number">1024</span><span class="special">,</span> 40 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">time_based_rotation</span> <span class="special">=</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">file</span><span class="special">::</span><span class="identifier">rotation_at_time_point</span><span class="special">(</span><span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="number">0</span><span class="special">),</span> 41 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">format</span> <span class="special">=</span> <span class="string">"[%TimeStamp%]: %Message%"</span> 42 <span class="special">);</span> 43 44 <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">set_filter</span> 45 <span class="special">(</span> 46 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">trivial</span><span class="special">::</span><span class="identifier">severity</span> <span class="special">>=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">trivial</span><span class="special">::</span><span class="identifier">info</span> 47 <span class="special">);</span> 48<span class="special">}</span> 49</pre> 50<p> 51 </p> 52<p> 53 In the case of the <code class="computeroutput"><span class="identifier">add_file_log</span></code> 54 function, the <code class="computeroutput"><span class="identifier">format</span></code> parameter 55 allows to specify format of the log records. If you prefer to set up sinks 56 manually, sink frontends provide the <code class="computeroutput"><span class="identifier">set_formatter</span></code> 57 member function for this purpose. 58 </p> 59<p> 60 The format can be specified in a number of ways, as described further. 61 </p> 62<h5> 63<a name="log.tutorial.formatters.h0"></a> 64 <span class="phrase"><a name="log.tutorial.formatters.lambda_style_formatters"></a></span><a class="link" href="formatters.html#log.tutorial.formatters.lambda_style_formatters">Lambda-style 65 formatters</a> 66 </h5> 67<p> 68 You can create a formatter with a lambda-style expression like this: 69 </p> 70<p> 71</p> 72<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">init</span><span class="special">()</span> 73<span class="special">{</span> 74 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">add_file_log</span> 75 <span class="special">(</span> 76 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">file_name</span> <span class="special">=</span> <span class="string">"sample_%N.log"</span><span class="special">,</span> 77 <span class="comment">// This makes the sink to write log records that look like this:</span> 78 <span class="comment">// 1: <normal> A normal severity message</span> 79 <span class="comment">// 2: <error> An error severity message</span> 80 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">format</span> <span class="special">=</span> 81 <span class="special">(</span> 82 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> 83 <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> 84 <span class="special"><<</span> <span class="string">": <"</span> <span class="special"><<</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">trivial</span><span class="special">::</span><span class="identifier">severity</span> 85 <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> 86 <span class="special">)</span> 87 <span class="special">);</span> 88<span class="special">}</span> 89</pre> 90<p> 91 </p> 92<p> 93 <a href="../../../../../../libs/log/example/doc/tutorial_fmt_stream.cpp" target="_top">See the 94 complete code</a>. 95 </p> 96<p> 97 Here the <code class="computeroutput"><span class="identifier">stream</span></code> is a placeholder 98 for the stream to format the record in. Other insertion arguments, such as 99 <a class="link" href="../detailed/expressions.html#log.detailed.expressions.attr" title="Generic attribute placeholder"><code class="computeroutput"><span class="identifier">attr</span></code></a> 100 and <a class="link" href="../detailed/expressions.html#log.detailed.expressions.message" title="Message text placeholders"><code class="computeroutput"><span class="identifier">message</span></code></a>, 101 are manipulators that define what should be stored in the stream. We have 102 already seen the <code class="computeroutput"><span class="identifier">severity</span></code> 103 placeholder in filtering expressions, and here it is used in a formatter. 104 This is a nice unification: you can use the same placeholders in both filters 105 and formatters. The <a class="link" href="../detailed/expressions.html#log.detailed.expressions.attr" title="Generic attribute placeholder"><code class="computeroutput"><span class="identifier">attr</span></code></a> placeholder is similar to the 106 <code class="computeroutput"><span class="identifier">severity</span></code> placeholder as it 107 represents the attribute value, too. The difference is that the <code class="computeroutput"><span class="identifier">severity</span></code> placeholder represents the particular 108 attribute with the name "Severity" and type <code class="computeroutput"><span class="identifier">trivial</span><span class="special">::</span><span class="identifier">severity_level</span></code> 109 and <a class="link" href="../detailed/expressions.html#log.detailed.expressions.attr" title="Generic attribute placeholder"><code class="computeroutput"><span class="identifier">attr</span></code></a> 110 can be used to represent any attribute. Otherwise the two placeholders are 111 equivalent. For instance, it is possible to replace <code class="computeroutput"><span class="identifier">severity</span></code> 112 with the following: 113 </p> 114<pre class="programlisting"><span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special"><</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">trivial</span><span class="special">::</span><span class="identifier">severity_level</span> <span class="special">>(</span><span class="string">"Severity"</span><span class="special">)</span> 115</pre> 116<div class="tip"><table border="0" summary="Tip"> 117<tr> 118<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td> 119<th align="left">Tip</th> 120</tr> 121<tr><td align="left" valign="top"><p> 122 As shown in the previous section, it is possible to define placeholders 123 like <code class="computeroutput"><span class="identifier">severity</span></code> for user's 124 attributes. As an additional benefit to the simpler syntax in the template 125 expressions such placeholders allow to concentrate all the information 126 about the attribute (the name and the value type) in the placeholder definition. 127 This makes coding less error-prone (you won't misspell the attribute name 128 or specify incorrect value type) and therefore is the recommended way of 129 defining new attributes and using them in template expressions. 130 </p></td></tr> 131</table></div> 132<p> 133 There are other <a class="link" href="../detailed/expressions.html#log.detailed.expressions.formatters" title="Formatting expressions">formatter 134 manipulators</a> that provide advanced support for date, time and other 135 types. Some manipulators accept additional arguments that customize their 136 behavior. Most of these arguments are named and can be passed in <a href="http://www.boost.org/doc/libs/release/libs/parameter/doc/html/index.html" target="_top">Boost.Parameter</a> 137 style. 138 </p> 139<p> 140 For a change, let's see how it's done when manually initializing sinks: 141 </p> 142<p> 143</p> 144<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">init</span><span class="special">()</span> 145<span class="special">{</span> 146 <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">text_sink</span><span class="special">;</span> 147 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span> <span class="identifier">text_sink</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">text_sink</span> <span class="special">>();</span> 148 149 <span class="identifier">sink</span><span class="special">-></span><span class="identifier">locked_backend</span><span class="special">()-></span><span class="identifier">add_stream</span><span class="special">(</span> 150 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special"><</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> 151 152 <span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span> 153 <span class="special">(</span> 154 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> 155 <span class="comment">// line id will be written in hex, 8-digits, zero-filled</span> 156 <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">hex</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">setw</span><span class="special">(</span><span class="number">8</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">setfill</span><span class="special">(</span><span class="char">'0'</span><span class="special">)</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="keyword">unsigned</span> <span class="keyword">int</span> <span class="special">>(</span><span class="string">"LineID"</span><span class="special">)</span> 157 <span class="special"><<</span> <span class="string">": <"</span> <span class="special"><<</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">trivial</span><span class="special">::</span><span class="identifier">severity</span> 158 <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> 159 <span class="special">);</span> 160 161 <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> 162<span class="special">}</span> 163</pre> 164<p> 165 </p> 166<p> 167 <a href="../../../../../../libs/log/example/doc/tutorial_fmt_stream_manual.cpp" target="_top">See 168 the complete code</a>. 169 </p> 170<p> 171 You can see that it is possible to bind format changing manipulators in the 172 expression; these manipulators will affect the subsequent attribute value 173 format when log record is formatted, just like with streams. More manipulators 174 are described in the <a class="link" href="../detailed/expressions.html" title="Lambda expressions">Detailed features 175 description</a> section. 176 </p> 177<h5> 178<a name="log.tutorial.formatters.h1"></a> 179 <span class="phrase"><a name="log.tutorial.formatters.boost_format_style_formatters"></a></span><a class="link" href="formatters.html#log.tutorial.formatters.boost_format_style_formatters">Boost.Format-style 180 formatters</a> 181 </h5> 182<p> 183 As an alternative, you can define formatters with a syntax similar to <a href="http://www.boost.org/doc/libs/release/libs/format/index.html" target="_top">Boost.Format</a>. 184 The same formatter as described above can be written as follows: 185 </p> 186<p> 187</p> 188<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">init</span><span class="special">()</span> 189<span class="special">{</span> 190 <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">text_sink</span><span class="special">;</span> 191 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span> <span class="identifier">text_sink</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">text_sink</span> <span class="special">>();</span> 192 193 <span class="identifier">sink</span><span class="special">-></span><span class="identifier">locked_backend</span><span class="special">()-></span><span class="identifier">add_stream</span><span class="special">(</span> 194 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special"><</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> 195 196 <span class="comment">// This makes the sink to write log records that look like this:</span> 197 <span class="comment">// 1: <normal> A normal severity message</span> 198 <span class="comment">// 2: <error> An error severity message</span> 199 <span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span> 200 <span class="special">(</span> 201 <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> 202 <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> 203 <span class="special">%</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">trivial</span><span class="special">::</span><span class="identifier">severity</span> 204 <span class="special">%</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">smessage</span> 205 <span class="special">);</span> 206 207 <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> 208<span class="special">}</span> 209</pre> 210<p> 211 </p> 212<p> 213 <a href="../../../../../../libs/log/example/doc/tutorial_fmt_format.cpp" target="_top">See the 214 complete code</a>. 215 </p> 216<p> 217 The <code class="computeroutput"><span class="identifier">format</span></code> placeholder accepts 218 the format string with positional specification of all arguments being formatted. 219 Note that only positional format is currently supported. The same format 220 specification can be used with the <code class="computeroutput"><span class="identifier">add_file_log</span></code> 221 and similar functions. 222 </p> 223<h5> 224<a name="log.tutorial.formatters.h2"></a> 225 <span class="phrase"><a name="log.tutorial.formatters.specialized_formatters"></a></span><a class="link" href="formatters.html#log.tutorial.formatters.specialized_formatters">Specialized 226 formatters</a> 227 </h5> 228<p> 229 The library provides specialized formatters for a number of types, such as 230 date, time and named scope. These formatters provide extended control over 231 the formatted values. For example, it is possible to describe date and time 232 format with a format string compatible with <a href="http://www.boost.org/doc/libs/release/doc/html/date_time.html" target="_top">Boost.DateTime</a>: 233 </p> 234<p> 235</p> 236<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">init</span><span class="special">()</span> 237<span class="special">{</span> 238 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">add_file_log</span> 239 <span class="special">(</span> 240 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">file_name</span> <span class="special">=</span> <span class="string">"sample_%N.log"</span><span class="special">,</span> 241 <span class="comment">// This makes the sink to write log records that look like this:</span> 242 <span class="comment">// YYYY-MM-DD HH:MI:SS: <normal> A normal severity message</span> 243 <span class="comment">// YYYY-MM-DD HH:MI:SS: <error> An error severity message</span> 244 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">format</span> <span class="special">=</span> 245 <span class="special">(</span> 246 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> 247 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">format_date_time</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> <span class="string">"%Y-%m-%d %H:%M:%S"</span><span class="special">)</span> 248 <span class="special"><<</span> <span class="string">": <"</span> <span class="special"><<</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">trivial</span><span class="special">::</span><span class="identifier">severity</span> 249 <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> 250 <span class="special">)</span> 251 <span class="special">);</span> 252<span class="special">}</span> 253</pre> 254<p> 255 </p> 256<p> 257 <a href="../../../../../../libs/log/example/doc/tutorial_fmt_stream.cpp" target="_top">See the 258 complete code</a>. 259 </p> 260<p> 261 The same formatter can also be used in the context of a <a href="http://www.boost.org/doc/libs/release/libs/format/index.html" target="_top">Boost.Format</a>-style 262 formatter. 263 </p> 264<h5> 265<a name="log.tutorial.formatters.h3"></a> 266 <span class="phrase"><a name="log.tutorial.formatters.string_templates_as_formatters"></a></span><a class="link" href="formatters.html#log.tutorial.formatters.string_templates_as_formatters">String templates 267 as formatters</a> 268 </h5> 269<p> 270 In some contexts textual templates are accepted as formatters. In this case 271 library initialization support code is invoked in order to parse the template 272 and reconstruct the appropriate formatter. There are a number of caveats 273 to keep in mind when using this approach, but here it will suffice to just 274 briefly describe the template format. 275 </p> 276<p> 277</p> 278<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">init</span><span class="special">()</span> 279<span class="special">{</span> 280 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">add_file_log</span> 281 <span class="special">(</span> 282 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">file_name</span> <span class="special">=</span> <span class="string">"sample_%N.log"</span><span class="special">,</span> 283 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">format</span> <span class="special">=</span> <span class="string">"[%TimeStamp%]: %Message%"</span> 284 <span class="special">);</span> 285<span class="special">}</span> 286</pre> 287<p> 288 </p> 289<p> 290 <a href="../../../../../../libs/log/example/doc/tutorial_fmt_string.cpp" target="_top">See the 291 complete code</a>. 292 </p> 293<p> 294 Here, the <code class="computeroutput"><span class="identifier">format</span></code> parameter 295 accepts such a format template. The template may contain a number of placeholders 296 enclosed with percent signs (<code class="computeroutput"><span class="special">%</span></code>). 297 Each placeholder must contain an attribute value name to insert instead of 298 the placeholder. The <code class="computeroutput"><span class="special">%</span><span class="identifier">Message</span><span class="special">%</span></code> placeholder will be replaced with the logging 299 record message. 300 </p> 301<div class="note"><table border="0" summary="Note"> 302<tr> 303<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td> 304<th align="left">Note</th> 305</tr> 306<tr><td align="left" valign="top"><p> 307 Textual format templates are not accepted by sink backends in the <code class="computeroutput"><span class="identifier">set_formatter</span></code> method. In order to parse 308 textual template into a formatter function one has to call <code class="computeroutput"><span class="identifier">parse_formatter</span></code> function. See <a class="link" href="../detailed/utilities.html#log.detailed.utilities.setup.filter_formatter" title="Filter and formatter parsers">here</a> 309 for more details. 310 </p></td></tr> 311</table></div> 312<h5> 313<a name="log.tutorial.formatters.h4"></a> 314 <span class="phrase"><a name="log.tutorial.formatters.custom_formatting_functions"></a></span><a class="link" href="formatters.html#log.tutorial.formatters.custom_formatting_functions">Custom 315 formatting functions</a> 316 </h5> 317<p> 318 You can add a custom formatter to a sink backend that supports formatting. 319 The formatter is actually a function object that supports the following signature: 320 </p> 321<pre class="programlisting"><span class="keyword">void</span> <span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">record_view</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">rec</span><span class="special">,</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">basic_formatting_ostream</span><span class="special"><</span> <span class="identifier">CharT</span> <span class="special">>&</span> <span class="identifier">strm</span><span class="special">);</span> 322</pre> 323<p> 324 Here <code class="computeroutput"><span class="identifier">CharT</span></code> is the target 325 character type. The formatter will be invoked whenever a log record view 326 <code class="computeroutput"><span class="identifier">rec</span></code> passes filtering and 327 is to be stored in log. 328 </p> 329<div class="tip"><table border="0" summary="Tip"> 330<tr> 331<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td> 332<th align="left">Tip</th> 333</tr> 334<tr><td align="left" valign="top"><p> 335 Record views are very similar to records. The notable distinction is that 336 the view is immutable and implements shallow copy. Formatters and sinks 337 only operate on record views, which prevents them from modifying the record 338 while it can be still in use by other sinks in other threads. 339 </p></td></tr> 340</table></div> 341<p> 342 The formatted record should be composed by insertion into STL-compatible 343 output stream <code class="computeroutput"><span class="identifier">strm</span></code>. Here's 344 an example of a custom formatter function usage: 345 </p> 346<p> 347</p> 348<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">my_formatter</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">record_view</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">rec</span><span class="special">,</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">formatting_ostream</span><span class="special">&</span> <span class="identifier">strm</span><span class="special">)</span> 349<span class="special">{</span> 350 <span class="comment">// Get the LineID attribute value and put it into the stream</span> 351 <span class="identifier">strm</span> <span class="special"><<</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">extract</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> <span class="identifier">rec</span><span class="special">)</span> <span class="special"><<</span> <span class="string">": "</span><span class="special">;</span> 352 353 <span class="comment">// The same for the severity level.</span> 354 <span class="comment">// The simplified syntax is possible if attribute keywords are used.</span> 355 <span class="identifier">strm</span> <span class="special"><<</span> <span class="string">"<"</span> <span class="special"><<</span> <span class="identifier">rec</span><span class="special">[</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">trivial</span><span class="special">::</span><span class="identifier">severity</span><span class="special">]</span> <span class="special"><<</span> <span class="string">"> "</span><span class="special">;</span> 356 357 <span class="comment">// Finally, put the record message to the stream</span> 358 <span class="identifier">strm</span> <span class="special"><<</span> <span class="identifier">rec</span><span class="special">[</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">smessage</span><span class="special">];</span> 359<span class="special">}</span> 360 361<span class="keyword">void</span> <span class="identifier">init</span><span class="special">()</span> 362<span class="special">{</span> 363 <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">text_sink</span><span class="special">;</span> 364 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span> <span class="identifier">text_sink</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">text_sink</span> <span class="special">>();</span> 365 366 <span class="identifier">sink</span><span class="special">-></span><span class="identifier">locked_backend</span><span class="special">()-></span><span class="identifier">add_stream</span><span class="special">(</span> 367 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special"><</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> 368 369 <span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span><span class="special">(&</span><span class="identifier">my_formatter</span><span class="special">);</span> 370 371 <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> 372<span class="special">}</span> 373</pre> 374<p> 375 </p> 376<p> 377 <a href="../../../../../../libs/log/example/doc/tutorial_fmt_custom.cpp" target="_top">See the 378 complete code</a>. 379 </p> 380</div> 381<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 382<td align="left"></td> 383<td align="right"><div class="copyright-footer">Copyright © 2007-2019 Andrey Semashev<p> 384 Distributed under the Boost Software License, Version 1.0. (See accompanying 385 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>). 386 </p> 387</div></td> 388</tr></table> 389<hr> 390<div class="spirit-nav"> 391<a accesskey="p" href="attributes.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="advanced_filtering.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> 392</div> 393</body> 394</html> 395