• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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">()-&gt;</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">&gt;=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">trivial</span><span class="special">::</span><span class="identifier">info</span>
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: &lt;normal&gt; A normal severity message</span>
79        <span class="comment">// 2: &lt;error&gt; 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">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="string">"LineID"</span><span class="special">)</span>
84                <span class="special">&lt;&lt;</span> <span class="string">": &lt;"</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="string">"&gt; "</span> <span class="special">&lt;&lt;</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">&lt;</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">&gt;(</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">&lt;</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">text_ostream_backend</span> <span class="special">&gt;</span> <span class="identifier">text_sink</span><span class="special">;</span>
147    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">text_sink</span> <span class="special">&gt;</span> <span class="identifier">sink</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">text_sink</span> <span class="special">&gt;();</span>
148
149    <span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">locked_backend</span><span class="special">()-&gt;</span><span class="identifier">add_stream</span><span class="special">(</span>
150        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ofstream</span> <span class="special">&gt;(</span><span class="string">"sample.log"</span><span class="special">));</span>
151
152    <span class="identifier">sink</span><span class="special">-&gt;</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">hex</span> <span class="special">&lt;&lt;</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">&lt;&lt;</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">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="string">"LineID"</span><span class="special">)</span>
157            <span class="special">&lt;&lt;</span> <span class="string">": &lt;"</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="string">"&gt; "</span> <span class="special">&lt;&lt;</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">()-&gt;</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">&lt;</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">text_ostream_backend</span> <span class="special">&gt;</span> <span class="identifier">text_sink</span><span class="special">;</span>
191    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">text_sink</span> <span class="special">&gt;</span> <span class="identifier">sink</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">text_sink</span> <span class="special">&gt;();</span>
192
193    <span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">locked_backend</span><span class="special">()-&gt;</span><span class="identifier">add_stream</span><span class="special">(</span>
194        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ofstream</span> <span class="special">&gt;(</span><span class="string">"sample.log"</span><span class="special">));</span>
195
196    <span class="comment">// This makes the sink to write log records that look like this:</span>
197    <span class="comment">// 1: &lt;normal&gt; A normal severity message</span>
198    <span class="comment">// 2: &lt;error&gt; An error severity message</span>
199    <span class="identifier">sink</span><span class="special">-&gt;</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%: &lt;%2%&gt; %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">&lt;</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="string">"LineID"</span><span class="special">)</span>
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">()-&gt;</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: &lt;normal&gt; A normal severity message</span>
243        <span class="comment">// YYYY-MM-DD HH:MI:SS: &lt;error&gt; 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">&lt;&lt;</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">format_date_time</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">posix_time</span><span class="special">::</span><span class="identifier">ptime</span> <span class="special">&gt;(</span><span class="string">"TimeStamp"</span><span class="special">,</span> <span class="string">"%Y-%m-%d %H:%M:%S"</span><span class="special">)</span>
248                <span class="special">&lt;&lt;</span> <span class="string">": &lt;"</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="string">"&gt; "</span> <span class="special">&lt;&lt;</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">&amp;</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">&lt;</span> <span class="identifier">CharT</span> <span class="special">&gt;&amp;</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">&amp;</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">&amp;</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">&lt;&lt;</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">extract</span><span class="special">&lt;</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="special">&gt;(</span><span class="string">"LineID"</span><span class="special">,</span> <span class="identifier">rec</span><span class="special">)</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="string">"&lt;"</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="string">"&gt; "</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">&lt;&lt;</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">&lt;</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">text_ostream_backend</span> <span class="special">&gt;</span> <span class="identifier">text_sink</span><span class="special">;</span>
364    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">text_sink</span> <span class="special">&gt;</span> <span class="identifier">sink</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">text_sink</span> <span class="special">&gt;();</span>
365
366    <span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">locked_backend</span><span class="special">()-&gt;</span><span class="identifier">add_stream</span><span class="special">(</span>
367        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ofstream</span> <span class="special">&gt;(</span><span class="string">"sample.log"</span><span class="special">));</span>
368
369    <span class="identifier">sink</span><span class="special">-&gt;</span><span class="identifier">set_formatter</span><span class="special">(&amp;</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">()-&gt;</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