1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 4<title>Lambda expressions</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_backends.html" title="Sink backends"> 10<link rel="next" href="attributes.html" title="Attributes"> 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_backends.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="attributes.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.expressions"></a><a class="link" href="expressions.html" title="Lambda expressions">Lambda expressions</a> 21</h3></div></div></div> 22<div class="toc"><dl class="toc"> 23<dt><span class="section"><a href="expressions.html#log.detailed.expressions.attr">Generic attribute placeholder</a></span></dt> 24<dt><span class="section"><a href="expressions.html#log.detailed.expressions.attr_keywords">Defining attribute 25 keywords</a></span></dt> 26<dt><span class="section"><a href="expressions.html#log.detailed.expressions.record">Record placeholder</a></span></dt> 27<dt><span class="section"><a href="expressions.html#log.detailed.expressions.message">Message text placeholders</a></span></dt> 28<dt><span class="section"><a href="expressions.html#log.detailed.expressions.predicates">Predicate expressions</a></span></dt> 29<dt><span class="section"><a href="expressions.html#log.detailed.expressions.formatters">Formatting expressions</a></span></dt> 30</dl></div> 31<p> 32 As it was pointed out in <a class="link" href="../tutorial.html" title="Tutorial">tutorial</a>, filters 33 and formatters can be specified as Lambda expressions with placeholders for 34 attribute values. This section will describe the placeholders that can be 35 used to build more complex Lambda expressions. 36 </p> 37<p> 38 There is also a way to specify the filter in the form of a string template. 39 This can be useful for initialization from the application settings. This 40 part of the library is described <a class="link" href="utilities.html#log.detailed.utilities.setup.filter_formatter" title="Filter and formatter parsers">here</a>. 41 </p> 42<div class="section"> 43<div class="titlepage"><div><div><h4 class="title"> 44<a name="log.detailed.expressions.attr"></a><a class="link" href="expressions.html#log.detailed.expressions.attr" title="Generic attribute placeholder">Generic attribute placeholder</a> 45</h4></div></div></div> 46<div class="toc"><dl class="toc"> 47<dt><span class="section"><a href="expressions.html#log.detailed.expressions.attr.fallback_policies">Customizing 48 fallback policy</a></span></dt> 49<dt><span class="section"><a href="expressions.html#log.detailed.expressions.attr.tags">Attribute tags 50 and custom formatting operators</a></span></dt> 51</dl></div> 52<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.attr_fwd_hpp" title="Header <boost/log/expressions/attr_fwd.hpp>">boost/log/expressions/attr_fwd.hpp</a></code><span class="special">></span> 53<span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.attr_hpp" title="Header <boost/log/expressions/attr.hpp>">boost/log/expressions/attr.hpp</a></code><span class="special">></span> 54</pre> 55<p> 56 The <code class="computeroutput"><a class="link" href="../../boost/log/expressions/attr_idm46079581366752.html" title="Function template attr">attr</a></code> 57 placeholder represents an attribute value in template expressions. Given 58 the record view or a set of attribute values, the placeholder will attempt 59 to extract the specified attribute value from the argument upon invocation. 60 This can be roughly described with the following pseudo-code: 61 </p> 62<pre class="programlisting"><span class="identifier">logging</span><span class="special">::</span><span class="identifier">value_ref</span><span class="special"><</span> <span class="identifier">T</span><span class="special">,</span> <span class="identifier">TagT</span> <span class="special">></span> <span class="identifier">val</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">T</span><span class="special">,</span> <span class="identifier">TagT</span> <span class="special">>(</span><span class="identifier">name</span><span class="special">)(</span><span class="identifier">rec</span><span class="special">);</span> 63</pre> 64<p> 65 where <code class="computeroutput"><span class="identifier">val</span></code> is the <a class="link" href="utilities.html#log.detailed.utilities.value_ref" title="Value reference wrapper">reference</a> to the extracted 66 value, <code class="computeroutput"><span class="identifier">name</span></code> and <code class="computeroutput"><span class="identifier">T</span></code> are the attribute value <a class="link" href="attributes.html#log.detailed.attributes.related_components.attribute_name" title="Attribute names">name</a> 67 and type, <code class="computeroutput"><span class="identifier">TagT</span></code> is an optional 68 tag (we'll return to it in a moment) and <code class="computeroutput"><span class="identifier">rec</span></code> 69 is the log <a class="link" href="../detailed.html#log.detailed.core.record" title="Logging records">record view</a> 70 or <a class="link" href="attributes.html#log.detailed.attributes.related_components.attribute_value_set" title="Attribute value set">attribute 71 value set</a>. <code class="computeroutput"><span class="identifier">T</span></code> can 72 be a <a href="http://www.boost.org/doc/libs/release/libs/mpl/doc/index.html" target="_top">Boost.MPL</a> 73 type sequence with possible expected types of the value; the extraction 74 will succeed if the type of the value matches one of the types in the sequence. 75 </p> 76<p> 77 The <code class="computeroutput"><span class="identifier">attr</span></code> placeholder can 78 be used in <a href="http://www.boost.org/doc/libs/release/libs/phoenix/doc/html/index.html" target="_top">Boost.Phoenix</a> 79 expressions, including the <code class="computeroutput"><span class="identifier">bind</span></code> 80 expression. 81 </p> 82<p> 83</p> 84<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">my_filter</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">value_ref</span><span class="special"><</span> <span class="identifier">severity_level</span><span class="special">,</span> <span class="identifier">tag</span><span class="special">::</span><span class="identifier">severity</span> <span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">level</span><span class="special">,</span> 85 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">value_ref</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">tag</span><span class="special">::</span><span class="identifier">tag_attr</span> <span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">tag</span><span class="special">)</span> 86<span class="special">{</span> 87 <span class="keyword">return</span> <span class="identifier">level</span> <span class="special">>=</span> <span class="identifier">warning</span> <span class="special">||</span> <span class="identifier">tag</span> <span class="special">==</span> <span class="string">"IMPORTANT_MESSAGE"</span><span class="special">;</span> 88<span class="special">}</span> 89 90<span class="keyword">void</span> <span class="identifier">init</span><span class="special">()</span> 91<span class="special">{</span> 92 <span class="comment">// ...</span> 93 94 <span class="keyword">namespace</span> <span class="identifier">phoenix</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">phoenix</span><span class="special">;</span> 95 <span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_filter</span><span class="special">(</span><span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(&</span><span class="identifier">my_filter</span><span class="special">,</span> <span class="identifier">severity</span><span class="special">.</span><span class="identifier">or_none</span><span class="special">(),</span> <span class="identifier">tag_attr</span><span class="special">.</span><span class="identifier">or_none</span><span class="special">()));</span> 96 97 <span class="comment">// ...</span> 98<span class="special">}</span> 99</pre> 100<p> 101 </p> 102<p> 103 The placeholder can be used both in filters and formatters: 104 </p> 105<pre class="programlisting"><span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_filter</span> 106<span class="special">(</span> 107 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special"><</span> <span class="keyword">int</span> <span class="special">>(</span><span class="string">"Severity"</span><span class="special">)</span> <span class="special">>=</span> <span class="number">5</span> <span class="special">&&</span> 108 <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">"Channel"</span><span class="special">)</span> <span class="special">==</span> <span class="string">"net"</span> 109<span class="special">);</span> 110 111<span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span> 112<span class="special">(</span> 113 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> 114 <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">int</span> <span class="special">>(</span><span class="string">"Severity"</span><span class="special">)</span> 115 <span class="special"><<</span> <span class="string">" ["</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">"Channel"</span><span class="special">)</span> <span class="special"><<</span> <span class="string">"] "</span> 116 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">smessage</span> 117<span class="special">);</span> 118</pre> 119<p> 120 The call to <code class="computeroutput"><span class="identifier">set_filter</span></code> 121 registers a composite filter that consists of two elementary subfilters: 122 the first one checks the severity level, and the second checks the channel 123 name. The call to <code class="computeroutput"><span class="identifier">set_formatter</span></code> 124 installs a formatter that composes a string containing the severity level 125 and the channel name along with the message text. 126 </p> 127<div class="section"> 128<div class="titlepage"><div><div><h5 class="title"> 129<a name="log.detailed.expressions.attr.fallback_policies"></a><a class="link" href="expressions.html#log.detailed.expressions.attr.fallback_policies" title="Customizing fallback policy">Customizing 130 fallback policy</a> 131</h5></div></div></div> 132<p> 133 By default, when the requested attribute value is not found in the record, 134 <code class="computeroutput"><span class="identifier">attr</span></code> will return an empty 135 reference. In case of filters, this will result in <code class="computeroutput"><span class="keyword">false</span></code> 136 in any ordering expressions, and in case of formatters the output from 137 the placeholder will be empty. This behavior can be changed: 138 </p> 139<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"> 140 To throw an exception (<code class="computeroutput"><a class="link" href="../../boost/log/missing_value.html" title="Class missing_value">missing_value</a></code> 141 or <code class="computeroutput"><a class="link" href="../../boost/log/invalid_type.html" title="Class invalid_type">invalid_type</a></code>, 142 depending on the reason of the failure). Add the <code class="computeroutput"><span class="identifier">or_throw</span></code> 143 modifier: 144 </li></ul></div> 145<pre class="programlisting"><span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_filter</span> 146<span class="special">(</span> 147 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special"><</span> <span class="keyword">int</span> <span class="special">>(</span><span class="string">"Severity"</span><span class="special">).</span><span class="identifier">or_throw</span><span class="special">()</span> <span class="special">>=</span> <span class="number">5</span> <span class="special">&&</span> 148 <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">"Channel"</span><span class="special">).</span><span class="identifier">or_throw</span><span class="special">()</span> <span class="special">==</span> <span class="string">"net"</span> 149<span class="special">);</span> 150</pre> 151<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"> 152 To use a default value instead. Add the <code class="computeroutput"><span class="identifier">or_default</span></code> 153 modifier with the desired default value: 154 </li></ul></div> 155<pre class="programlisting"><span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_filter</span> 156<span class="special">(</span> 157 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special"><</span> <span class="keyword">int</span> <span class="special">>(</span><span class="string">"Severity"</span><span class="special">).</span><span class="identifier">or_default</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">>=</span> <span class="number">5</span> <span class="special">&&</span> 158 <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">"Channel"</span><span class="special">).</span><span class="identifier">or_default</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">"general"</span><span class="special">))</span> <span class="special">==</span> <span class="string">"net"</span> 159<span class="special">);</span> 160</pre> 161<div class="tip"><table border="0" summary="Tip"> 162<tr> 163<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td> 164<th align="left">Tip</th> 165</tr> 166<tr><td align="left" valign="top"><p> 167 You can also use the <a class="link" href="expressions.html#log.detailed.expressions.predicates.has_attr" title="Attribute presence filter"><code class="computeroutput"><span class="identifier">has_attr</span></code></a> predicate to implement 168 filters and formatters conditional on the attribute value presence. 169 </p></td></tr> 170</table></div> 171<p> 172 The default behavior is also accessible through the <code class="computeroutput"><span class="identifier">or_none</span></code> 173 modifier. The modified placeholders can be used in filters and formatters 174 just the same way as the unmodified ones. 175 </p> 176<p> 177 In <code class="computeroutput"><span class="identifier">bind</span></code> expressions, 178 the bound function object will still receive the <a class="link" href="utilities.html#log.detailed.utilities.value_ref" title="Value reference wrapper"><code class="computeroutput"><span class="identifier">value_ref</span></code></a>-wrapped values in 179 place of the modified <code class="computeroutput"><span class="identifier">attr</span></code> 180 placeholder. Even though both <code class="computeroutput"><span class="identifier">or_throw</span></code> 181 and <code class="computeroutput"><span class="identifier">or_default</span></code> modifiers 182 guarantee that the bound function will receive a filled reference, <a class="link" href="utilities.html#log.detailed.utilities.value_ref" title="Value reference wrapper"><code class="computeroutput"><span class="identifier">value_ref</span></code></a> 183 is still needed if the value type is specified as a type sequence. Also, 184 the reference wrapper may contain a tag type which may be useful for 185 formatting customization. 186 </p> 187</div> 188<div class="section"> 189<div class="titlepage"><div><div><h5 class="title"> 190<a name="log.detailed.expressions.attr.tags"></a><a class="link" href="expressions.html#log.detailed.expressions.attr.tags" title="Attribute tags and custom formatting operators">Attribute tags 191 and custom formatting operators</a> 192</h5></div></div></div> 193<p> 194 The <code class="computeroutput"><span class="identifier">TagT</span></code> type in the 195 <a class="link" href="expressions.html#log.detailed.expressions.attr" title="Generic attribute placeholder">abstract description</a> 196 of <code class="computeroutput"><span class="identifier">attr</span></code> above is optional 197 and by default is <code class="computeroutput"><span class="keyword">void</span></code>. 198 This is an attribute tag which can be used to customize the output formatters 199 produce for different attributes. This tag is forwarded to the <a class="link" href="utilities.html#log.detailed.utilities.manipulators.to_log" title="Customized logging manipulator"><code class="computeroutput"><span class="identifier">to_log</span></code></a> 200 manipulator when the extracted attribute value is put to a stream (this 201 behavior is warranted by <a class="link" href="utilities.html#log.detailed.utilities.value_ref" title="Value reference wrapper"><code class="computeroutput"><span class="identifier">value_ref</span></code></a> implementation). Here's 202 a quick example: 203 </p> 204<p> 205</p> 206<pre class="programlisting"><span class="comment">// We define our own severity levels</span> 207<span class="keyword">enum</span> <span class="identifier">severity_level</span> 208<span class="special">{</span> 209 <span class="identifier">normal</span><span class="special">,</span> 210 <span class="identifier">notification</span><span class="special">,</span> 211 <span class="identifier">warning</span><span class="special">,</span> 212 <span class="identifier">error</span><span class="special">,</span> 213 <span class="identifier">critical</span> 214<span class="special">};</span> 215 216<span class="comment">// The operator is used for regular stream formatting</span> 217<span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&</span> <span class="keyword">operator</span><span class="special"><<</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">strm</span><span class="special">,</span> <span class="identifier">severity_level</span> <span class="identifier">level</span><span class="special">)</span> 218<span class="special">{</span> 219 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">strings</span><span class="special">[]</span> <span class="special">=</span> 220 <span class="special">{</span> 221 <span class="string">"normal"</span><span class="special">,</span> 222 <span class="string">"notification"</span><span class="special">,</span> 223 <span class="string">"warning"</span><span class="special">,</span> 224 <span class="string">"error"</span><span class="special">,</span> 225 <span class="string">"critical"</span> 226 <span class="special">};</span> 227 228 <span class="keyword">if</span> <span class="special">(</span><span class="keyword">static_cast</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="special">>(</span><span class="identifier">level</span><span class="special">)</span> <span class="special"><</span> <span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">strings</span><span class="special">)</span> <span class="special">/</span> <span class="keyword">sizeof</span><span class="special">(*</span><span class="identifier">strings</span><span class="special">))</span> 229 <span class="identifier">strm</span> <span class="special"><<</span> <span class="identifier">strings</span><span class="special">[</span><span class="identifier">level</span><span class="special">];</span> 230 <span class="keyword">else</span> 231 <span class="identifier">strm</span> <span class="special"><<</span> <span class="keyword">static_cast</span><span class="special"><</span> <span class="keyword">int</span> <span class="special">>(</span><span class="identifier">level</span><span class="special">);</span> 232 233 <span class="keyword">return</span> <span class="identifier">strm</span><span class="special">;</span> 234<span class="special">}</span> 235 236<span class="comment">// Attribute value tag type</span> 237<span class="keyword">struct</span> <span class="identifier">severity_tag</span><span class="special">;</span> 238 239<span class="comment">// The operator is used when putting the severity level to log</span> 240<span class="identifier">logging</span><span class="special">::</span><span class="identifier">formatting_ostream</span><span class="special">&</span> <span class="keyword">operator</span><span class="special"><<</span> 241<span class="special">(</span> 242 <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> 243 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">to_log_manip</span><span class="special"><</span> <span class="identifier">severity_level</span><span class="special">,</span> <span class="identifier">severity_tag</span> <span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">manip</span> 244<span class="special">)</span> 245<span class="special">{</span> 246 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">strings</span><span class="special">[]</span> <span class="special">=</span> 247 <span class="special">{</span> 248 <span class="string">"NORM"</span><span class="special">,</span> 249 <span class="string">"NTFY"</span><span class="special">,</span> 250 <span class="string">"WARN"</span><span class="special">,</span> 251 <span class="string">"ERRR"</span><span class="special">,</span> 252 <span class="string">"CRIT"</span> 253 <span class="special">};</span> 254 255 <span class="identifier">severity_level</span> <span class="identifier">level</span> <span class="special">=</span> <span class="identifier">manip</span><span class="special">.</span><span class="identifier">get</span><span class="special">();</span> 256 <span class="keyword">if</span> <span class="special">(</span><span class="keyword">static_cast</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="special">>(</span><span class="identifier">level</span><span class="special">)</span> <span class="special"><</span> <span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">strings</span><span class="special">)</span> <span class="special">/</span> <span class="keyword">sizeof</span><span class="special">(*</span><span class="identifier">strings</span><span class="special">))</span> 257 <span class="identifier">strm</span> <span class="special"><<</span> <span class="identifier">strings</span><span class="special">[</span><span class="identifier">level</span><span class="special">];</span> 258 <span class="keyword">else</span> 259 <span class="identifier">strm</span> <span class="special"><<</span> <span class="keyword">static_cast</span><span class="special"><</span> <span class="keyword">int</span> <span class="special">>(</span><span class="identifier">level</span><span class="special">);</span> 260 261 <span class="keyword">return</span> <span class="identifier">strm</span><span class="special">;</span> 262<span class="special">}</span> 263 264<span class="keyword">void</span> <span class="identifier">init</span><span class="special">()</span> 265<span class="special">{</span> 266 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">add_console_log</span> 267 <span class="special">(</span> 268 <span class="identifier">std</span><span class="special">::</span><span class="identifier">clog</span><span class="special">,</span> 269 <span class="comment">// This makes the sink to write log records that look like this:</span> 270 <span class="comment">// 1: <NORM> A normal severity message</span> 271 <span class="comment">// 2: <ERRR> An error severity message</span> 272 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">format</span> <span class="special">=</span> 273 <span class="special">(</span> 274 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> 275 <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> 276 <span class="special"><<</span> <span class="string">": <"</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">severity_level</span><span class="special">,</span> <span class="identifier">severity_tag</span> <span class="special">>(</span><span class="string">"Severity"</span><span class="special">)</span> 277 <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> 278 <span class="special">)</span> 279 <span class="special">);</span> 280<span class="special">}</span> 281</pre> 282<p> 283 </p> 284<p> 285 <a href="../../../../../../libs/log/example/doc/expressions_attr_fmt_tag.cpp" target="_top">See 286 the complete code</a>. 287 </p> 288<p> 289 Here we specify a different formatting operator for the severity level 290 wrapped in the <a class="link" href="utilities.html#log.detailed.utilities.manipulators.to_log" title="Customized logging manipulator"><code class="computeroutput"><span class="identifier">to_log_manip</span></code></a> manipulator marked 291 with the tag <code class="computeroutput"><span class="identifier">severity_tag</span></code>. 292 This operator will be called when log records are formatted while the 293 regular <code class="computeroutput"><span class="keyword">operator</span><span class="special"><<</span></code> 294 will be used in other contexts. 295 </p> 296</div> 297</div> 298<div class="section"> 299<div class="titlepage"><div><div><h4 class="title"> 300<a name="log.detailed.expressions.attr_keywords"></a><a class="link" href="expressions.html#log.detailed.expressions.attr_keywords" title="Defining attribute keywords">Defining attribute 301 keywords</a> 302</h4></div></div></div> 303<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.keyword_fwd_hpp" title="Header <boost/log/expressions/keyword_fwd.hpp>">boost/log/expressions/keyword_fwd.hpp</a></code><span class="special">></span> 304<span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.keyword_hpp" title="Header <boost/log/expressions/keyword.hpp>">boost/log/expressions/keyword.hpp</a></code><span class="special">></span> 305</pre> 306<p> 307 Attribute keywords can be used as replacements for the <a class="link" href="expressions.html#log.detailed.expressions.attr" title="Generic attribute placeholder"><code class="computeroutput"><span class="identifier">attr</span></code></a> placeholders in filters and 308 formatters while providing a more concise and less error prone syntax. 309 An attribute keyword can be declared with the <code class="computeroutput"><a class="link" href="../../BOOST_LO_idm46079578189088.html" title="Macro BOOST_LOG_ATTRIBUTE_KEYWORD">BOOST_LOG_ATTRIBUTE_KEYWORD</a></code> 310 macro: 311 </p> 312<pre class="programlisting"><span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">keyword</span><span class="special">,</span> <span class="string">"Keyword"</span><span class="special">,</span> <span class="identifier">type</span><span class="special">)</span> 313</pre> 314<p> 315 Here the macro declares a keyword <code class="computeroutput"><span class="identifier">keyword</span></code> 316 for an attribute named "Keyword" with the value type of <code class="computeroutput"><span class="identifier">type</span></code>. Additionally, the macro defines 317 an attribute tag type <code class="computeroutput"><span class="identifier">keyword</span></code> 318 within the <code class="computeroutput"><span class="identifier">tag</span></code> namespace. 319 We can rewrite the previous example in the following way: 320 </p> 321<p> 322</p> 323<pre class="programlisting"><span class="comment">// We define our own severity levels</span> 324<span class="keyword">enum</span> <span class="identifier">severity_level</span> 325<span class="special">{</span> 326 <span class="identifier">normal</span><span class="special">,</span> 327 <span class="identifier">notification</span><span class="special">,</span> 328 <span class="identifier">warning</span><span class="special">,</span> 329 <span class="identifier">error</span><span class="special">,</span> 330 <span class="identifier">critical</span> 331<span class="special">};</span> 332 333<span class="comment">// Define the attribute keywords</span> 334<span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">line_id</span><span class="special">,</span> <span class="string">"LineID"</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span><span class="special">)</span> 335<span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">severity</span><span class="special">,</span> <span class="string">"Severity"</span><span class="special">,</span> <span class="identifier">severity_level</span><span class="special">)</span> 336 337<span class="comment">// The operator is used for regular stream formatting</span> 338<span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&</span> <span class="keyword">operator</span><span class="special"><<</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">strm</span><span class="special">,</span> <span class="identifier">severity_level</span> <span class="identifier">level</span><span class="special">)</span> 339<span class="special">{</span> 340 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">strings</span><span class="special">[]</span> <span class="special">=</span> 341 <span class="special">{</span> 342 <span class="string">"normal"</span><span class="special">,</span> 343 <span class="string">"notification"</span><span class="special">,</span> 344 <span class="string">"warning"</span><span class="special">,</span> 345 <span class="string">"error"</span><span class="special">,</span> 346 <span class="string">"critical"</span> 347 <span class="special">};</span> 348 349 <span class="keyword">if</span> <span class="special">(</span><span class="keyword">static_cast</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="special">>(</span><span class="identifier">level</span><span class="special">)</span> <span class="special"><</span> <span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">strings</span><span class="special">)</span> <span class="special">/</span> <span class="keyword">sizeof</span><span class="special">(*</span><span class="identifier">strings</span><span class="special">))</span> 350 <span class="identifier">strm</span> <span class="special"><<</span> <span class="identifier">strings</span><span class="special">[</span><span class="identifier">level</span><span class="special">];</span> 351 <span class="keyword">else</span> 352 <span class="identifier">strm</span> <span class="special"><<</span> <span class="keyword">static_cast</span><span class="special"><</span> <span class="keyword">int</span> <span class="special">>(</span><span class="identifier">level</span><span class="special">);</span> 353 354 <span class="keyword">return</span> <span class="identifier">strm</span><span class="special">;</span> 355<span class="special">}</span> 356 357<span class="comment">// The operator is used when putting the severity level to log</span> 358<span class="identifier">logging</span><span class="special">::</span><span class="identifier">formatting_ostream</span><span class="special">&</span> <span class="keyword">operator</span><span class="special"><<</span> 359<span class="special">(</span> 360 <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> 361 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">to_log_manip</span><span class="special"><</span> <span class="identifier">severity_level</span><span class="special">,</span> <span class="identifier">tag</span><span class="special">::</span><span class="identifier">severity</span> <span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">manip</span> 362<span class="special">)</span> 363<span class="special">{</span> 364 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">strings</span><span class="special">[]</span> <span class="special">=</span> 365 <span class="special">{</span> 366 <span class="string">"NORM"</span><span class="special">,</span> 367 <span class="string">"NTFY"</span><span class="special">,</span> 368 <span class="string">"WARN"</span><span class="special">,</span> 369 <span class="string">"ERRR"</span><span class="special">,</span> 370 <span class="string">"CRIT"</span> 371 <span class="special">};</span> 372 373 <span class="identifier">severity_level</span> <span class="identifier">level</span> <span class="special">=</span> <span class="identifier">manip</span><span class="special">.</span><span class="identifier">get</span><span class="special">();</span> 374 <span class="keyword">if</span> <span class="special">(</span><span class="keyword">static_cast</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="special">>(</span><span class="identifier">level</span><span class="special">)</span> <span class="special"><</span> <span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">strings</span><span class="special">)</span> <span class="special">/</span> <span class="keyword">sizeof</span><span class="special">(*</span><span class="identifier">strings</span><span class="special">))</span> 375 <span class="identifier">strm</span> <span class="special"><<</span> <span class="identifier">strings</span><span class="special">[</span><span class="identifier">level</span><span class="special">];</span> 376 <span class="keyword">else</span> 377 <span class="identifier">strm</span> <span class="special"><<</span> <span class="keyword">static_cast</span><span class="special"><</span> <span class="keyword">int</span> <span class="special">>(</span><span class="identifier">level</span><span class="special">);</span> 378 379 <span class="keyword">return</span> <span class="identifier">strm</span><span class="special">;</span> 380<span class="special">}</span> 381 382<span class="keyword">void</span> <span class="identifier">init</span><span class="special">()</span> 383<span class="special">{</span> 384 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">add_console_log</span> 385 <span class="special">(</span> 386 <span class="identifier">std</span><span class="special">::</span><span class="identifier">clog</span><span class="special">,</span> 387 <span class="comment">// This makes the sink to write log records that look like this:</span> 388 <span class="comment">// 1: <NORM> A normal severity message</span> 389 <span class="comment">// 2: <ERRR> An error severity message</span> 390 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">format</span> <span class="special">=</span> 391 <span class="special">(</span> 392 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> 393 <span class="special"><<</span> <span class="identifier">line_id</span> 394 <span class="special"><<</span> <span class="string">": <"</span> <span class="special"><<</span> <span class="identifier">severity</span> 395 <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> 396 <span class="special">)</span> 397 <span class="special">);</span> 398<span class="special">}</span> 399</pre> 400<p> 401 </p> 402<p> 403 Attribute keywords behave the same way as the <a class="link" href="expressions.html#log.detailed.expressions.attr" title="Generic attribute placeholder"><code class="computeroutput"><span class="identifier">attr</span></code></a> placeholders and can be used 404 both in filters and formatters. The <code class="computeroutput"><span class="identifier">or_throw</span></code> 405 and <code class="computeroutput"><span class="identifier">or_default</span></code> modifiers 406 are also supported. 407 </p> 408<p> 409 Keywords can also be used in attribute value lookup expressions in log 410 records and attribute value sets: 411 </p> 412<p> 413</p> 414<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">print_severity</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> 415<span class="special">{</span> 416 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">value_ref</span><span class="special"><</span> <span class="identifier">severity_level</span><span class="special">,</span> <span class="identifier">tag</span><span class="special">::</span><span class="identifier">severity</span> <span class="special">></span> <span class="identifier">level</span> <span class="special">=</span> <span class="identifier">rec</span><span class="special">[</span><span class="identifier">severity</span><span class="special">];</span> 417 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">level</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 418<span class="special">}</span> 419</pre> 420<p> 421 </p> 422</div> 423<div class="section"> 424<div class="titlepage"><div><div><h4 class="title"> 425<a name="log.detailed.expressions.record"></a><a class="link" href="expressions.html#log.detailed.expressions.record" title="Record placeholder">Record placeholder</a> 426</h4></div></div></div> 427<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.record_hpp" title="Header <boost/log/expressions/record.hpp>">boost/log/expressions/record.hpp</a></code><span class="special">></span> 428</pre> 429<p> 430 The <code class="computeroutput"><span class="identifier">record</span></code> placeholder 431 can be used in <code class="computeroutput"><span class="identifier">bind</span></code> expressions 432 to pass the whole log <a class="link" href="../detailed.html#log.detailed.core.record" title="Logging records">record view</a> 433 to the bound function object. 434 </p> 435<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">formatting_ostream</span><span class="special">&</span> <span class="identifier">strm</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> 436<span class="special">{</span> 437 <span class="comment">// ...</span> 438<span class="special">}</span> 439 440<span class="keyword">namespace</span> <span class="identifier">phoenix</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">phoenix</span><span class="special">;</span> 441<span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span><span class="special">(</span><span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(&</span><span class="identifier">my_formatter</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">record</span><span class="special">));</span> 442</pre> 443<div class="note"><table border="0" summary="Note"> 444<tr> 445<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td> 446<th align="left">Note</th> 447</tr> 448<tr><td align="left" valign="top"><p> 449 In case of filters, the placeholder will correspond to the <a class="link" href="attributes.html#log.detailed.attributes.related_components.attribute_value_set" title="Attribute value set">set 450 of attribute values</a> rather than the log record itself. This is 451 because the record is not constructed yet at the point of filtering, 452 and filters only operate on the set of attribute values. 453 </p></td></tr> 454</table></div> 455</div> 456<div class="section"> 457<div class="titlepage"><div><div><h4 class="title"> 458<a name="log.detailed.expressions.message"></a><a class="link" href="expressions.html#log.detailed.expressions.message" title="Message text placeholders">Message text placeholders</a> 459</h4></div></div></div> 460<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.message_hpp" title="Header <boost/log/expressions/message.hpp>">boost/log/expressions/message.hpp</a></code><span class="special">></span> 461</pre> 462<p> 463 Log records typically contain a special attribute "Message" with 464 the value of one of the string types (more specifically, an <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span></code> specialization). This attribute 465 contains the text of the log message that is constructed at the point of 466 the record creation. This attribute is only constructed after filtering, 467 so filters cannot use it. There are several keywords to access this attribute 468 value: 469 </p> 470<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 471<li class="listitem"> 472 <code class="computeroutput"><span class="identifier">smessage</span></code> - the attribute 473 value is expected to be an <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> 474 </li> 475<li class="listitem"> 476 <code class="computeroutput"><span class="identifier">wmessage</span></code> - the attribute 477 value is expected to be an <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">wstring</span></code> 478 </li> 479<li class="listitem"> 480 <code class="computeroutput"><span class="identifier">message</span></code> - the attribute 481 value is expected to be an <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> 482 or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">wstring</span></code> 483 </li> 484</ul></div> 485<p> 486 The <code class="computeroutput"><span class="identifier">message</span></code> keyword has 487 to dispatch between different string types, so it is slightly less efficient 488 than the other two keywords. If the application is able to guarantee the 489 fixed character type of log messages, it is advised to use the corresponding 490 keyword for better performance. 491 </p> 492<pre class="programlisting"><span class="comment">// Sets up a formatter that will ignore all attributes and only print log record text</span> 493<span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</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">message</span><span class="special">);</span> 494</pre> 495</div> 496<div class="section"> 497<div class="titlepage"><div><div><h4 class="title"> 498<a name="log.detailed.expressions.predicates"></a><a class="link" href="expressions.html#log.detailed.expressions.predicates" title="Predicate expressions">Predicate expressions</a> 499</h4></div></div></div> 500<div class="toc"><dl class="toc"> 501<dt><span class="section"><a href="expressions.html#log.detailed.expressions.predicates.has_attr">Attribute 502 presence filter</a></span></dt> 503<dt><span class="section"><a href="expressions.html#log.detailed.expressions.predicates.is_in_range">Range 504 checking filter</a></span></dt> 505<dt><span class="section"><a href="expressions.html#log.detailed.expressions.predicates.simple_string_matching">Simple 506 string matching filters</a></span></dt> 507<dt><span class="section"><a href="expressions.html#log.detailed.expressions.predicates.advanced_string_matching">Advanced 508 string matching filter</a></span></dt> 509<dt><span class="section"><a href="expressions.html#log.detailed.expressions.predicates.channel_severity_filter">Severity 510 threshold per channel filter</a></span></dt> 511<dt><span class="section"><a href="expressions.html#log.detailed.expressions.predicates.is_debugger_present">Debugger 512 presence filter</a></span></dt> 513</dl></div> 514<p> 515 This section describes several expressions that can be used as predicates 516 in filtering expressions. 517 </p> 518<div class="section"> 519<div class="titlepage"><div><div><h5 class="title"> 520<a name="log.detailed.expressions.predicates.has_attr"></a><a class="link" href="expressions.html#log.detailed.expressions.predicates.has_attr" title="Attribute presence filter">Attribute 521 presence filter</a> 522</h5></div></div></div> 523<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.predicates.has_attr_hpp" title="Header <boost/log/expressions/predicates/has_attr.hpp>">boost/log/expressions/predicates/has_attr.hpp</a></code><span class="special">></span> 524</pre> 525<p> 526 The filter <code class="computeroutput"><a class="link" href="../../boost/log/expressions/has_attr_idm46079577821792.html" title="Function template has_attr">has_attr</a></code> checks if an 527 attribute value with the specified name and, optionally, type is attached 528 to a log record. If no type specified to the filter, the filter returns 529 <code class="computeroutput"><span class="keyword">true</span></code> if any value with the 530 specified name is found. If an MPL-compatible type sequence in specified 531 as a value type, the filter returns <code class="computeroutput"><span class="keyword">true</span></code> 532 if a value with the specified name and one of the specified types is 533 found. 534 </p> 535<p> 536 This filter is usually used in conjunction with <a class="link" href="expressions.html#log.detailed.expressions.formatters.conditional" title="Conditional formatters">conditional 537 formatters</a>, but it also can be used as a quick filter based on 538 the log record structure. For example, one can use this filter to extract 539 statistic records and route them to a specific sink. 540 </p> 541<p> 542</p> 543<pre class="programlisting"><span class="comment">// Declare attribute keywords</span> 544<span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">stat_stream</span><span class="special">,</span> <span class="string">"StatisticStream"</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">)</span> 545<span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">change</span><span class="special">,</span> <span class="string">"Change"</span><span class="special">,</span> <span class="keyword">int</span><span class="special">)</span> 546 547<span class="comment">// A simple sink backend to accumulate statistic information</span> 548<span class="keyword">class</span> <span class="identifier">my_stat_accumulator</span> <span class="special">:</span> 549 <span class="keyword">public</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">basic_sink_backend</span><span class="special"><</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">synchronized_feeding</span> <span class="special">></span> 550<span class="special">{</span> 551 <span class="comment">// A map of accumulated statistic values,</span> 552 <span class="comment">// ordered by the statistic information stream name</span> 553 <span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">map</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="keyword">int</span> <span class="special">></span> <span class="identifier">stat_info_map</span><span class="special">;</span> 554 <span class="identifier">stat_info_map</span> <span class="identifier">m_stat_info</span><span class="special">;</span> 555 556<span class="keyword">public</span><span class="special">:</span> 557 <span class="comment">// Destructor</span> 558 <span class="special">~</span><span class="identifier">my_stat_accumulator</span><span class="special">()</span> 559 <span class="special">{</span> 560 <span class="comment">// Display the accumulated data</span> 561 <span class="identifier">stat_info_map</span><span class="special">::</span><span class="identifier">const_iterator</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">m_stat_info</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">end</span> <span class="special">=</span> <span class="identifier">m_stat_info</span><span class="special">.</span><span class="identifier">end</span><span class="special">();</span> 562 <span class="keyword">for</span> <span class="special">(;</span> <span class="identifier">it</span> <span class="special">!=</span> <span class="identifier">end</span><span class="special">;</span> <span class="special">++</span><span class="identifier">it</span><span class="special">)</span> 563 <span class="special">{</span> 564 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Statistic stream: "</span> <span class="special"><<</span> <span class="identifier">it</span><span class="special">-></span><span class="identifier">first</span> 565 <span class="special"><<</span> <span class="string">", accumulated value: "</span> <span class="special"><<</span> <span class="identifier">it</span><span class="special">-></span><span class="identifier">second</span> <span class="special"><<</span> <span class="string">"\n"</span><span class="special">;</span> 566 <span class="special">}</span> 567 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">.</span><span class="identifier">flush</span><span class="special">();</span> 568 <span class="special">}</span> 569 570 <span class="comment">// The method is called for every log record being put into the sink backend</span> 571 <span class="keyword">void</span> <span class="identifier">consume</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> 572 <span class="special">{</span> 573 <span class="comment">// First, acquire statistic information stream name</span> 574 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">value_ref</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">tag</span><span class="special">::</span><span class="identifier">stat_stream</span> <span class="special">></span> <span class="identifier">name</span> <span class="special">=</span> <span class="identifier">rec</span><span class="special">[</span><span class="identifier">stat_stream</span><span class="special">];</span> 575 <span class="keyword">if</span> <span class="special">(</span><span class="identifier">name</span><span class="special">)</span> 576 <span class="special">{</span> 577 <span class="comment">// Next, get the statistic value change</span> 578 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">value_ref</span><span class="special"><</span> <span class="keyword">int</span><span class="special">,</span> <span class="identifier">tag</span><span class="special">::</span><span class="identifier">change</span> <span class="special">></span> <span class="identifier">change_amount</span> <span class="special">=</span> <span class="identifier">rec</span><span class="special">[</span><span class="identifier">change</span><span class="special">];</span> 579 <span class="keyword">if</span> <span class="special">(</span><span class="identifier">change_amount</span><span class="special">)</span> 580 <span class="special">{</span> 581 <span class="comment">// Accumulate the statistic data</span> 582 <span class="identifier">m_stat_info</span><span class="special">[</span><span class="identifier">name</span><span class="special">.</span><span class="identifier">get</span><span class="special">()]</span> <span class="special">+=</span> <span class="identifier">change_amount</span><span class="special">.</span><span class="identifier">get</span><span class="special">();</span> 583 <span class="special">}</span> 584 <span class="special">}</span> 585 <span class="special">}</span> 586<span class="special">};</span> 587 588<span class="comment">// The function registers two sinks - one for statistic information,</span> 589<span class="comment">// and another one for other records</span> 590<span class="keyword">void</span> <span class="identifier">init</span><span class="special">()</span> 591<span class="special">{</span> 592 <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> 593 594 <span class="comment">// Create a backend and attach a stream to it</span> 595 <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> 596 <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> 597 <span class="identifier">backend</span><span class="special">-></span><span class="identifier">add_stream</span><span class="special">(</span> 598 <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">"test.log"</span><span class="special">)));</span> 599 600 <span class="comment">// Create a frontend and setup filtering</span> 601 <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">log_sink_type</span><span class="special">;</span> 602 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span> <span class="identifier">log_sink_type</span> <span class="special">></span> <span class="identifier">log_sink</span><span class="special">(</span><span class="keyword">new</span> <span class="identifier">log_sink_type</span><span class="special">(</span><span class="identifier">backend</span><span class="special">));</span> 603 <span class="comment">// All records that don't have a "StatisticStream" attribute attached</span> 604 <span class="comment">// will go to the "test.log" file</span> 605 <span class="identifier">log_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="identifier">stat_stream</span><span class="special">));</span> 606 607 <span class="identifier">core</span><span class="special">-></span><span class="identifier">add_sink</span><span class="special">(</span><span class="identifier">log_sink</span><span class="special">);</span> 608 609 <span class="comment">// Create another sink that will receive all statistic data</span> 610 <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">my_stat_accumulator</span> <span class="special">></span> <span class="identifier">stat_sink_type</span><span class="special">;</span> 611 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span> <span class="identifier">stat_sink_type</span> <span class="special">></span> <span class="identifier">stat_sink</span><span class="special">(</span><span class="keyword">new</span> <span class="identifier">stat_sink_type</span><span class="special">());</span> 612 <span class="comment">// All records with a "StatisticStream" string attribute attached</span> 613 <span class="comment">// will go to the my_stat_accumulator sink</span> 614 <span class="identifier">stat_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="identifier">stat_stream</span><span class="special">));</span> 615 616 <span class="identifier">core</span><span class="special">-></span><span class="identifier">add_sink</span><span class="special">(</span><span class="identifier">stat_sink</span><span class="special">);</span> 617<span class="special">}</span> 618 619<span class="comment">// This simple macro will simplify putting statistic data into a logger</span> 620<span class="preprocessor">#define</span> <span class="identifier">PUT_STAT</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="identifier">stat_stream_name</span><span class="special">,</span> <span class="identifier">change</span><span class="special">)\</span> 621 <span class="keyword">if</span> <span class="special">(</span><span class="keyword">true</span><span class="special">)</span> <span class="special">{\</span> 622 <span class="identifier">BOOST_LOG_SCOPED_LOGGER_TAG</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="string">"StatisticStream"</span><span class="special">,</span> <span class="identifier">stat_stream_name</span><span class="special">);\</span> 623 <span class="identifier">BOOST_LOG</span><span class="special">(</span><span class="identifier">lg</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">add_value</span><span class="special">(</span><span class="string">"Change"</span><span class="special">,</span> <span class="special">(</span><span class="keyword">int</span><span class="special">)(</span><span class="identifier">change</span><span class="special">));\</span> 624 <span class="special">}</span> <span class="keyword">else</span> <span class="special">((</span><span class="keyword">void</span><span class="special">)</span><span class="number">0</span><span class="special">)</span> 625 626<span class="keyword">void</span> <span class="identifier">logging_function</span><span class="special">()</span> 627<span class="special">{</span> 628 <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger</span> <span class="identifier">lg</span><span class="special">;</span> 629 630 <span class="comment">// Put a regular log record, it will go to the "test.log" file</span> 631 <span class="identifier">BOOST_LOG</span><span class="special">(</span><span class="identifier">lg</span><span class="special">)</span> <span class="special"><<</span> <span class="string">"A regular log record"</span><span class="special">;</span> 632 633 <span class="comment">// Put some statistic data</span> 634 <span class="identifier">PUT_STAT</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="string">"StreamOne"</span><span class="special">,</span> <span class="number">10</span><span class="special">);</span> 635 <span class="identifier">PUT_STAT</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="string">"StreamTwo"</span><span class="special">,</span> <span class="number">20</span><span class="special">);</span> 636 <span class="identifier">PUT_STAT</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="string">"StreamOne"</span><span class="special">,</span> <span class="special">-</span><span class="number">5</span><span class="special">);</span> 637<span class="special">}</span> 638</pre> 639<p> 640 </p> 641<p> 642 <a href="../../../../../../libs/log/example/doc/expressions_has_attr_stat_accum.cpp" target="_top">See 643 the complete code</a>. 644 </p> 645<p> 646 In this example, log records emitted with the <code class="computeroutput"><span class="identifier">PUT_STAT</span></code> 647 macro will be directed to the <code class="computeroutput"><span class="identifier">my_stat_accumulator</span></code> 648 sink backend, which will accumulate the changes passed in the "Change" 649 attribute values. All other records (even those made through the same 650 logger) will be passed to the filter sink. This is achieved with the 651 mutually exclusive filters set for the two sinks. 652 </p> 653<p> 654 Please note that in the example above we extended the library in two 655 ways: we defined a new sink backend <code class="computeroutput"><span class="identifier">my_stat_accumulator</span></code> 656 and a new macro <code class="computeroutput"><span class="identifier">PUT_STAT</span></code>. 657 Also note that <code class="computeroutput"><span class="identifier">has_attr</span></code> 658 can accept attribute keywords to identify the attribute to check. 659 </p> 660</div> 661<div class="section"> 662<div class="titlepage"><div><div><h5 class="title"> 663<a name="log.detailed.expressions.predicates.is_in_range"></a><a class="link" href="expressions.html#log.detailed.expressions.predicates.is_in_range" title="Range checking filter">Range 664 checking filter</a> 665</h5></div></div></div> 666<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.predicates.is_in_range_hpp" title="Header <boost/log/expressions/predicates/is_in_range.hpp>">boost/log/expressions/predicates/is_in_range.hpp</a></code><span class="special">></span> 667</pre> 668<p> 669 The <code class="computeroutput"><a class="link" href="../../boost/log/expressions/is_in_ra_idm46079577805680.html" title="Function template is_in_range">is_in_range</a></code> predicate 670 checks that the attribute value fits in the half-open range (i.e. it 671 returns <code class="computeroutput"><span class="keyword">true</span></code> if the attribute 672 value <code class="computeroutput"><span class="identifier">x</span></code> satisfies the 673 following condition: <code class="computeroutput"><span class="identifier">left</span> <span class="special"><=</span> <span class="identifier">x</span> <span class="special"><</span> <span class="identifier">right</span></code>). 674 For example: 675 </p> 676<pre class="programlisting"><span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_filter</span> 677<span class="special">(</span> 678 <span class="comment">// drops all records that have level below 3 or greater than 4</span> 679 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">is_in_range</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">int</span> <span class="special">>(</span><span class="string">"Severity"</span><span class="special">),</span> <span class="number">3</span><span class="special">,</span> <span class="number">5</span><span class="special">)</span> 680<span class="special">);</span> 681</pre> 682<p> 683 The attribute can also be identified by an attribute keyword or name 684 and type: 685 </p> 686<pre class="programlisting"><span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_filter</span> 687<span class="special">(</span> 688 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">is_in_range</span><span class="special">(</span><span class="identifier">severity</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">5</span><span class="special">)</span> 689<span class="special">);</span> 690 691<span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_filter</span> 692<span class="special">(</span> 693 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">is_in_range</span><span class="special"><</span> <span class="keyword">int</span> <span class="special">>(</span><span class="string">"Severity"</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">5</span><span class="special">)</span> 694<span class="special">);</span> 695</pre> 696</div> 697<div class="section"> 698<div class="titlepage"><div><div><h5 class="title"> 699<a name="log.detailed.expressions.predicates.simple_string_matching"></a><a class="link" href="expressions.html#log.detailed.expressions.predicates.simple_string_matching" title="Simple string matching filters">Simple 700 string matching filters</a> 701</h5></div></div></div> 702<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.predicates.begins_with_hpp" title="Header <boost/log/expressions/predicates/begins_with.hpp>">boost/log/expressions/predicates/begins_with.hpp</a></code><span class="special">></span> 703<span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.predicates.ends_with_hpp" title="Header <boost/log/expressions/predicates/ends_with.hpp>">boost/log/expressions/predicates/ends_with.hpp</a></code><span class="special">></span> 704<span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.predicates.contains_hpp" title="Header <boost/log/expressions/predicates/contains.hpp>">boost/log/expressions/predicates/contains.hpp</a></code><span class="special">></span> 705</pre> 706<p> 707 Predicates <code class="computeroutput"><a class="link" href="../../boost/log/expressions/begins_w_idm46079578131920.html" title="Function template begins_with">begins_with</a></code>, <code class="computeroutput"><a class="link" href="../../boost/log/expressions/ends_wit_idm46079577870368.html" title="Function template ends_with">ends_with</a></code> 708 and <code class="computeroutput"><a class="link" href="../../boost/log/expressions/contains_idm46079577892816.html" title="Function template contains">contains</a></code> provide an 709 easy way of matching string attribute values. As follows from their names, 710 the functions construct filters that return <code class="computeroutput"><span class="keyword">true</span></code> 711 if an attribute value begins with, ends with or contains the specified 712 substring, respectively. The string comparison is case sensitive. 713 </p> 714<pre class="programlisting"><span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_filter</span> 715<span class="special">(</span> 716 <span class="comment">// selects only records that are related to Russian web domains</span> 717 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">ends_with</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">"Domain"</span><span class="special">),</span> <span class="string">".ru"</span><span class="special">)</span> 718<span class="special">);</span> 719</pre> 720<p> 721 The attribute can also be identified by an attribute keyword or name 722 and type. 723 </p> 724</div> 725<div class="section"> 726<div class="titlepage"><div><div><h5 class="title"> 727<a name="log.detailed.expressions.predicates.advanced_string_matching"></a><a class="link" href="expressions.html#log.detailed.expressions.predicates.advanced_string_matching" title="Advanced string matching filter">Advanced 728 string matching filter</a> 729</h5></div></div></div> 730<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.predicates.matches_hpp" title="Header <boost/log/expressions/predicates/matches.hpp>">boost/log/expressions/predicates/matches.hpp</a></code><span class="special">></span> 731 732<span class="comment">// Supporting headers</span> 733<span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../other_libraries_support_layer.html#header.boost.log.support.regex_hpp" title="Header <boost/log/support/regex.hpp>">boost/log/support/regex.hpp</a></code><span class="special">></span> 734<span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../other_libraries_support_layer.html#header.boost.log.support.std_regex_hpp" title="Header <boost/log/support/std_regex.hpp>">boost/log/support/std_regex.hpp</a></code><span class="special">></span> 735<span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../other_libraries_support_layer.html#header.boost.log.support.xpressive_hpp" title="Header <boost/log/support/xpressive.hpp>">boost/log/support/xpressive.hpp</a></code><span class="special">></span> 736<span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../other_libraries_support_layer.html#header.boost.log.support.spirit_qi_hpp" title="Header <boost/log/support/spirit_qi.hpp>">boost/log/support/spirit_qi.hpp</a></code><span class="special">></span> 737<span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../other_libraries_support_layer.html#header.boost.log.support.spirit_classic_hpp" title="Header <boost/log/support/spirit_classic.hpp>">boost/log/support/spirit_classic.hpp</a></code><span class="special">></span> 738</pre> 739<p> 740 The <code class="computeroutput"><a class="link" href="../../boost/log/expressions/matches_idm46079577768640.html" title="Function template matches">matches</a></code> function creates 741 a filter that apples a regular expression or a parser to a string attribute 742 value. The regular expression can be provided by <a href="http://www.boost.org/doc/libs/release/libs/regex/index.html" target="_top">Boost.Regex</a> 743 or <a href="http://www.boost.org/doc/libs/release/doc/html/xpressive.html" target="_top">Boost.Xpressive</a>. 744 Parsers from <a href="http://www.boost.org/doc/libs/release/libs/spirit/classic/index.html" target="_top">Boost.Spirit</a> 745 and <a href="http://www.boost.org/doc/libs/release/libs/spirit/doc/html/index.html" target="_top">Boost.Spirit2</a> 746 are also supported. The filter returns <code class="computeroutput"><span class="keyword">true</span></code> 747 if the regular expression matches or the parser successfully parses the 748 attribute value. 749 </p> 750<div class="note"><table border="0" summary="Note"> 751<tr> 752<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td> 753<th align="left">Note</th> 754</tr> 755<tr><td align="left" valign="top"><p> 756 In order to use this predicate, a corresponding supporting header should 757 also be included. 758 </p></td></tr> 759</table></div> 760<pre class="programlisting"><span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_filter</span> 761<span class="special">(</span> 762 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">matches</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">"Domain"</span><span class="special">),</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">regex</span><span class="special">(</span><span class="string">"www\\..*\\.ru"</span><span class="special">))</span> 763<span class="special">);</span> 764</pre> 765<p> 766 The attribute can also be identified by an attribute keyword or name 767 and type. 768 </p> 769</div> 770<div class="section"> 771<div class="titlepage"><div><div><h5 class="title"> 772<a name="log.detailed.expressions.predicates.channel_severity_filter"></a><a class="link" href="expressions.html#log.detailed.expressions.predicates.channel_severity_filter" title="Severity threshold per channel filter">Severity 773 threshold per channel filter</a> 774</h5></div></div></div> 775<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.predicates.channel_severity_filter_hpp" title="Header <boost/log/expressions/predicates/channel_severity_filter.hpp>">boost/log/expressions/predicates/channel_severity_filter.hpp</a></code><span class="special">></span> 776</pre> 777<p> 778 This filter is aimed for a specific but commonly encountered use case. 779 The <code class="computeroutput"><a class="link" href="../../boost/log/expressions/channel_severity_filter.html" title="Function channel_severity_filter">channel_severity_filter</a></code> 780 function creates a predicate that will check log record severity levels 781 against a threshold. The predicate allows setting different thresholds 782 for different channels. The mapping between channel names and severity 783 thresholds can be filled in <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span></code> 784 style by using the subscript operator or by calling <code class="computeroutput"><span class="identifier">add</span></code> 785 method on the filter itself (the <code class="computeroutput"><a class="link" href="../../boost/log/expressions/channel__idm46079578111408.html" title="Class template channel_severity_filter_actor">channel_severity_filter_actor</a></code> 786 instance). Let's see an example: 787 </p> 788<p> 789</p> 790<pre class="programlisting"><span class="comment">// We define our own severity levels</span> 791<span class="keyword">enum</span> <span class="identifier">severity_level</span> 792<span class="special">{</span> 793 <span class="identifier">normal</span><span class="special">,</span> 794 <span class="identifier">notification</span><span class="special">,</span> 795 <span class="identifier">warning</span><span class="special">,</span> 796 <span class="identifier">error</span><span class="special">,</span> 797 <span class="identifier">critical</span> 798<span class="special">};</span> 799 800<span class="comment">// Define the attribute keywords</span> 801<span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">line_id</span><span class="special">,</span> <span class="string">"LineID"</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span><span class="special">)</span> 802<span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">severity</span><span class="special">,</span> <span class="string">"Severity"</span><span class="special">,</span> <span class="identifier">severity_level</span><span class="special">)</span> 803<span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">channel</span><span class="special">,</span> <span class="string">"Channel"</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">)</span> 804 805 806<span class="keyword">void</span> <span class="identifier">init</span><span class="special">()</span> 807<span class="special">{</span> 808 <span class="comment">// Create a minimal severity table filter</span> 809 <span class="keyword">typedef</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">channel_severity_filter_actor</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">severity_level</span> <span class="special">></span> <span class="identifier">min_severity_filter</span><span class="special">;</span> 810 <span class="identifier">min_severity_filter</span> <span class="identifier">min_severity</span> <span class="special">=</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">channel_severity_filter</span><span class="special">(</span><span class="identifier">channel</span><span class="special">,</span> <span class="identifier">severity</span><span class="special">);</span> 811 812 <span class="comment">// Set up the minimum severity levels for different channels</span> 813 <span class="identifier">min_severity</span><span class="special">[</span><span class="string">"general"</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">notification</span><span class="special">;</span> 814 <span class="identifier">min_severity</span><span class="special">[</span><span class="string">"network"</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">warning</span><span class="special">;</span> 815 <span class="identifier">min_severity</span><span class="special">[</span><span class="string">"gui"</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">error</span><span class="special">;</span> 816 817 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">add_console_log</span> 818 <span class="special">(</span> 819 <span class="identifier">std</span><span class="special">::</span><span class="identifier">clog</span><span class="special">,</span> 820 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">filter</span> <span class="special">=</span> <span class="identifier">min_severity</span> <span class="special">||</span> <span class="identifier">severity</span> <span class="special">>=</span> <span class="identifier">critical</span><span class="special">,</span> 821 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">format</span> <span class="special">=</span> 822 <span class="special">(</span> 823 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> 824 <span class="special"><<</span> <span class="identifier">line_id</span> 825 <span class="special"><<</span> <span class="string">": <"</span> <span class="special"><<</span> <span class="identifier">severity</span> 826 <span class="special"><<</span> <span class="string">"> ["</span> <span class="special"><<</span> <span class="identifier">channel</span> <span class="special"><<</span> <span class="string">"] "</span> 827 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">smessage</span> 828 <span class="special">)</span> 829 <span class="special">);</span> 830<span class="special">}</span> 831 832<span class="comment">// Define our logger type</span> 833<span class="keyword">typedef</span> <span class="identifier">src</span><span class="special">::</span><span class="identifier">severity_channel_logger</span><span class="special"><</span> <span class="identifier">severity_level</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">logger_type</span><span class="special">;</span> 834 835<span class="keyword">void</span> <span class="identifier">test_logging</span><span class="special">(</span><span class="identifier">logger_type</span><span class="special">&</span> <span class="identifier">lg</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">channel_name</span><span class="special">)</span> 836<span class="special">{</span> 837 <span class="identifier">BOOST_LOG_CHANNEL_SEV</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="identifier">channel_name</span><span class="special">,</span> <span class="identifier">normal</span><span class="special">)</span> <span class="special"><<</span> <span class="string">"A normal severity level message"</span><span class="special">;</span> 838 <span class="identifier">BOOST_LOG_CHANNEL_SEV</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="identifier">channel_name</span><span class="special">,</span> <span class="identifier">notification</span><span class="special">)</span> <span class="special"><<</span> <span class="string">"A notification severity level message"</span><span class="special">;</span> 839 <span class="identifier">BOOST_LOG_CHANNEL_SEV</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="identifier">channel_name</span><span class="special">,</span> <span class="identifier">warning</span><span class="special">)</span> <span class="special"><<</span> <span class="string">"A warning severity level message"</span><span class="special">;</span> 840 <span class="identifier">BOOST_LOG_CHANNEL_SEV</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="identifier">channel_name</span><span class="special">,</span> <span class="identifier">error</span><span class="special">)</span> <span class="special"><<</span> <span class="string">"An error severity level message"</span><span class="special">;</span> 841 <span class="identifier">BOOST_LOG_CHANNEL_SEV</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="identifier">channel_name</span><span class="special">,</span> <span class="identifier">critical</span><span class="special">)</span> <span class="special"><<</span> <span class="string">"A critical severity level message"</span><span class="special">;</span> 842<span class="special">}</span> 843</pre> 844<p> 845 </p> 846<p> 847 <a href="../../../../../../libs/log/example/doc/expressions_channel_severity_filter.cpp" target="_top">See 848 the complete code</a>. 849 </p> 850<p> 851 The filter for the console sink is composed from the <code class="computeroutput"><a class="link" href="../../boost/log/expressions/channel__idm46079578111408.html" title="Class template channel_severity_filter_actor">channel_severity_filter_actor</a></code> 852 filter and a general severity level check. This general check will be 853 used when log records do not have a channel attribute or the channel 854 name is not one of those specified in <code class="computeroutput"><a class="link" href="../../boost/log/expressions/channel__idm46079578111408.html" title="Class template channel_severity_filter_actor">channel_severity_filter_actor</a></code> 855 initialization. It should be noted that it is possible to set the default 856 result of the threshold filter that will be used in this case; the default 857 result can be set by the <code class="computeroutput"><span class="identifier">set_default</span></code> 858 method. The <code class="computeroutput"><a class="link" href="../../boost/log/expressions/channel__idm46079578111408.html" title="Class template channel_severity_filter_actor">channel_severity_filter_actor</a></code> 859 filter is set up to limit record severity levels for channels "general", 860 "network" and "gui" - all records in these channels 861 with levels below the specified thresholds will not pass the filter and 862 will be ignored. 863 </p> 864<p> 865 The threshold filter is implemented as an equivalent to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span></code> over the channels, which means 866 that the channel value type must support partial ordering. Obviously, 867 the severity level type must also support ordering to be able to be compared 868 against thresholds. By default the predicate will use <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">less</span></code> 869 equivalent for channel name ordering and <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">greater_equal</span></code> 870 equivalent to compare severity levels. It is possible to customize the 871 ordering predicates. Consult the reference of the <code class="computeroutput"><a class="link" href="../../boost/log/expressions/channel__idm46079578111408.html" title="Class template channel_severity_filter_actor">channel_severity_filter_actor</a></code> 872 class and <code class="computeroutput"><a class="link" href="../../boost/log/expressions/channel_severity_filter.html" title="Function channel_severity_filter">channel_severity_filter</a></code> 873 generator to see the relevant template parameters. 874 </p> 875</div> 876<div class="section"> 877<div class="titlepage"><div><div><h5 class="title"> 878<a name="log.detailed.expressions.predicates.is_debugger_present"></a><a class="link" href="expressions.html#log.detailed.expressions.predicates.is_debugger_present" title="Debugger presence filter">Debugger 879 presence filter</a> 880</h5></div></div></div> 881<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.predicates.is_debugger_present_hpp" title="Header <boost/log/expressions/predicates/is_debugger_present.hpp>">boost/log/expressions/predicates/is_debugger_present.hpp</a></code><span class="special">></span> 882</pre> 883<p> 884 This filter is implemented for Windows only. The <code class="computeroutput"><span class="identifier">is_debugger_present</span></code> 885 filter returns <code class="computeroutput"><span class="keyword">true</span></code> if the 886 application is run under a debugger and <code class="computeroutput"><span class="keyword">false</span></code> 887 otherwise. It does not use any attribute values from the log record. 888 This predicate is typically used with the <a class="link" href="sink_backends.html#log.detailed.sink_backends.debugger" title="Windows debugger output backend">debugger 889 output</a> sink. 890 </p> 891<p> 892</p> 893<pre class="programlisting"><span class="comment">// Complete sink type</span> 894<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> 895 896<span class="keyword">void</span> <span class="identifier">init_logging</span><span class="special">()</span> 897<span class="special">{</span> 898 <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> 899 900 <span class="comment">// Create the sink. The backend requires synchronization in the frontend.</span> 901 <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> 902 903 <span class="comment">// Set the special filter to the frontend</span> 904 <span class="comment">// in order to skip the sink when no debugger is available</span> 905 <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> 906 907 <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> 908<span class="special">}</span> 909</pre> 910<p> 911 </p> 912<p> 913 <a href="../../../../../../libs/log/example/doc/sinks_debugger.cpp" target="_top">See the complete 914 code</a>. 915 </p> 916</div> 917</div> 918<div class="section"> 919<div class="titlepage"><div><div><h4 class="title"> 920<a name="log.detailed.expressions.formatters"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters" title="Formatting expressions">Formatting expressions</a> 921</h4></div></div></div> 922<div class="toc"><dl class="toc"> 923<dt><span class="section"><a href="expressions.html#log.detailed.expressions.formatters.date_time">Date 924 and time formatter</a></span></dt> 925<dt><span class="section"><a href="expressions.html#log.detailed.expressions.formatters.named_scope">Named 926 scope formatter</a></span></dt> 927<dt><span class="section"><a href="expressions.html#log.detailed.expressions.formatters.conditional">Conditional 928 formatters</a></span></dt> 929<dt><span class="section"><a href="expressions.html#log.detailed.expressions.formatters.auto_newline">Automatic 930 newline insertion</a></span></dt> 931<dt><span class="section"><a href="expressions.html#log.detailed.expressions.formatters.decorators">Character 932 decorators</a></span></dt> 933</dl></div> 934<p> 935 As was noted in the <a class="link" href="../tutorial/formatters.html" title="Log record formatting">tutorial</a>, 936 the library provides several ways of expressing formatters, most notable 937 being with a stream-style syntax and <a href="http://www.boost.org/doc/libs/release/libs/format/index.html" target="_top">Boost.Format</a>-style 938 expression. Which of the two formats is chosen is determined by the appropriate 939 anchor expression. To use stream-style syntax one should begin the formatter 940 definition with the <code class="computeroutput"><span class="identifier">stream</span></code> 941 keyword, like that: 942 </p> 943<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.stream_hpp" title="Header <boost/log/expressions/formatters/stream.hpp>">boost/log/expressions/formatters/stream.hpp</a></code><span class="special">></span> 944 945<span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</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">expr1</span> <span class="special"><<</span> <span class="identifier">expr2</span> <span class="special"><<</span> <span class="special">...</span> <span class="special"><<</span> <span class="identifier">exprN</span><span class="special">);</span> 946</pre> 947<p> 948 Here expressions <code class="computeroutput"><span class="identifier">expr1</span></code> 949 through <code class="computeroutput"><span class="identifier">exprN</span></code> may be either 950 manipulators, described in this section, or other expressions resulting 951 in an object that supports putting into an STL-stream. 952 </p> 953<p> 954 To use <a href="http://www.boost.org/doc/libs/release/libs/format/index.html" target="_top">Boost.Format</a>-style 955 syntax one should use <code class="computeroutput"><span class="identifier">format</span></code> 956 construct: 957 </p> 958<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.format_hpp" title="Header <boost/log/expressions/formatters/format.hpp>">boost/log/expressions/formatters/format.hpp</a></code><span class="special">></span> 959 960<span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span><span class="special">(</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"format string"</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">expr1</span> <span class="special">%</span> <span class="identifier">expr2</span> <span class="special">%</span> <span class="special">...</span> <span class="special">%</span> <span class="identifier">exprN</span><span class="special">);</span> 961</pre> 962<p> 963 The format string passed to the <code class="computeroutput"><span class="identifier">format</span></code> 964 keyword should contain positional placeholders for the appropriate expressions. 965 In the case of wide-character logging the format string should be wide. 966 Expressions <code class="computeroutput"><span class="identifier">expr1</span></code> through 967 <code class="computeroutput"><span class="identifier">exprN</span></code> have the same meaning 968 as in stream-like variant. It should be noted though that using stream-like 969 syntax usually results in a faster formatter than the one constructed with 970 the <code class="computeroutput"><span class="identifier">format</span></code> keyword. 971 </p> 972<p> 973 Another useful way of expressing formatters is by using string templates. 974 This part of the library is described in <a class="link" href="utilities.html#log.detailed.utilities.setup.filter_formatter" title="Filter and formatter parsers">this</a> 975 section and is mostly intended to support initialization from the application 976 settings. 977 </p> 978<div class="section"> 979<div class="titlepage"><div><div><h5 class="title"> 980<a name="log.detailed.expressions.formatters.date_time"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.date_time" title="Date and time formatter">Date 981 and time formatter</a> 982</h5></div></div></div> 983<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.date_time_hpp" title="Header <boost/log/expressions/formatters/date_time.hpp>">boost/log/expressions/formatters/date_time.hpp</a></code><span class="special">></span> 984 985<span class="comment">// Supporting headers</span> 986<span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../other_libraries_support_layer.html#header.boost.log.support.date_time_hpp" title="Header <boost/log/support/date_time.hpp>">boost/log/support/date_time.hpp</a></code><span class="special">></span> 987</pre> 988<p> 989 The library provides the <code class="computeroutput"><a class="link" href="../../boost/log/expressions/format_d_idm46079578535872.html" title="Function template format_date_time">format_date_time</a></code> formatter 990 dedicated to date and time-related attribute value types. The function 991 accepts the attribute value name and the format string compatible with 992 <a href="http://www.boost.org/doc/libs/release/doc/html/date_time.html" target="_top">Boost.DateTime</a>. 993 </p> 994<pre class="programlisting"><span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span> 995<span class="special">(</span> 996 <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">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> 997<span class="special">);</span> 998</pre> 999<p> 1000 The attribute value can alternatively be identified with the <a class="link" href="expressions.html#log.detailed.expressions.attr" title="Generic attribute placeholder"><code class="computeroutput"><span class="identifier">attr</span></code></a> placeholder or the <a class="link" href="expressions.html#log.detailed.expressions.attr_keywords" title="Defining attribute keywords">attribute keyword</a>. 1001 </p> 1002<p> 1003 The following placeholders are supported in the format string: 1004 </p> 1005<div class="table"> 1006<a name="log.detailed.expressions.formatters.date_time.date_format_placeholders"></a><p class="title"><b>Table 1.2. Date format placeholders</b></p> 1007<div class="table-contents"><table class="table" summary="Date format placeholders"> 1008<colgroup> 1009<col> 1010<col> 1011<col> 1012</colgroup> 1013<thead><tr> 1014<th> 1015 <p> 1016 Placeholder 1017 </p> 1018 </th> 1019<th> 1020 <p> 1021 Meaning 1022 </p> 1023 </th> 1024<th> 1025 <p> 1026 Example 1027 </p> 1028 </th> 1029</tr></thead> 1030<tbody> 1031<tr> 1032<td> 1033 <p> 1034 %a 1035 </p> 1036 </td> 1037<td> 1038 <p> 1039 Abbreviated weekday name 1040 </p> 1041 </td> 1042<td> 1043 <p> 1044 "Mon" => Monday 1045 </p> 1046 </td> 1047</tr> 1048<tr> 1049<td> 1050 <p> 1051 %A 1052 </p> 1053 </td> 1054<td> 1055 <p> 1056 Long weekday name 1057 </p> 1058 </td> 1059<td> 1060 <p> 1061 "Monday" 1062 </p> 1063 </td> 1064</tr> 1065<tr> 1066<td> 1067 <p> 1068 %b 1069 </p> 1070 </td> 1071<td> 1072 <p> 1073 Abbreviated month name 1074 </p> 1075 </td> 1076<td> 1077 <p> 1078 "Feb" => February 1079 </p> 1080 </td> 1081</tr> 1082<tr> 1083<td> 1084 <p> 1085 %B 1086 </p> 1087 </td> 1088<td> 1089 <p> 1090 Long month name 1091 </p> 1092 </td> 1093<td> 1094 <p> 1095 "February" 1096 </p> 1097 </td> 1098</tr> 1099<tr> 1100<td> 1101 <p> 1102 %d 1103 </p> 1104 </td> 1105<td> 1106 <p> 1107 Numeric day of month with leading zero 1108 </p> 1109 </td> 1110<td> 1111 <p> 1112 "01" 1113 </p> 1114 </td> 1115</tr> 1116<tr> 1117<td> 1118 <p> 1119 %e 1120 </p> 1121 </td> 1122<td> 1123 <p> 1124 Numeric day of month with leading space 1125 </p> 1126 </td> 1127<td> 1128 <p> 1129 " 1" 1130 </p> 1131 </td> 1132</tr> 1133<tr> 1134<td> 1135 <p> 1136 %m 1137 </p> 1138 </td> 1139<td> 1140 <p> 1141 Numeric month, 01-12 1142 </p> 1143 </td> 1144<td> 1145 <p> 1146 "01" 1147 </p> 1148 </td> 1149</tr> 1150<tr> 1151<td> 1152 <p> 1153 %w 1154 </p> 1155 </td> 1156<td> 1157 <p> 1158 Numeric day of week, 1-7 1159 </p> 1160 </td> 1161<td> 1162 <p> 1163 "1" 1164 </p> 1165 </td> 1166</tr> 1167<tr> 1168<td> 1169 <p> 1170 %y 1171 </p> 1172 </td> 1173<td> 1174 <p> 1175 Short year 1176 </p> 1177 </td> 1178<td> 1179 <p> 1180 "12" => 2012 1181 </p> 1182 </td> 1183</tr> 1184<tr> 1185<td> 1186 <p> 1187 %Y 1188 </p> 1189 </td> 1190<td> 1191 <p> 1192 Long year 1193 </p> 1194 </td> 1195<td> 1196 <p> 1197 "2012" 1198 </p> 1199 </td> 1200</tr> 1201</tbody> 1202</table></div> 1203</div> 1204<br class="table-break"><div class="table"> 1205<a name="log.detailed.expressions.formatters.date_time.time_format_placeholders"></a><p class="title"><b>Table 1.3. Time format placeholders</b></p> 1206<div class="table-contents"><table class="table" summary="Time format placeholders"> 1207<colgroup> 1208<col> 1209<col> 1210<col> 1211</colgroup> 1212<thead><tr> 1213<th> 1214 <p> 1215 Placeholder 1216 </p> 1217 </th> 1218<th> 1219 <p> 1220 Meaning 1221 </p> 1222 </th> 1223<th> 1224 <p> 1225 Example 1226 </p> 1227 </th> 1228</tr></thead> 1229<tbody> 1230<tr> 1231<td> 1232 <p> 1233 %f 1234 </p> 1235 </td> 1236<td> 1237 <p> 1238 Fractional seconds with leading zeros 1239 </p> 1240 </td> 1241<td> 1242 <p> 1243 "000231" 1244 </p> 1245 </td> 1246</tr> 1247<tr> 1248<td> 1249 <p> 1250 %H, %O 1251 </p> 1252 </td> 1253<td> 1254 <p> 1255 Hours in 24 hour clock or hours in time duration types with 1256 leading zero if less than 10 1257 </p> 1258 </td> 1259<td> 1260 <p> 1261 "07" 1262 </p> 1263 </td> 1264</tr> 1265<tr> 1266<td> 1267 <p> 1268 %I 1269 </p> 1270 </td> 1271<td> 1272 <p> 1273 Hours in 12 hour clock with leading zero if less than 10 1274 </p> 1275 </td> 1276<td> 1277 <p> 1278 "07" 1279 </p> 1280 </td> 1281</tr> 1282<tr> 1283<td> 1284 <p> 1285 %k 1286 </p> 1287 </td> 1288<td> 1289 <p> 1290 Hours in 24 hour clock or hours in time duration types with 1291 leading space if less than 10 1292 </p> 1293 </td> 1294<td> 1295 <p> 1296 " 7" 1297 </p> 1298 </td> 1299</tr> 1300<tr> 1301<td> 1302 <p> 1303 %l 1304 </p> 1305 </td> 1306<td> 1307 <p> 1308 Hours in 12 hour clock with leading space if less than 10 1309 </p> 1310 </td> 1311<td> 1312 <p> 1313 " 7" 1314 </p> 1315 </td> 1316</tr> 1317<tr> 1318<td> 1319 <p> 1320 %M 1321 </p> 1322 </td> 1323<td> 1324 <p> 1325 Minutes 1326 </p> 1327 </td> 1328<td> 1329 <p> 1330 "32" 1331 </p> 1332 </td> 1333</tr> 1334<tr> 1335<td> 1336 <p> 1337 %p 1338 </p> 1339 </td> 1340<td> 1341 <p> 1342 AM/PM mark, uppercase 1343 </p> 1344 </td> 1345<td> 1346 <p> 1347 "AM" 1348 </p> 1349 </td> 1350</tr> 1351<tr> 1352<td> 1353 <p> 1354 %P 1355 </p> 1356 </td> 1357<td> 1358 <p> 1359 AM/PM mark, lowercase 1360 </p> 1361 </td> 1362<td> 1363 <p> 1364 "am" 1365 </p> 1366 </td> 1367</tr> 1368<tr> 1369<td> 1370 <p> 1371 %q 1372 </p> 1373 </td> 1374<td> 1375 <p> 1376 ISO time zone 1377 </p> 1378 </td> 1379<td> 1380 <p> 1381 "-0700" => Mountain Standard Time 1382 </p> 1383 </td> 1384</tr> 1385<tr> 1386<td> 1387 <p> 1388 %Q 1389 </p> 1390 </td> 1391<td> 1392 <p> 1393 Extended ISO time zone 1394 </p> 1395 </td> 1396<td> 1397 <p> 1398 "-05:00" => Eastern Standard Time 1399 </p> 1400 </td> 1401</tr> 1402<tr> 1403<td> 1404 <p> 1405 %S 1406 </p> 1407 </td> 1408<td> 1409 <p> 1410 Seconds 1411 </p> 1412 </td> 1413<td> 1414 <p> 1415 "26" 1416 </p> 1417 </td> 1418</tr> 1419</tbody> 1420</table></div> 1421</div> 1422<br class="table-break"><div class="table"> 1423<a name="log.detailed.expressions.formatters.date_time.miscellaneous_placeholders"></a><p class="title"><b>Table 1.4. Miscellaneous placeholders</b></p> 1424<div class="table-contents"><table class="table" summary="Miscellaneous placeholders"> 1425<colgroup> 1426<col> 1427<col> 1428<col> 1429</colgroup> 1430<thead><tr> 1431<th> 1432 <p> 1433 Placeholder 1434 </p> 1435 </th> 1436<th> 1437 <p> 1438 Meaning 1439 </p> 1440 </th> 1441<th> 1442 <p> 1443 Example 1444 </p> 1445 </th> 1446</tr></thead> 1447<tbody> 1448<tr> 1449<td> 1450 <p> 1451 %- 1452 </p> 1453 </td> 1454<td> 1455 <p> 1456 Negative sign in case of time duration, if the duration is 1457 less than zero 1458 </p> 1459 </td> 1460<td> 1461 <p> 1462 "-" 1463 </p> 1464 </td> 1465</tr> 1466<tr> 1467<td> 1468 <p> 1469 %+ 1470 </p> 1471 </td> 1472<td> 1473 <p> 1474 Sign of time duration, even if positive 1475 </p> 1476 </td> 1477<td> 1478 <p> 1479 "+" 1480 </p> 1481 </td> 1482</tr> 1483<tr> 1484<td> 1485 <p> 1486 %% 1487 </p> 1488 </td> 1489<td> 1490 <p> 1491 An escaped percent sign 1492 </p> 1493 </td> 1494<td> 1495 <p> 1496 "%" 1497 </p> 1498 </td> 1499</tr> 1500<tr> 1501<td> 1502 <p> 1503 %T 1504 </p> 1505 </td> 1506<td> 1507 <p> 1508 Extended ISO time, equivalent to "%H:%M:%S" 1509 </p> 1510 </td> 1511<td> 1512 <p> 1513 "07:32:26" 1514 </p> 1515 </td> 1516</tr> 1517</tbody> 1518</table></div> 1519</div> 1520<br class="table-break"><p> 1521 Note that in order to use this formatter you will also have to include 1522 a supporting header. When <code class="computeroutput"><a class="link" href="../../other_libraries_support_layer.html#header.boost.log.support.date_time_hpp" title="Header <boost/log/support/date_time.hpp>">boost/log/support/date_time.hpp</a></code> 1523 is included, the formatter supports the following types of <a href="http://www.boost.org/doc/libs/release/doc/html/date_time.html" target="_top">Boost.DateTime</a>: 1524 </p> 1525<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 1526<li class="listitem"> 1527 Date and time types: <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">posix_time</span><span class="special">::</span><span class="identifier">ptime</span></code> 1528 and <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">local_time</span><span class="special">::</span><span class="identifier">local_date_time</span></code>. 1529 </li> 1530<li class="listitem"> 1531 Gregorian date type: <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">gregorian</span><span class="special">::</span><span class="identifier">date</span></code>. 1532 </li> 1533<li class="listitem"> 1534 Time duration types: <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">posix_time</span><span class="special">::</span><span class="identifier">time_duration</span></code> 1535 as well as all the specialized time units such as <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">posix_time</span><span class="special">::</span><span class="identifier">seconds</span></code>, 1536 including subsecond units. 1537 </li> 1538<li class="listitem"> 1539 Date duration types: <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">gregorian</span><span class="special">::</span><span class="identifier">date_duration</span></code>. 1540 </li> 1541</ul></div> 1542<div class="tip"><table border="0" summary="Tip"> 1543<tr> 1544<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td> 1545<th align="left">Tip</th> 1546</tr> 1547<tr><td align="left" valign="top"><p> 1548 <a href="http://www.boost.org/doc/libs/release/doc/html/date_time.html" target="_top">Boost.DateTime</a> 1549 already provides formatting functionality implemented as a number of 1550 locale facets. This functionality can be used instead of this formatter, 1551 although the formatter is expected to provide better performance. 1552 </p></td></tr> 1553</table></div> 1554</div> 1555<div class="section"> 1556<div class="titlepage"><div><div><h5 class="title"> 1557<a name="log.detailed.expressions.formatters.named_scope"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.named_scope" title="Named scope formatter">Named 1558 scope formatter</a> 1559</h5></div></div></div> 1560<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.named_scope_hpp" title="Header <boost/log/expressions/formatters/named_scope.hpp>">boost/log/expressions/formatters/named_scope.hpp</a></code><span class="special">></span> 1561</pre> 1562<p> 1563 The formatter <code class="computeroutput"><a class="link" href="../../boost/log/expressions/format_n_idm46079578339104.html" title="Function template format_named_scope">format_named_scope</a></code> is 1564 intended to add support for flexible formatting of the <a class="link" href="attributes.html#log.detailed.attributes.named_scope" title="Named scopes">named 1565 scope</a> attribute values. The basic usage is quite straightforward 1566 and its result is similar to what <a class="link" href="expressions.html#log.detailed.expressions.attr" title="Generic attribute placeholder"><code class="computeroutput"><span class="identifier">attr</span></code></a> provides: 1567 </p> 1568<pre class="programlisting"><span class="comment">// Puts the scope stack from outer ones towards inner ones: outer scope -> inner scope</span> 1569<span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</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">format_named_scope</span><span class="special">(</span><span class="string">"Scopes"</span><span class="special">,</span> <span class="string">"%n"</span><span class="special">));</span> 1570</pre> 1571<p> 1572 The first argument names the attribute and the second is the format string. 1573 The string can contain the following placeholders: 1574 </p> 1575<div class="table"> 1576<a name="log.detailed.expressions.formatters.named_scope.named_scope_format_placeholders"></a><p class="title"><b>Table 1.5. Named scope format placeholders</b></p> 1577<div class="table-contents"><table class="table" summary="Named scope format placeholders"> 1578<colgroup> 1579<col> 1580<col> 1581<col> 1582</colgroup> 1583<thead><tr> 1584<th> 1585 <p> 1586 Placeholder 1587 </p> 1588 </th> 1589<th> 1590 <p> 1591 Meaning 1592 </p> 1593 </th> 1594<th> 1595 <p> 1596 Example 1597 </p> 1598 </th> 1599</tr></thead> 1600<tbody> 1601<tr> 1602<td> 1603 <p> 1604 %n 1605 </p> 1606 </td> 1607<td> 1608 <p> 1609 Scope name 1610 </p> 1611 </td> 1612<td> 1613 <p> 1614 "void bar::foo()" 1615 </p> 1616 </td> 1617</tr> 1618<tr> 1619<td> 1620 <p> 1621 %c 1622 </p> 1623 </td> 1624<td> 1625 <p> 1626 Function name, if the scope is denoted with <code class="computeroutput"><span class="identifier">BOOST_LOG_FUNCTION</span></code>, 1627 otherwise the full scope name. See the note below. 1628 </p> 1629 </td> 1630<td> 1631 <p> 1632 "bar::foo" 1633 </p> 1634 </td> 1635</tr> 1636<tr> 1637<td> 1638 <p> 1639 %C 1640 </p> 1641 </td> 1642<td> 1643 <p> 1644 Function name, without the function scope, if the scope is 1645 denoted with <code class="computeroutput"><span class="identifier">BOOST_LOG_FUNCTION</span></code>, 1646 otherwise the full scope name. See the note below. 1647 </p> 1648 </td> 1649<td> 1650 <p> 1651 "foo" 1652 </p> 1653 </td> 1654</tr> 1655<tr> 1656<td> 1657 <p> 1658 %f 1659 </p> 1660 </td> 1661<td> 1662 <p> 1663 Source file name of the scope 1664 </p> 1665 </td> 1666<td> 1667 <p> 1668 "/home/user/project/foo.cpp" 1669 </p> 1670 </td> 1671</tr> 1672<tr> 1673<td> 1674 <p> 1675 %F 1676 </p> 1677 </td> 1678<td> 1679 <p> 1680 Source file name of the scope, without the path 1681 </p> 1682 </td> 1683<td> 1684 <p> 1685 "foo.cpp" 1686 </p> 1687 </td> 1688</tr> 1689<tr> 1690<td> 1691 <p> 1692 %l 1693 </p> 1694 </td> 1695<td> 1696 <p> 1697 Line number in the source file 1698 </p> 1699 </td> 1700<td> 1701 <p> 1702 "45" 1703 </p> 1704 </td> 1705</tr> 1706</tbody> 1707</table></div> 1708</div> 1709<br class="table-break"><div class="note"><table border="0" summary="Note"> 1710<tr> 1711<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td> 1712<th align="left">Note</th> 1713</tr> 1714<tr><td align="left" valign="top"><p> 1715 As described in the <a class="link" href="attributes.html#log.detailed.attributes.named_scope" title="Named scopes">named 1716 scope</a> attribute description, it is possible to use <code class="computeroutput"><span class="identifier">BOOST_LOG_FUNCTION</span></code> macro to automatically 1717 generate scope names from the enclosing function name. Unfortunately, 1718 the actual format of the generated strings is compiler-dependent and 1719 in many cases it includes the complete signature of the function. When 1720 "%c" or "%C" format flag is specified, the library 1721 attempts to parse the generated string to extract the function name. 1722 Since C++ syntax is very context dependent and complex, it is not possible 1723 to parse function signature correctly in all cases, so the library 1724 is basically guessing. Depending on the string format, this may fail 1725 or produce incorrect results. In particular, type conversion operators 1726 can pose problems for the parser. In case if the parser fails to recognize 1727 the function signature the library falls back to using the whole string 1728 (i.e. behave equivalent to the "%n" flag). To alleviate the 1729 problem the user can replace the problematic <code class="computeroutput"><span class="identifier">BOOST_LOG_FUNCTION</span></code> 1730 usage with the <code class="computeroutput"><span class="identifier">BOOST_LOG_NAMED_SCOPE</span></code> 1731 macro and explicitly write the desired scope name. Scope names denoted 1732 with <code class="computeroutput"><span class="identifier">BOOST_LOG_NAMED_SCOPE</span></code> 1733 will not be interpreted by the library and will be output as is. In 1734 general, for portability and runtime performance reasons it is preferable 1735 to always use <code class="computeroutput"><span class="identifier">BOOST_LOG_NAMED_SCOPE</span></code> 1736 and "%n" format flag. 1737 </p></td></tr> 1738</table></div> 1739<p> 1740 While the format string describes the presentation of each named scope 1741 in the list, the following named arguments allow to customize the list 1742 traversal and formatting: 1743 </p> 1744<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 1745<li class="listitem"> 1746 <code class="computeroutput"><span class="identifier">format</span></code>. The named 1747 scope format string, as described above. This parameter is used to 1748 specify the format when other named parameters are used. 1749 </li> 1750<li class="listitem"> 1751 <code class="computeroutput"><span class="identifier">iteration</span></code>. The argument 1752 describes the direction of iteration through scopes. Can have values 1753 <code class="computeroutput"><span class="identifier">forward</span></code> (default) 1754 or <code class="computeroutput"><span class="identifier">reverse</span></code>. 1755 </li> 1756<li class="listitem"> 1757 <code class="computeroutput"><span class="identifier">delimiter</span></code>. The argument 1758 can be used to specify the delimiters between scopes. The default 1759 delimiter depends on the <code class="computeroutput"><span class="identifier">iteration</span></code> 1760 argument. If <code class="computeroutput"><span class="identifier">iteration</span> 1761 <span class="special">==</span> <span class="identifier">forward</span></code> 1762 the default <code class="computeroutput"><span class="identifier">delimiter</span></code> 1763 will be "->", otherwise it will be "<-". 1764 </li> 1765<li class="listitem"> 1766 <code class="computeroutput"><span class="identifier">depth</span></code>. The argument 1767 can be used to limit the number of scopes to put to log. The formatter 1768 will print <code class="computeroutput"><span class="identifier">depth</span></code> 1769 innermost scopes and, if there are more scopes left, append an ellipsis 1770 to the written sequence. By default the formatter will write all 1771 scope names. 1772 </li> 1773<li class="listitem"> 1774 <code class="computeroutput"><span class="identifier">incomplete_marker</span></code>. 1775 The argument can be used to specify the string that is used to indicate 1776 that the list has been limited by the <code class="computeroutput"><span class="identifier">depth</span></code> 1777 argument. By default the "..." string is used as the marker. 1778 </li> 1779<li class="listitem"> 1780 <code class="computeroutput"><span class="identifier">empty_marker</span></code>. The 1781 argument can be used to specify the string to output in case if the 1782 scope list is empty. By default nothing is output in this case. 1783 </li> 1784</ul></div> 1785<p> 1786 Here are a few usage examples: 1787 </p> 1788<pre class="programlisting"><span class="comment">// Puts the scope stack in reverse order:</span> 1789<span class="comment">// inner scope (file:line) <- outer scope (file:line)</span> 1790<span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span> 1791<span class="special">(</span> 1792 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> 1793 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">format_named_scope</span><span class="special">(</span> 1794 <span class="string">"Scopes"</span><span class="special">,</span> 1795 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">format</span> <span class="special">=</span> <span class="string">"%n (%f:%l)"</span><span class="special">,</span> 1796 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">iteration</span> <span class="special">=</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">reverse</span><span class="special">)</span> 1797<span class="special">);</span> 1798 1799<span class="comment">// Puts the scope stack in reverse order with a custom delimiter:</span> 1800<span class="comment">// inner scope | outer scope</span> 1801<span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span> 1802<span class="special">(</span> 1803 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> 1804 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">format_named_scope</span><span class="special">(</span> 1805 <span class="string">"Scopes"</span><span class="special">,</span> 1806 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">format</span> <span class="special">=</span> <span class="string">"%n"</span><span class="special">,</span> 1807 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">iteration</span> <span class="special">=</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">reverse</span><span class="special">,</span> 1808 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">delimiter</span> <span class="special">=</span> <span class="string">" | "</span><span class="special">)</span> 1809<span class="special">);</span> 1810 1811<span class="comment">// Puts the scope stack in forward order, no more than 2 inner scopes:</span> 1812<span class="comment">// ... outer scope -> inner scope</span> 1813<span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span> 1814<span class="special">(</span> 1815 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> 1816 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">format_named_scope</span><span class="special">(</span> 1817 <span class="string">"Scopes"</span><span class="special">,</span> 1818 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">format</span> <span class="special">=</span> <span class="string">"%n"</span><span class="special">,</span> 1819 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">iteration</span> <span class="special">=</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">forward</span><span class="special">,</span> 1820 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">depth</span> <span class="special">=</span> <span class="number">2</span><span class="special">)</span> 1821<span class="special">);</span> 1822 1823<span class="comment">// Puts the scope stack in reverse order, no more than 2 inner scopes:</span> 1824<span class="comment">// inner scope <- outer scope <<and more>>...</span> 1825<span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span> 1826<span class="special">(</span> 1827 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> 1828 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">format_named_scope</span><span class="special">(</span> 1829 <span class="string">"Scopes"</span><span class="special">,</span> 1830 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">format</span> <span class="special">=</span> <span class="string">"%n"</span><span class="special">,</span> 1831 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">iteration</span> <span class="special">=</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">reverse</span><span class="special">,</span> 1832 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">incomplete_marker</span> <span class="special">=</span> <span class="string">" <<and more>>..."</span> 1833 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">depth</span> <span class="special">=</span> <span class="number">2</span><span class="special">)</span> 1834<span class="special">);</span> 1835</pre> 1836<div class="tip"><table border="0" summary="Tip"> 1837<tr> 1838<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td> 1839<th align="left">Tip</th> 1840</tr> 1841<tr><td align="left" valign="top"><p> 1842 An empty string can be specified as the <code class="computeroutput"><span class="identifier">incomplete_marker</span></code> 1843 parameter, in which case there will be no indication that the list 1844 was truncated. 1845 </p></td></tr> 1846</table></div> 1847</div> 1848<div class="section"> 1849<div class="titlepage"><div><div><h5 class="title"> 1850<a name="log.detailed.expressions.formatters.conditional"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.conditional" title="Conditional formatters">Conditional 1851 formatters</a> 1852</h5></div></div></div> 1853<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.if_hpp" title="Header <boost/log/expressions/formatters/if.hpp>">boost/log/expressions/formatters/if.hpp</a></code><span class="special">></span> 1854</pre> 1855<p> 1856 There are cases when one would want to check some condition about the 1857 log record and format it depending on that condition. One example of 1858 such a need is formatting an attribute value depending on its runtime 1859 type. The general syntax of the conditional formatter is as follows: 1860 </p> 1861<pre class="programlisting"><span class="identifier">expr</span><span class="special">::</span><span class="identifier">if_</span> <span class="special">(</span><span class="identifier">filter</span><span class="special">)</span> 1862<span class="special">[</span> 1863 <span class="identifier">true_formatter</span> 1864<span class="special">]</span> 1865<span class="special">.</span><span class="identifier">else_</span> 1866<span class="special">[</span> 1867 <span class="identifier">false_formatter</span> 1868<span class="special">]</span> 1869</pre> 1870<p> 1871 Those familiar with <a href="http://www.boost.org/doc/libs/release/libs/phoenix/doc/html/index.html" target="_top">Boost.Phoenix</a> 1872 lambda expressions will find this syntax quite familiar. The <code class="computeroutput"><span class="identifier">filter</span></code> argument is a filter that is 1873 applied to the record being formatted. If it returns <code class="computeroutput"><span class="keyword">true</span></code>, 1874 the <code class="computeroutput"><span class="identifier">true_formatter</span></code> is 1875 executed, otherwise <code class="computeroutput"><span class="identifier">false_formatter</span></code> 1876 is executed. The <code class="computeroutput"><span class="identifier">else_</span></code> 1877 section with <code class="computeroutput"><span class="identifier">false_formatter</span></code> 1878 is optional. If it is omitted and <code class="computeroutput"><span class="identifier">filter</span></code> 1879 yields <code class="computeroutput"><span class="keyword">false</span></code>, no formatter 1880 is executed. Here is an example: 1881 </p> 1882<pre class="programlisting"><span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span> 1883<span class="special">(</span> 1884 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> 1885 <span class="comment">// First, put the current time</span> 1886 <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="string">"TimeStamp"</span><span class="special">,</span> <span class="string">"%Y-%m-%d %H:%M:%S.%f"</span><span class="special">)</span> <span class="special"><<</span> <span class="string">" "</span> 1887 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">if_</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">"ID"</span><span class="special">))</span> 1888 <span class="special">[</span> 1889 <span class="comment">// if "ID" is present then put it to the record</span> 1890 <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">attr</span><span class="special"><</span> <span class="keyword">int</span> <span class="special">>(</span><span class="string">"ID"</span><span class="special">)</span> 1891 <span class="special">]</span> 1892 <span class="special">.</span><span class="identifier">else_</span> 1893 <span class="special">[</span> 1894 <span class="comment">// otherwise put a missing marker</span> 1895 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special"><<</span> <span class="string">"--"</span> 1896 <span class="special">]</span> 1897 <span class="comment">// and after that goes the log record text</span> 1898 <span class="special"><<</span> <span class="string">" "</span> <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">message</span> 1899<span class="special">);</span> 1900</pre> 1901</div> 1902<div class="section"> 1903<div class="titlepage"><div><div><h5 class="title"> 1904<a name="log.detailed.expressions.formatters.auto_newline"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.auto_newline" title="Automatic newline insertion">Automatic 1905 newline insertion</a> 1906</h5></div></div></div> 1907<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.auto_newline_hpp" title="Header <boost/log/expressions/formatters/auto_newline.hpp>">boost/log/expressions/formatters/auto_newline.hpp</a></code><span class="special">></span> 1908</pre> 1909<p> 1910 This is an adaptation of the <a class="link" href="utilities.html#log.detailed.utilities.manipulators.auto_newline" title="Automatic newline insertion"><code class="computeroutput"><span class="identifier">auto_newline</span></code> manipulator</a> for 1911 formatter expressions. The <code class="computeroutput"><span class="identifier">auto_newline</span></code> 1912 formatter can be useful, for example, if log messages generated by one 1913 source are terminated with a newline character (and that behavior cannot 1914 be changed easily), and other messages are not. The formatter will ensure 1915 that all messages are reliably terminated with a newline and there are 1916 no duplicate newline characters. Like the manipulator, it will insert 1917 a newline unless the last character inserted into the stream before it 1918 was a newline. For example: 1919 </p> 1920<pre class="programlisting"><span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span> 1921<span class="special">(</span> 1922 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> 1923 <span class="comment">// Ensure that the sink outputs one message per line,</span> 1924 <span class="comment">// regardless whether the message itself ends with a newline or not</span> 1925 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">message</span> <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">auto_newline</span> 1926<span class="special">);</span> 1927</pre> 1928</div> 1929<div class="section"> 1930<div class="titlepage"><div><div><h5 class="title"> 1931<a name="log.detailed.expressions.formatters.decorators"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.decorators" title="Character decorators">Character 1932 decorators</a> 1933</h5></div></div></div> 1934<p> 1935 There are times when one would like to additionally post-process the 1936 composed string before passing it to the sink backend. For example, in 1937 order to store log into an XML file the formatted log record should be 1938 checked for special characters that have a special meaning in XML documents. 1939 This is where decorators step in. 1940 </p> 1941<div class="note"><table border="0" summary="Note"> 1942<tr> 1943<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td> 1944<th align="left">Note</th> 1945</tr> 1946<tr><td align="left" valign="top"><p> 1947 Unlike most other formatters, decorators are dependent on the character 1948 type of the formatted output and this type cannot be deduced from the 1949 decorated formatter. By default, the character type is assumed to be 1950 <code class="computeroutput"><span class="keyword">char</span></code>. If the formatter 1951 is used to compose a wide-character string, prepend the decorator name 1952 with the <code class="computeroutput"><span class="identifier">w</span></code> letter (e.g. 1953 use <code class="computeroutput"><span class="identifier">wxml_decor</span></code> instead 1954 of <code class="computeroutput"><span class="identifier">xml_decor</span></code>). Also, 1955 for each decorator there is a generator function that accepts the character 1956 type as a template parameter; the function is named similarly to the 1957 decorator prepended with the <code class="computeroutput"><span class="identifier">make_</span></code> 1958 prefix (e.g. <code class="computeroutput"><span class="identifier">make_xml_decor</span></code>). 1959 </p></td></tr> 1960</table></div> 1961<div class="section"> 1962<div class="titlepage"><div><div><h6 class="title"> 1963<a name="log.detailed.expressions.formatters.decorators.xml"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.decorators.xml" title="XML character decorator">XML 1964 character decorator</a> 1965</h6></div></div></div> 1966<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.xml_decorator_hpp" title="Header <boost/log/expressions/formatters/xml_decorator.hpp>">boost/log/expressions/formatters/xml_decorator.hpp</a></code><span class="special">></span> 1967</pre> 1968<p> 1969 This decorator replaces XML special characters (&, <, >, 1970 " and ') with the corresponding tokens (<code class="computeroutput"><span class="special">&</span><span class="identifier">amp</span><span class="special">;</span></code>, 1971 <code class="computeroutput"><span class="special">&</span><span class="identifier">lt</span><span class="special">;</span></code>, <code class="computeroutput"><span class="special">&</span><span class="identifier">gt</span><span class="special">;</span></code>, 1972 <code class="computeroutput"><span class="special">&</span><span class="identifier">quot</span><span class="special">;</span></code> and <code class="computeroutput"><span class="special">&</span><span class="identifier">apos</span><span class="special">;</span></code>, 1973 correspondingly). The usage is as follows: 1974 </p> 1975<pre class="programlisting"><span class="identifier">xml_sink</span><span class="special">-></span><span class="identifier">set_formatter</span> 1976<span class="special">(</span> 1977 <span class="comment">// Apply the decoration to the whole formatted record</span> 1978 <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">xml_decor</span> 1979 <span class="special">[</span> 1980 <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">message</span> 1981 <span class="special">]</span> 1982<span class="special">);</span> 1983</pre> 1984<p> 1985 Since character decorators are yet another kind of formatters, it's 1986 fine to use them in other contexts where formatters are appropriate. 1987 For example, this is also a valid example: 1988 </p> 1989<pre class="programlisting"><span class="identifier">xml_sink</span><span class="special">-></span><span class="identifier">set_formatter</span> 1990<span class="special">(</span> 1991 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"<message>%1%: %2%</message>"</span><span class="special">)</span> 1992 <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> 1993 <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">message</span> <span class="special">];</span> <span class="comment">// Only decorate the message text</span> 1994<span class="special">);</span> 1995</pre> 1996<p> 1997 There is an example of the library set up for logging into an XML file, 1998 see <a href="../../../../../../libs/log/example/doc/sinks_xml_file.cpp" target="_top">here</a>. 1999 </p> 2000</div> 2001<div class="section"> 2002<div class="titlepage"><div><div><h6 class="title"> 2003<a name="log.detailed.expressions.formatters.decorators.csv"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.decorators.csv" title="CSV character decorator">CSV 2004 character decorator</a> 2005</h6></div></div></div> 2006<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.csv_decorator_hpp" title="Header <boost/log/expressions/formatters/csv_decorator.hpp>">boost/log/expressions/formatters/csv_decorator.hpp</a></code><span class="special">></span> 2007</pre> 2008<p> 2009 This decorator allows to ensure that the resulting string conforms 2010 to the <a href="http://en.wikipedia.org/wiki/Comma-separated_values" target="_top">CSV</a> 2011 format requirements. In particular, it duplicates the quote characters 2012 in the formatted string. 2013 </p> 2014<pre class="programlisting"><span class="identifier">csv_sink</span><span class="special">-></span><span class="identifier">set_formatter</span> 2015<span class="special">(</span> 2016 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> 2017 <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> <span class="special"><<</span> <span class="string">","</span> 2018 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">csv_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">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">"Tag"</span><span class="special">)</span> <span class="special">]</span> <span class="special"><<</span> <span class="string">","</span> 2019 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">csv_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">message</span> <span class="special">]</span> 2020<span class="special">);</span> 2021</pre> 2022</div> 2023<div class="section"> 2024<div class="titlepage"><div><div><h6 class="title"> 2025<a name="log.detailed.expressions.formatters.decorators.c"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.decorators.c" title="C-style character decorators">C-style 2026 character decorators</a> 2027</h6></div></div></div> 2028<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.c_decorator_hpp" title="Header <boost/log/expressions/formatters/c_decorator.hpp>">boost/log/expressions/formatters/c_decorator.hpp</a></code><span class="special">></span> 2029</pre> 2030<p> 2031 The header defines two character decorators: <code class="computeroutput"><span class="identifier">c_decor</span></code> 2032 and <code class="computeroutput"><span class="identifier">c_ascii_decor</span></code>. 2033 The first one replaces the following characters with their escaped 2034 counterparts: \ (backslash, 0x5c), \a (bell character, 0x07), \b (backspace, 2035 0x08), \f (formfeed, 0x0c), \n (newline, 0x0a), \r (carriage return, 2036 0x0d), \t (horizontal tabulation, 0x09), \v (vertical tabulation, 0x0b), 2037 ' (apostroph, 0x27), " (quote, 0x22), ? (question mark, 0x3f). 2038 The <code class="computeroutput"><span class="identifier">c_ascii_decor</span></code> decorator 2039 does the same but also replaces all other non-printable and non-ASCII 2040 characters with escaped hexadecimal character codes in C notation (e.g. 2041 "\x8c"). The usage is similar to other character decorators: 2042 </p> 2043<pre class="programlisting"><span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span> 2044<span class="special">(</span> 2045 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> 2046 <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> <span class="special"><<</span> <span class="string">": ["</span> 2047 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">c_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">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">"Tag"</span><span class="special">)</span> <span class="special">]</span> <span class="special"><<</span> <span class="string">"] "</span> 2048 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">c_ascii_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">message</span> <span class="special">]</span> 2049<span class="special">);</span> 2050</pre> 2051</div> 2052<div class="section"> 2053<div class="titlepage"><div><div><h6 class="title"> 2054<a name="log.detailed.expressions.formatters.decorators.char"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.decorators.char" title="General character decorator">General 2055 character decorator</a> 2056</h6></div></div></div> 2057<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.char_decorator_hpp" title="Header <boost/log/expressions/formatters/char_decorator.hpp>">boost/log/expressions/formatters/char_decorator.hpp</a></code><span class="special">></span> 2058</pre> 2059<p> 2060 This decorator allows the user to define his own character replacement 2061 mapping in one of the two forms. The first form is a range of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span></code>s of strings (which can be C-style 2062 strings or ranges of characters, including <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>s). 2063 The strings in the <code class="computeroutput"><span class="identifier">first</span></code> 2064 elements of pairs will be replaced with the <code class="computeroutput"><span class="identifier">second</span></code> 2065 elements of the corresponding pair. 2066 </p> 2067<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="special">>,</span> <span class="number">3</span> <span class="special">></span> <span class="identifier">shell_escapes</span> <span class="special">=</span> 2068<span class="special">{</span> 2069 <span class="special">{</span> <span class="string">"\""</span><span class="special">,</span> <span class="string">"\\\""</span> <span class="special">},</span> 2070 <span class="special">{</span> <span class="string">"'"</span><span class="special">,</span> <span class="string">"\\'"</span> <span class="special">},</span> 2071 <span class="special">{</span> <span class="string">"$"</span><span class="special">,</span> <span class="string">"\\$"</span> <span class="special">}</span> 2072<span class="special">};</span> 2073 2074<span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span> 2075<span class="special">(</span> 2076 <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">char_decor</span><span class="special">(</span><span class="identifier">shell_escapes</span><span class="special">)</span> 2077 <span class="special">[</span> 2078 <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">message</span> 2079 <span class="special">]</span> 2080<span class="special">);</span> 2081</pre> 2082<p> 2083 The second form is two same-sized sequences of strings; the first containing 2084 the search patterns and the second - the corresponding replacements. 2085 </p> 2086<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special"><</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*,</span> <span class="number">3</span> <span class="special">></span> <span class="identifier">shell_patterns</span> <span class="special">=</span> 2087<span class="special">{</span> 2088 <span class="string">"\""</span><span class="special">,</span> <span class="string">"'"</span><span class="special">,</span> <span class="string">"$"</span> 2089<span class="special">};</span> 2090<span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special"><</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*,</span> <span class="number">3</span> <span class="special">></span> <span class="identifier">shell_replacements</span> <span class="special">=</span> 2091<span class="special">{</span> 2092 <span class="string">"\\\""</span><span class="special">,</span> <span class="string">"\\'"</span><span class="special">,</span> <span class="string">"\\$"</span> 2093<span class="special">};</span> 2094 2095<span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span> 2096<span class="special">(</span> 2097 <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">char_decor</span><span class="special">(</span><span class="identifier">shell_patterns</span><span class="special">,</span> <span class="identifier">shell_replacements</span><span class="special">)</span> 2098 <span class="special">[</span> 2099 <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">message</span> 2100 <span class="special">]</span> 2101<span class="special">);</span> 2102</pre> 2103<p> 2104 In both cases the patterns are not interpreted and are sought in the 2105 formatted characters in the original form. 2106 </p> 2107</div> 2108<div class="section"> 2109<div class="titlepage"><div><div><h6 class="title"> 2110<a name="log.detailed.expressions.formatters.decorators.max_size"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.decorators.max_size" title="String length limiting decorator">String 2111 length limiting decorator</a> 2112</h6></div></div></div> 2113<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.max_size_decorator_hpp" title="Header <boost/log/expressions/formatters/max_size_decorator.hpp>">boost/log/expressions/formatters/max_size_decorator.hpp</a></code><span class="special">></span> 2114</pre> 2115<p> 2116 Sometimes it can be useful to be able to limit the size of the output 2117 of a formatter or its part. For example, the limit might be imposed 2118 by the sink or the required output format. The <code class="computeroutput"><span class="identifier">max_size_decor</span></code> 2119 decorator allows to enforce such limit. Let's see a simple example: 2120 </p> 2121<pre class="programlisting"><span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span> 2122<span class="special">(</span> 2123 <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">max_size_decor</span><span class="special"><</span> <span class="keyword">char</span> <span class="special">>(</span><span class="number">20</span><span class="special">)</span> 2124 <span class="special">[</span> 2125 <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">message</span> 2126 <span class="special">]</span> 2127<span class="special">);</span> 2128</pre> 2129<div class="note"><table border="0" summary="Note"> 2130<tr> 2131<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td> 2132<th align="left">Note</th> 2133</tr> 2134<tr><td align="left" valign="top"><p> 2135 The explicit template parameter for <code class="computeroutput"><span class="identifier">max_size_decor</span></code> 2136 specifies the character type that is used by formatter. In this example 2137 the string produced by the formatter contains characters of type 2138 <code class="computeroutput"><span class="keyword">char</span></code>, hence the template 2139 parameter. 2140 </p></td></tr> 2141</table></div> 2142<p> 2143 In this example the decorator limits the log message to no more than 2144 20 <a href="https://en.wikipedia.org/wiki/Character_encoding#Terminology" target="_top">code 2145 units</a> of type <code class="computeroutput"><span class="keyword">char</span></code> 2146 and removes the rest from the output. So if we had a log record like 2147 this: 2148 </p> 2149<pre class="programlisting"><span class="identifier">BOOST_LOG</span><span class="special">(</span><span class="identifier">lg</span><span class="special">)</span> <span class="special"><<</span> <span class="string">"The quick brown fox jumps over the lazy dog"</span><span class="special">;</span> 2150</pre> 2151<p> 2152 the resulting output would look like this: 2153 </p> 2154<pre class="programlisting">The quick brown fox 2155</pre> 2156<p> 2157 However, looking at this output in a log file it is unclear whether 2158 the original output contained anything else. One might want to indicate 2159 the fact of message truncation, should one occur. For that purpose 2160 the decorator allows to specify an overflow marker that will be placed 2161 at the end of the truncated output, if the truncation took place. We 2162 can modify the above example like this: 2163 </p> 2164<pre class="programlisting"><span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span> 2165<span class="special">(</span> 2166 <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">max_size_decor</span><span class="special">(</span><span class="number">20</span><span class="special">,</span> <span class="string">">>>"</span><span class="special">)</span> 2167 <span class="special">[</span> 2168 <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">message</span> 2169 <span class="special">]</span> 2170<span class="special">);</span> 2171</pre> 2172<div class="tip"><table border="0" summary="Tip"> 2173<tr> 2174<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td> 2175<th align="left">Tip</th> 2176</tr> 2177<tr><td align="left" valign="top"><p> 2178 The formatter character type is deduced from the character type of 2179 the overflow marker, so it can be omitted. 2180 </p></td></tr> 2181</table></div> 2182<p> 2183 Now our log record will look like this in the output: 2184 </p> 2185<pre class="programlisting">The quick brown f>>> 2186</pre> 2187<p> 2188 This output makes it more obvious that there was more to the original 2189 message. Note also that the length of the output is still 20 characters; 2190 the marker replaced the last characters of the truncated output. 2191 </p> 2192<div class="tip"><table border="0" summary="Tip"> 2193<tr> 2194<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td> 2195<th align="left">Tip</th> 2196</tr> 2197<tr><td align="left" valign="top"><p> 2198 For the character truncation and marker positioning to work correctly 2199 in multibyte encodings, it is important that the locale used by the 2200 formatter is set up properly. In particular, the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">codecvt</span></code> 2201 facet in the locale must correctly recognize multibyte sequences 2202 corresponding to a single character in the output. One can use <a href="http://www.boost.org/doc/libs/release/libs/locale/doc/html/index.html" target="_top">Boost.Locale</a> 2203 to generate the locale and then install it in the sink frontend by 2204 calling <code class="computeroutput"><span class="identifier">imbue</span></code> (see 2205 <code class="computeroutput"><a class="link" href="../../boost/log/sinks/basic_fo_idm46079576891744.html" title="Class template basic_formatting_sink_frontend">basic_formatting_sink_frontend</a></code> 2206 for reference). If the output character type is <code class="computeroutput"><span class="keyword">wchar_t</span></code>, 2207 <code class="computeroutput"><span class="keyword">char16_t</span></code> or <code class="computeroutput"><span class="keyword">char32_t</span></code> the library assumes that 2208 the output is encoded in UTF-16 or UTF-32, depending on the size 2209 of the character type. Because the truncation might occur in the 2210 middle of a multi-unit character, truncated output produced by the 2211 decorator can be slightly shorter than the specified limit sometimes. 2212 </p></td></tr> 2213</table></div> 2214<p> 2215 As with any other formatter, <code class="computeroutput"><span class="identifier">max_size_decor</span></code> 2216 can participate in more complex formatting expressions and limit length 2217 of only part of the message. 2218 </p> 2219<pre class="programlisting"><span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span> 2220<span class="special">(</span> 2221 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> 2222 <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="string">"TimeStamp"</span><span class="special">,</span> <span class="string">"%Y-%m-%d %H:%M:%S.%f"</span><span class="special">)</span> <span class="special"><<</span> <span class="string">" ["</span> 2223 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">max_size_decor</span><span class="special">(</span><span class="number">20</span><span class="special">,</span> <span class="string">">>>"</span><span class="special">)</span> 2224 <span class="special">[</span> 2225 <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">message</span> 2226 <span class="special">]</span> 2227 <span class="special"><<</span> <span class="string">"]"</span> 2228<span class="special">);</span> 2229</pre> 2230<p> 2231 The above formatter can produce output like this: 2232 </p> 2233<pre class="programlisting">2016-08-10 00:36:44.028473 [The quick brown f>>>] 2234</pre> 2235</div> 2236</div> 2237</div> 2238</div> 2239<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 2240<td align="left"></td> 2241<td align="right"><div class="copyright-footer">Copyright © 2007-2019 Andrey Semashev<p> 2242 Distributed under the Boost Software License, Version 1.0. (See accompanying 2243 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>). 2244 </p> 2245</div></td> 2246</tr></table> 2247<hr> 2248<div class="spirit-nav"> 2249<a accesskey="p" href="sink_backends.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="attributes.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> 2250</div> 2251</body> 2252</html> 2253