1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 4<title>Attributes</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="expressions.html" title="Lambda expressions"> 10<link rel="next" href="utilities.html" title="Utilities"> 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="expressions.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="utilities.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.attributes"></a><a class="link" href="attributes.html" title="Attributes">Attributes</a> 21</h3></div></div></div> 22<div class="toc"><dl class="toc"> 23<dt><span class="section"><a href="attributes.html#log.detailed.attributes.constant">Constants</a></span></dt> 24<dt><span class="section"><a href="attributes.html#log.detailed.attributes.mutable_constant">Mutable constants</a></span></dt> 25<dt><span class="section"><a href="attributes.html#log.detailed.attributes.counter">Counters</a></span></dt> 26<dt><span class="section"><a href="attributes.html#log.detailed.attributes.clock">Wall clock</a></span></dt> 27<dt><span class="section"><a href="attributes.html#log.detailed.attributes.timer">Stop watch (timer)</a></span></dt> 28<dt><span class="section"><a href="attributes.html#log.detailed.attributes.named_scope">Named scopes</a></span></dt> 29<dt><span class="section"><a href="attributes.html#log.detailed.attributes.process_id">Current process 30 identifier</a></span></dt> 31<dt><span class="section"><a href="attributes.html#log.detailed.attributes.process_name">Current process 32 name</a></span></dt> 33<dt><span class="section"><a href="attributes.html#log.detailed.attributes.thread_id">Current thread identifier</a></span></dt> 34<dt><span class="section"><a href="attributes.html#log.detailed.attributes.function">Function objects 35 as attributes</a></span></dt> 36<dt><span class="section"><a href="attributes.html#log.detailed.attributes.related_components">Other attribute-related 37 components</a></span></dt> 38</dl></div> 39<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.attribute_hpp" title="Header <boost/log/attributes/attribute.hpp>">boost/log/attributes/attribute.hpp</a></code><span class="special">></span> 40<span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.attribute_cast_hpp" title="Header <boost/log/attributes/attribute_cast.hpp>">boost/log/attributes/attribute_cast.hpp</a></code><span class="special">></span> 41<span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.attribute_value_hpp" title="Header <boost/log/attributes/attribute_value.hpp>">boost/log/attributes/attribute_value.hpp</a></code><span class="special">></span> 42</pre> 43<p> 44 All attributes in the library are implemented using the <a href="http://c2.com/cgi/wiki?PimplIdiom" target="_top">pimpl 45 idiom</a>, or more specifically - shared pimpl idiom. Every attribute 46 provides an interface class which derives from the <code class="computeroutput"><a class="link" href="../../boost/log/attribute.html" title="Class attribute">attribute</a></code> 47 class and an implementation class that derives from <code class="computeroutput"><a class="link" href="../../boost/log/attribute/impl.html" title="Struct impl">impl</a></code>. 48 The interface class only holds a reference counted pointer to the actual 49 implementation of the attribute; this pointer is a member of the <code class="computeroutput"><a class="link" href="../../boost/log/attribute.html" title="Class attribute">attribute</a></code> class, so derived interface 50 classes don't have any data members. When the interface class is default 51 constructed, it creates the corresponding implementation object and initializes 52 the <code class="computeroutput"><a class="link" href="../../boost/log/attribute.html" title="Class attribute">attribute</a></code> base class 53 with a pointer to the implementation. Therefore the pimpl nature of attributes 54 is transparent for users in a typical workflow. 55 </p> 56<p> 57 The shared pimpl design comes significant in a few cases though. One such 58 case is copying the attribute. The copy operation is shallow, so multiple 59 interface objects may refer to a single implementation object. There is no 60 way to deep copy an attribute. Another case is default construction of <code class="computeroutput"><a class="link" href="../../boost/log/attribute.html" title="Class attribute">attribute</a></code> which creates an empty 61 object that does not refer to an implementation. Attributes in such empty 62 state should not be passed to the library but can be useful in some cases, 63 e.g. when a delayed variable initialization is needed. 64 </p> 65<p> 66 It is possible to upcast the attribute interface from <code class="computeroutput"><a class="link" href="../../boost/log/attribute.html" title="Class attribute">attribute</a></code> 67 to the actual interface class. To do this one has to apply <code class="computeroutput"><a class="link" href="../../boost/log/attribute_cast.html" title="Function template attribute_cast">attribute_cast</a></code>: 68 </p> 69<pre class="programlisting"><span class="identifier">logging</span><span class="special">::</span><span class="identifier">attribute</span> <span class="identifier">attr</span> <span class="special">=</span> <span class="special">...;</span> 70<span class="identifier">attrs</span><span class="special">::</span><span class="identifier">constant</span><span class="special"><</span> <span class="keyword">int</span> <span class="special">></span> <span class="identifier">const_attr</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">attribute_cast</span><span class="special"><</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">constant</span><span class="special"><</span> <span class="keyword">int</span> <span class="special">></span> <span class="special">>(</span><span class="identifier">attr</span><span class="special">);</span> 71</pre> 72<p> 73 In this example, the cast will succeed (i.e. the <code class="computeroutput"><span class="identifier">const_attr</span></code> 74 will be non-empty) if the attribute <code class="computeroutput"><span class="identifier">attr</span></code> 75 was originally created as <code class="computeroutput"><span class="identifier">attrs</span><span class="special">::</span><span class="identifier">constant</span><span class="special"><</span> <span class="keyword">int</span> <span class="special">></span></code>. Since all data is stored in the implementation 76 object, no data is lost in the casting process. 77 </p> 78<p> 79 The main purpose of attributes is to generate attribute values. Values are 80 semantically distinct from the attributes. Such separation allows implementing 81 attributes that can return different values at different time points (like 82 clock-related attributes, for example) and, on the other hand, allows using 83 different values of the same attribute independently. The <code class="computeroutput"><a class="link" href="../../boost/log/attribute.html" title="Class attribute">attribute</a></code> 84 interface has a method named <code class="computeroutput"><span class="identifier">get_value</span></code> 85 that returns the actual attribute value. Attribute values are also implemented 86 using the shared pimpl approach, the interface class is <code class="computeroutput"><a class="link" href="../../boost/log/attribute_value.html" title="Class attribute_value">attribute_value</a></code> 87 and implementation classes derive from <code class="computeroutput"><a class="link" href="../../boost/log/attribute_value/impl.html" title="Struct impl">impl</a></code>. 88 </p> 89<p> 90 The attribute value object is mostly intended to store the actual attribute 91 value and implement type dispatching in order to be able to extract the stored 92 value. One should not confuse the attribute value object type and the stored 93 value type. The former is in most cases not needed by users and provides 94 type erasure, but the latter is needed to be able to extract the value. For 95 brevity we call the stored attribute value type simply the attribute value 96 type in this documentation. 97 </p> 98<div class="section"> 99<div class="titlepage"><div><div><h4 class="title"> 100<a name="log.detailed.attributes.constant"></a><a class="link" href="attributes.html#log.detailed.attributes.constant" title="Constants">Constants</a> 101</h4></div></div></div> 102<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.constant_hpp" title="Header <boost/log/attributes/constant.hpp>">boost/log/attributes/constant.hpp</a></code><span class="special">></span> 103</pre> 104<p> 105 The most simple and frequently used attribute type is a constant value 106 of some type. This kind of attribute is implemented with the <code class="computeroutput"><a class="link" href="../../boost/log/attributes/constant.html" title="Class template constant">constant</a></code> class template. 107 The template is parametrized with the attribute value type. The constant 108 value should be passed to the attribute constructor. Here is an example: 109 </p> 110<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span> 111<span class="special">{</span> 112 <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger</span> <span class="identifier">lg</span><span class="special">;</span> 113 114 <span class="comment">// Register a constant attribute that always yields value -5</span> 115 <span class="identifier">lg</span><span class="special">.</span><span class="identifier">add_attribute</span><span class="special">(</span><span class="string">"MyInteger"</span><span class="special">,</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">constant</span><span class="special"><</span> <span class="keyword">int</span> <span class="special">>(-</span><span class="number">5</span><span class="special">));</span> 116 117 <span class="comment">// Register another constant attribute. Make it a string this time.</span> 118 <span class="identifier">lg</span><span class="special">.</span><span class="identifier">add_attribute</span><span class="special">(</span><span class="string">"MyString"</span><span class="special">,</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">constant</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">"Hello world!"</span><span class="special">));</span> 119 120 <span class="comment">// There is also a convenience generator function. "MyInteger2" is constant< int > here.</span> 121 <span class="identifier">lg</span><span class="special">.</span><span class="identifier">add_attribute</span><span class="special">(</span><span class="string">"MyInteger2"</span><span class="special">,</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">make_constant</span><span class="special">(</span><span class="number">10</span><span class="special">));</span> 122<span class="special">}</span> 123</pre> 124<p> 125 That's it, there's nothing much you can do with a constant attribute. Constants 126 are very useful when one wants to highlight some log records or just pass 127 some data to a sink backend (e.g. pass statistical parameters to the collector). 128 </p> 129</div> 130<div class="section"> 131<div class="titlepage"><div><div><h4 class="title"> 132<a name="log.detailed.attributes.mutable_constant"></a><a class="link" href="attributes.html#log.detailed.attributes.mutable_constant" title="Mutable constants">Mutable constants</a> 133</h4></div></div></div> 134<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.mutable_constant_hpp" title="Header <boost/log/attributes/mutable_constant.hpp>">boost/log/attributes/mutable_constant.hpp</a></code><span class="special">></span> 135</pre> 136<p> 137 This kind of attribute is an extension for the <a class="link" href="attributes.html#log.detailed.attributes.constant" title="Constants">constant 138 attribute</a>. In addition to being able to store some value, the <code class="computeroutput"><a class="link" href="../../boost/log/attributes/mutable_constant.html" title="Class template mutable_constant">mutable_constant</a></code> 139 class template has two distinctions: 140 </p> 141<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 142<li class="listitem"> 143 it allows modification of the stored value without re-registering the 144 attribute 145 </li> 146<li class="listitem"> 147 it allows synchronization of the stores and reads of the stored value 148 </li> 149</ul></div> 150<p> 151 In order to change the stored value of the attribute, one must call the 152 <code class="computeroutput"><span class="identifier">set</span></code> method: 153 </p> 154<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span> 155<span class="special">{</span> 156 <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger</span> <span class="identifier">lg</span><span class="special">;</span> 157 158 <span class="comment">// Register a mutable constant attribute that always yields value -5</span> 159 <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">mutable_constant</span><span class="special"><</span> <span class="keyword">int</span> <span class="special">></span> <span class="identifier">attr</span><span class="special">(-</span><span class="number">5</span><span class="special">);</span> 160 <span class="identifier">lg</span><span class="special">.</span><span class="identifier">add_attribute</span><span class="special">(</span><span class="string">"MyInteger"</span><span class="special">,</span> <span class="identifier">attr</span><span class="special">);</span> 161 <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">"This record has MyInteger == -5"</span><span class="special">;</span> 162 163 <span class="comment">// Change the attribute value</span> 164 <span class="identifier">attr</span><span class="special">.</span><span class="identifier">set</span><span class="special">(</span><span class="number">100</span><span class="special">);</span> 165 <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">"This record has MyInteger == 100"</span><span class="special">;</span> 166<span class="special">}</span> 167</pre> 168<p> 169 In multithreaded applications the <code class="computeroutput"><span class="identifier">set</span></code> 170 method calls must be serialized with the <code class="computeroutput"><span class="identifier">get_value</span></code> 171 calls (which, generally speaking, happen on every log record being made). 172 By default <code class="computeroutput"><a class="link" href="../../boost/log/attributes/mutable_constant.html" title="Class template mutable_constant">mutable_constant</a></code> 173 does not serialize calls in any way, assuming that the user will do so 174 externally. However, the <code class="computeroutput"><a class="link" href="../../boost/log/attributes/mutable_constant.html" title="Class template mutable_constant">mutable_constant</a></code> 175 template provides three additional template arguments: synchronization 176 primitive type, scoped exclusive lock type and scoped shareable lock type. 177 If a synchronization primitive type is specified, the scoped exclusive 178 lock type is a mandatory parameter. If the scoped shareable lock type is 179 not specified, the attribute will fall back to the exclusive lock instead 180 of shared locks. For example: 181 </p> 182<pre class="programlisting"><span class="comment">// This mutable constant will always lock exclusively</span> 183<span class="comment">// either for reading or storing the value</span> 184<span class="keyword">typedef</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">mutable_constant</span><span class="special"><</span> 185 <span class="keyword">int</span><span class="special">,</span> <span class="comment">// attribute value type</span> 186 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mutex</span><span class="special">,</span> <span class="comment">// synchronization primitive</span> 187 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">lock_guard</span><span class="special"><</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mutex</span> <span class="special">></span> <span class="comment">// exclusive lock type</span> 188<span class="special">></span> <span class="identifier">exclusive_mc</span><span class="special">;</span> 189<span class="identifier">exclusive_mc</span> <span class="identifier">my_int1</span><span class="special">(</span><span class="number">10</span><span class="special">);</span> 190 191<span class="comment">// This mutable constant will use shared clocking for reading the value</span> 192<span class="comment">// and exclusive locking for storing</span> 193<span class="keyword">typedef</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">mutable_constant</span><span class="special"><</span> 194 <span class="keyword">int</span><span class="special">,</span> <span class="comment">// attribute value type</span> 195 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_mutex</span><span class="special">,</span> <span class="comment">// synchronization primitive</span> 196 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">unique_lock</span><span class="special"><</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_mutex</span> <span class="special">>,</span> <span class="comment">// exclusive lock type</span> 197 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_lock</span><span class="special"><</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_mutex</span> <span class="special">></span> <span class="comment">// shared lock type</span> 198<span class="special">></span> <span class="identifier">shared_mc</span><span class="special">;</span> 199<span class="identifier">shared_mc</span> <span class="identifier">my_int2</span><span class="special">(</span><span class="number">20</span><span class="special">);</span> 200 201<span class="identifier">BOOST_LOG_INLINE_GLOBAL_LOGGER_INIT</span><span class="special">(</span><span class="identifier">my_logger</span><span class="special">,</span> <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger_mt</span><span class="special">)</span> 202<span class="special">{</span> 203 <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger_mt</span> <span class="identifier">lg</span><span class="special">;</span> 204 <span class="identifier">lg</span><span class="special">.</span><span class="identifier">add_attribute</span><span class="special">(</span><span class="string">"MyInteger1"</span><span class="special">,</span> <span class="identifier">my_int1</span><span class="special">);</span> 205 <span class="identifier">lg</span><span class="special">.</span><span class="identifier">add_attribute</span><span class="special">(</span><span class="string">"MyInteger2"</span><span class="special">,</span> <span class="identifier">my_int2</span><span class="special">);</span> 206 207 <span class="keyword">return</span> <span class="identifier">lg</span><span class="special">;</span> 208<span class="special">}</span> 209 210<span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span> 211<span class="special">{</span> 212 <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger_mt</span><span class="special">&</span> <span class="identifier">lg</span> <span class="special">=</span> <span class="identifier">get_my_logger</span><span class="special">();</span> 213 214 <span class="comment">// This is safe, even if executed in multiple threads</span> 215 <span class="identifier">my_int1</span><span class="special">.</span><span class="identifier">set</span><span class="special">(</span><span class="number">200</span><span class="special">);</span> 216 <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">"This record has MyInteger1 == 200"</span><span class="special">;</span> 217 218 <span class="identifier">my_int2</span><span class="special">.</span><span class="identifier">set</span><span class="special">(</span><span class="number">300</span><span class="special">);</span> 219 <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">"This record has MyInteger2 == 300"</span><span class="special">;</span> 220<span class="special">}</span> 221</pre> 222<p> 223 Mutable constants are often used as auxiliary attributes inside loggers 224 to store attributes that may change on some events. As opposed to regular 225 constants, which would require re-registering in case of value modification, 226 mutable constants allow modifying the value in-place. 227 </p> 228</div> 229<div class="section"> 230<div class="titlepage"><div><div><h4 class="title"> 231<a name="log.detailed.attributes.counter"></a><a class="link" href="attributes.html#log.detailed.attributes.counter" title="Counters">Counters</a> 232</h4></div></div></div> 233<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.counter_hpp" title="Header <boost/log/attributes/counter.hpp>">boost/log/attributes/counter.hpp</a></code><span class="special">></span> 234</pre> 235<p> 236 Counters are one of the simplest attributes that generate a new value each 237 time requested. Counters are often used to identify log records or to count 238 some events, e.g. accepted network connections. The class template <code class="computeroutput"><a class="link" href="../../boost/log/attributes/counter.html" title="Class template counter">counter</a></code> provides such 239 functionality. This template is parametrized with the counter value type, 240 which should support arithmetic operations, such as <code class="computeroutput"><span class="keyword">operator</span> 241 <span class="special">+</span></code> and <code class="computeroutput"><span class="keyword">operator</span> 242 <span class="special">-</span></code>. The counter attribute allows 243 specification of the initial value and step (which can be negative) on 244 construction. 245 </p> 246<pre class="programlisting"><span class="identifier">BOOST_LOG_INLINE_GLOBAL_LOGGER_INIT</span><span class="special">(</span><span class="identifier">my_logger</span><span class="special">,</span> <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger_mt</span><span class="special">)</span> 247<span class="special">{</span> 248 <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger_mt</span> <span class="identifier">lg</span><span class="special">;</span> 249 250 <span class="comment">// This counter will count lines, starting from 0</span> 251 <span class="identifier">lg</span><span class="special">.</span><span class="identifier">add_attribute</span><span class="special">(</span><span class="string">"LineCounter"</span><span class="special">,</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">counter</span><span class="special"><</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="special">>());</span> 252 253 <span class="comment">// This counter will count backwards, starting from 100 with step -5</span> 254 <span class="identifier">lg</span><span class="special">.</span><span class="identifier">add_attribute</span><span class="special">(</span><span class="string">"CountDown"</span><span class="special">,</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">counter</span><span class="special"><</span> <span class="keyword">int</span> <span class="special">>(</span><span class="number">100</span><span class="special">,</span> <span class="special">-</span><span class="number">5</span><span class="special">));</span> 255 256 <span class="keyword">return</span> <span class="identifier">lg</span><span class="special">;</span> 257<span class="special">}</span> 258 259<span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span> 260<span class="special">{</span> 261 <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger_mt</span><span class="special">&</span> <span class="identifier">lg</span> <span class="special">=</span> <span class="identifier">get_my_logger</span><span class="special">();</span> 262 <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">"This record has LineCounter == 0, CountDown == 100"</span><span class="special">;</span> 263 <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">"This record has LineCounter == 1, CountDown == 95"</span><span class="special">;</span> 264 <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">"This record has LineCounter == 2, CountDown == 90"</span><span class="special">;</span> 265<span class="special">}</span> 266</pre> 267<div class="note"><table border="0" summary="Note"> 268<tr> 269<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td> 270<th align="left">Note</th> 271</tr> 272<tr><td align="left" valign="top"><p> 273 Don't expect that the log records with the <code class="computeroutput"><a class="link" href="../../boost/log/attributes/counter.html" title="Class template counter">counter</a></code> 274 attribute will always have ascending or descending counter values in 275 the resulting log. In multithreaded applications counter values acquired 276 by different threads may come to a sink in any order. See <a class="link" href="../rationale/why_weak_record_ordering.html" title="Why log records are weakly ordered in a multithreaded application?">Rationale</a> 277 for a more detailed explanation on why it can happen. For this reason 278 it is more accurate to say that the <code class="computeroutput"><a class="link" href="../../boost/log/attributes/counter.html" title="Class template counter">counter</a></code> 279 attribute generates an identifier in an ascending or descending order 280 rather than that it counts log records in either order. 281 </p></td></tr> 282</table></div> 283</div> 284<div class="section"> 285<div class="titlepage"><div><div><h4 class="title"> 286<a name="log.detailed.attributes.clock"></a><a class="link" href="attributes.html#log.detailed.attributes.clock" title="Wall clock">Wall clock</a> 287</h4></div></div></div> 288<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.clock_hpp" title="Header <boost/log/attributes/clock.hpp>">boost/log/attributes/clock.hpp</a></code><span class="special">></span> 289</pre> 290<p> 291 One of the "must-have" features of any logging library is support 292 for attaching a time stamp to every log record. The library provides two 293 attributes for this purpose: <code class="computeroutput"><span class="identifier">utc_clock</span></code> 294 and <code class="computeroutput"><span class="identifier">local_clock</span></code>. The former 295 returns the current UTC time and the latter returns the current local time. 296 In either case the returned time stamp is acquired with the maximum precision 297 for the target platform. The attribute value is <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> 298 (see <a href="http://www.boost.org/doc/libs/release/doc/html/date_time.html" target="_top">Boost.DateTime</a>). 299 The usage is quite straightforward: 300 </p> 301<pre class="programlisting"><span class="identifier">BOOST_LOG_DECLARE_GLOBAL_LOGGER</span><span class="special">(</span><span class="identifier">my_logger</span><span class="special">,</span> <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger_mt</span><span class="special">)</span> 302 303<span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span> 304<span class="special">{</span> 305 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">()-></span><span class="identifier">add_global_attribute</span><span class="special">(</span> 306 <span class="string">"TimeStamp"</span><span class="special">,</span> 307 <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">local_clock</span><span class="special">());</span> 308 309 <span class="comment">// Now every log record ever made will have a time stamp attached</span> 310 <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger_mt</span><span class="special">&</span> <span class="identifier">lg</span> <span class="special">=</span> <span class="identifier">get_my_logger</span><span class="special">();</span> 311 <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">"This record has a time stamp"</span><span class="special">;</span> 312<span class="special">}</span> 313</pre> 314</div> 315<div class="section"> 316<div class="titlepage"><div><div><h4 class="title"> 317<a name="log.detailed.attributes.timer"></a><a class="link" href="attributes.html#log.detailed.attributes.timer" title="Stop watch (timer)">Stop watch (timer)</a> 318</h4></div></div></div> 319<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.timer_hpp" title="Header <boost/log/attributes/timer.hpp>">boost/log/attributes/timer.hpp</a></code><span class="special">></span> 320</pre> 321<p> 322 The <code class="computeroutput"><a class="link" href="../../boost/log/attributes/timer.html" title="Class timer">timer</a></code> attribute 323 is very useful when there is a need to estimate the duration of some prolonged 324 process. The attribute returns the time elapsed since the attribute construction. 325 The attribute value type is <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><span class="special">::</span><span class="identifier">time_duration_type</span></code> 326 (see <a href="http://www.boost.org/doc/libs/release/doc/html/date_time.html" target="_top">Boost.DateTime</a>). 327 </p> 328<pre class="programlisting"><span class="comment">// The class represents a single peer-to-peer connection</span> 329<span class="keyword">class</span> <span class="identifier">network_connection</span> 330<span class="special">{</span> 331 <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger</span> <span class="identifier">m_logger</span><span class="special">;</span> 332 333<span class="keyword">public</span><span class="special">:</span> 334 <span class="identifier">network_connection</span><span class="special">()</span> 335 <span class="special">{</span> 336 <span class="identifier">m_logger</span><span class="special">.</span><span class="identifier">add_attribute</span><span class="special">(</span><span class="string">"Duration"</span><span class="special">,</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">timer</span><span class="special">());</span> 337 <span class="identifier">BOOST_LOG</span><span class="special">(</span><span class="identifier">m_logger</span><span class="special">)</span> <span class="special"><<</span> <span class="string">"Connection established"</span><span class="special">;</span> 338 <span class="special">}</span> 339 <span class="special">~</span><span class="identifier">network_connection</span><span class="special">()</span> 340 <span class="special">{</span> 341 <span class="comment">// This log record will show the whole life time duration of the connection</span> 342 <span class="identifier">BOOST_LOG</span><span class="special">(</span><span class="identifier">m_logger</span><span class="special">)</span> <span class="special"><<</span> <span class="string">"Connection closed"</span><span class="special">;</span> 343 <span class="special">}</span> 344<span class="special">};</span> 345</pre> 346<p> 347 The attribute provides high resolution of the time estimation and can even 348 be used as a simple in-place performance profiling tool. 349 </p> 350<div class="tip"><table border="0" summary="Tip"> 351<tr> 352<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td> 353<th align="left">Tip</th> 354</tr> 355<tr><td align="left" valign="top"><p> 356 The <code class="computeroutput"><a class="link" href="../../boost/log/attributes/timer.html" title="Class timer">timer</a></code> 357 attribute can even be used to profile the code in different modules without 358 recompiling them. The trick is to wrap an expensive call to a foreign 359 module with the thread-specific <code class="computeroutput"><a class="link" href="../../boost/log/attributes/timer.html" title="Class timer">timer</a></code> 360 <a class="link" href="attributes.html#log.detailed.attributes.related_components.scoped_attributes" title="Scoped attributes">scoped 361 attribute</a>, which will markup all log records made from within 362 the module with time readings. 363 </p></td></tr> 364</table></div> 365</div> 366<div class="section"> 367<div class="titlepage"><div><div><h4 class="title"> 368<a name="log.detailed.attributes.named_scope"></a><a class="link" href="attributes.html#log.detailed.attributes.named_scope" title="Named scopes">Named scopes</a> 369</h4></div></div></div> 370<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.named_scope_hpp" title="Header <boost/log/attributes/named_scope.hpp>">boost/log/attributes/named_scope.hpp</a></code><span class="special">></span> 371 372<span class="comment">// Supporting headers</span> 373<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.exception_hpp" title="Header <boost/log/support/exception.hpp>">boost/log/support/exception.hpp</a></code><span class="special">></span> 374</pre> 375<p> 376 The logging library supports maintaining scope stack tracking during the 377 application's execution. This stack may either be written to log or be 378 used for other needs (for example, to save the exact call sequence that 379 led to an exception when throwing one). Each stack element contains the 380 following information (see the <code class="computeroutput"><a class="link" href="../../boost/log/attributes/named_scope_entry.html" title="Struct named_scope_entry">named_scope_entry</a></code> 381 structure template definition): 382 </p> 383<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 384<li class="listitem"> 385 Scope name. It can be defined by the user or generated by the compiler, 386 but in any case it <span class="underline">must be a constant string 387 literal</span> (see <a class="link" href="../rationale.html#log.rationale.why_str_lit" title="Why string literals as scope names?">Rationale</a>). 388 </li> 389<li class="listitem"> 390 Source file name, where the scope begins. It is usually a result of 391 the standard <code class="computeroutput"><span class="identifier">__FILE__</span></code> 392 macro expansion. Like the scope name, the file name <span class="underline">must 393 be a constant string literal</span>. 394 </li> 395<li class="listitem"> 396 Line number in the source file. Usually it is a result of the standard 397 <code class="computeroutput"><span class="identifier">__LINE__</span></code> macro expansion. 398 </li> 399</ul></div> 400<p> 401 The scope stack is implemented as a thread-specific global storage internally. 402 There is the <code class="computeroutput"><a class="link" href="../../boost/log/attributes/named_scope.html" title="Class named_scope">named_scope</a></code> 403 attribute that allows hooking this stack into the logging pipeline. This 404 attribute generates value of the nested type <code class="computeroutput"><span class="identifier">named_scope</span><span class="special">::</span><span class="identifier">scope_stack</span></code> 405 which is the instance of the scope stack. The attribute can be registered 406 in the following way: 407 </p> 408<pre class="programlisting"><span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">()-></span><span class="identifier">add_global_attribute</span><span class="special">(</span><span class="string">"Scope"</span><span class="special">,</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">named_scope</span><span class="special">());</span> 409</pre> 410<p> 411 Note that it is perfectly valid to register the attribute globally because 412 the scope stack is thread-local anyway. This will also implicitly add scope 413 tracking to all threads of the application, which is often exactly what 414 is needed. 415 </p> 416<p> 417 Now we can mark execution scopes with the macros <code class="computeroutput"><span class="identifier">BOOST_LOG_FUNCTION</span></code> 418 and <code class="computeroutput"><span class="identifier">BOOST_LOG_NAMED_SCOPE</span></code> 419 (the latter accepts the scope name as its argument). These macros automatically 420 add source position information to each scope entry. An example follows: 421 </p> 422<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">n</span><span class="special">)</span> 423<span class="special">{</span> 424 <span class="comment">// Mark the scope of the function foo</span> 425 <span class="identifier">BOOST_LOG_FUNCTION</span><span class="special">();</span> 426 427 <span class="keyword">switch</span> <span class="special">(</span><span class="identifier">n</span><span class="special">)</span> 428 <span class="special">{</span> 429 <span class="keyword">case</span> <span class="number">0</span><span class="special">:</span> 430 <span class="special">{</span> 431 <span class="comment">// Mark the current scope</span> 432 <span class="identifier">BOOST_LOG_NAMED_SCOPE</span><span class="special">(</span><span class="string">"case 0"</span><span class="special">);</span> 433 <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">"Some log record"</span><span class="special">;</span> 434 <span class="identifier">bar</span><span class="special">();</span> <span class="comment">// call some function</span> 435 <span class="special">}</span> 436 <span class="keyword">break</span><span class="special">;</span> 437 438 <span class="keyword">case</span> <span class="number">1</span><span class="special">:</span> 439 <span class="special">{</span> 440 <span class="comment">// Mark the current scope</span> 441 <span class="identifier">BOOST_LOG_NAMED_SCOPE</span><span class="special">(</span><span class="string">"case 1"</span><span class="special">);</span> 442 <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">"Some log record"</span><span class="special">;</span> 443 <span class="identifier">bar</span><span class="special">();</span> <span class="comment">// call some function</span> 444 <span class="special">}</span> 445 <span class="keyword">break</span><span class="special">;</span> 446 447 <span class="keyword">default</span><span class="special">:</span> 448 <span class="special">{</span> 449 <span class="comment">// Mark the current scope</span> 450 <span class="identifier">BOOST_LOG_NAMED_SCOPE</span><span class="special">(</span><span class="string">"default"</span><span class="special">);</span> 451 <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">"Some log record"</span><span class="special">;</span> 452 <span class="identifier">bar</span><span class="special">();</span> <span class="comment">// call some function</span> 453 <span class="special">}</span> 454 <span class="keyword">break</span><span class="special">;</span> 455 <span class="special">}</span> 456<span class="special">}</span> 457</pre> 458<p> 459 After executing <code class="computeroutput"><span class="identifier">foo</span></code> we 460 will be able to see in the log that the <code class="computeroutput"><span class="identifier">bar</span></code> 461 function was called from <code class="computeroutput"><span class="identifier">foo</span></code> 462 and, more precisely, from the case statement that corresponds to the value 463 of <code class="computeroutput"><span class="identifier">n</span></code>. This may be very 464 useful when tracking down subtle bugs that show up only when <code class="computeroutput"><span class="identifier">bar</span></code> is called from a specific location 465 (e.g. if <code class="computeroutput"><span class="identifier">bar</span></code> is being passed 466 invalid arguments in that particular location). 467 </p> 468<div class="note"><table border="0" summary="Note"> 469<tr> 470<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td> 471<th align="left">Note</th> 472</tr> 473<tr><td align="left" valign="top"><p> 474 The <code class="computeroutput"><span class="identifier">BOOST_LOG_FUNCTION</span></code> 475 macro uses compiler-specific extensions to generate the scope name from 476 the enclosing function. C++11 defines a standard macro <code class="computeroutput"><span class="identifier">__func__</span></code> for this purpose, but it is 477 not universally supported. Additionally, format of the string is not 478 standardized and may vary from one compiler to another. For this reason 479 it is generally advised to use <code class="computeroutput"><span class="identifier">BOOST_LOG_NAMED_SCOPE</span></code> 480 instead of <code class="computeroutput"><span class="identifier">BOOST_LOG_FUNCTION</span></code> 481 to ensure consistent and portable behavior. 482 </p></td></tr> 483</table></div> 484<p> 485 Another good use case is attaching the scope stack information to an exception. 486 With the help of <a href="http://www.boost.org/doc/libs/release/libs/exception/doc/boost-exception.html" target="_top">Boost.Exception</a>, 487 this is possible: 488 </p> 489<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">)</span> 490<span class="special">{</span> 491 <span class="identifier">BOOST_LOG_FUNCTION</span><span class="special">();</span> 492 493 <span class="keyword">if</span> <span class="special">(</span><span class="identifier">x</span> <span class="special"><</span> <span class="number">0</span><span class="special">)</span> 494 <span class="special">{</span> 495 <span class="comment">// Attach a copy of the current scope stack to the exception</span> 496 <span class="keyword">throw</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">enable_error_info</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">range_error</span><span class="special">(</span><span class="string">"x must not be negative"</span><span class="special">))</span> 497 <span class="special"><<</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">current_scope</span><span class="special">();</span> 498 <span class="special">}</span> 499<span class="special">}</span> 500 501<span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span> 502<span class="special">{</span> 503 <span class="identifier">BOOST_LOG_FUNCTION</span><span class="special">();</span> 504 505 <span class="keyword">try</span> 506 <span class="special">{</span> 507 <span class="identifier">bar</span><span class="special">(-</span><span class="number">1</span><span class="special">);</span> 508 <span class="special">}</span> 509 <span class="keyword">catch</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">range_error</span><span class="special">&</span> <span class="identifier">e</span><span class="special">)</span> 510 <span class="special">{</span> 511 <span class="comment">// Acquire the scope stack from the exception object</span> 512 <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">"bar call failed: "</span> <span class="special"><<</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">()</span> <span class="special"><<</span> <span class="string">", scopes stack:\n"</span> 513 <span class="special"><<</span> <span class="special">*</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">get_error_info</span><span class="special"><</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">current_scope_info</span> <span class="special">>(</span><span class="identifier">e</span><span class="special">);</span> 514 <span class="special">}</span> 515<span class="special">}</span> 516</pre> 517<div class="note"><table border="0" summary="Note"> 518<tr> 519<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td> 520<th align="left">Note</th> 521</tr> 522<tr><td align="left" valign="top"><p> 523 In order this code to compile, the <a href="http://www.boost.org/doc/libs/release/libs/exception/doc/boost-exception.html" target="_top">Boost.Exception</a> 524 support header has to be included. 525 </p></td></tr> 526</table></div> 527<div class="note"><table border="0" summary="Note"> 528<tr> 529<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td> 530<th align="left">Note</th> 531</tr> 532<tr><td align="left" valign="top"><p> 533 We do not inject the <code class="computeroutput"><a class="link" href="../../boost/log/attributes/named_scope.html" title="Class named_scope">named_scope</a></code> 534 attribute into the exception. Since scope stacks are maintained globally, 535 throwing an exception will cause stack unwinding and, as a result, will 536 truncate the global stack. Instead we create a copy of the scope stack 537 by calling <code class="computeroutput"><a class="link" href="../../boost/log/current_scope.html" title="Function current_scope">current_scope</a></code> at the 538 throw site. This copy will be kept intact even if the global stack instance 539 changes during the stack unwinding. 540 </p></td></tr> 541</table></div> 542</div> 543<div class="section"> 544<div class="titlepage"><div><div><h4 class="title"> 545<a name="log.detailed.attributes.process_id"></a><a class="link" href="attributes.html#log.detailed.attributes.process_id" title="Current process identifier">Current process 546 identifier</a> 547</h4></div></div></div> 548<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.current_process_id_hpp" title="Header <boost/log/attributes/current_process_id.hpp>">boost/log/attributes/current_process_id.hpp</a></code><span class="special">></span> 549</pre> 550<p> 551 It is often useful to know the process identifier that produces the log, 552 especially if the log can eventually combine the output of different processes. 553 The <code class="computeroutput"><a class="link" href="../../boost/log/attributes/current_process_id.html" title="Class current_process_id">current_process_id</a></code> 554 attribute is a constant that formats into the current process identifier. 555 The value type of the attribute can be determined by the <code class="computeroutput"><span class="identifier">current_process_id</span><span class="special">::</span><span class="identifier">value_type</span></code> typedef. 556 </p> 557<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span> 558<span class="special">{</span> 559 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">()-></span><span class="identifier">add_global_attribute</span><span class="special">(</span> 560 <span class="string">"ProcessID"</span><span class="special">,</span> 561 <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">current_process_id</span><span class="special">());</span> 562<span class="special">}</span> 563</pre> 564</div> 565<div class="section"> 566<div class="titlepage"><div><div><h4 class="title"> 567<a name="log.detailed.attributes.process_name"></a><a class="link" href="attributes.html#log.detailed.attributes.process_name" title="Current process name">Current process 568 name</a> 569</h4></div></div></div> 570<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.current_process_name_hpp" title="Header <boost/log/attributes/current_process_name.hpp>">boost/log/attributes/current_process_name.hpp</a></code><span class="special">></span> 571</pre> 572<p> 573 The <code class="computeroutput"><a class="link" href="../../boost/log/attributes/current_process_name.html" title="Class current_process_name">current_process_name</a></code> 574 produces <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> values with the executable name 575 of the current process. 576 </p> 577<div class="note"><table border="0" summary="Note"> 578<tr> 579<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td> 580<th align="left">Note</th> 581</tr> 582<tr><td align="left" valign="top"><p> 583 This attribute is not universally portable, although Windows, Linux and 584 OS X are supported. The attribute may work on other POSIX systems as 585 well, but it was not tested. If the process name cannot be obtained the 586 attribute will generate a string with the process id. 587 </p></td></tr> 588</table></div> 589<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span> 590<span class="special">{</span> 591 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">()-></span><span class="identifier">add_global_attribute</span><span class="special">(</span> 592 <span class="string">"Process"</span><span class="special">,</span> 593 <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">current_process_name</span><span class="special">());</span> 594<span class="special">}</span> 595</pre> 596</div> 597<div class="section"> 598<div class="titlepage"><div><div><h4 class="title"> 599<a name="log.detailed.attributes.thread_id"></a><a class="link" href="attributes.html#log.detailed.attributes.thread_id" title="Current thread identifier">Current thread identifier</a> 600</h4></div></div></div> 601<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.current_thread_id_hpp" title="Header <boost/log/attributes/current_thread_id.hpp>">boost/log/attributes/current_thread_id.hpp</a></code><span class="special">></span> 602</pre> 603<p> 604 Multithreaded builds of the library also support the <code class="computeroutput"><a class="link" href="../../boost/log/attributes/current_thread_id.html" title="Class current_thread_id">current_thread_id</a></code> 605 attribute with value type <code class="computeroutput"><span class="identifier">current_thread_id</span><span class="special">::</span><span class="identifier">value_type</span></code>. 606 The attribute will generate values specific to the calling thread. The 607 usage is similar to the process id. 608 </p> 609<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span> 610<span class="special">{</span> 611 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">()-></span><span class="identifier">add_global_attribute</span><span class="special">(</span> 612 <span class="string">"ThreadID"</span><span class="special">,</span> 613 <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">current_thread_id</span><span class="special">());</span> 614<span class="special">}</span> 615</pre> 616<div class="tip"><table border="0" summary="Tip"> 617<tr> 618<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td> 619<th align="left">Tip</th> 620</tr> 621<tr><td align="left" valign="top"><p> 622 You may have noticed that the attribute is registered globally. This 623 will not result in all threads having the same ThreadID in log records 624 as the attribute will always return a thread-specific value. The additional 625 benefit is that you don't have to do a thing in the thread initialization 626 routines to have the thread-specific attribute value in log records. 627 </p></td></tr> 628</table></div> 629</div> 630<div class="section"> 631<div class="titlepage"><div><div><h4 class="title"> 632<a name="log.detailed.attributes.function"></a><a class="link" href="attributes.html#log.detailed.attributes.function" title="Function objects as attributes">Function objects 633 as attributes</a> 634</h4></div></div></div> 635<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.function_hpp" title="Header <boost/log/attributes/function.hpp>">boost/log/attributes/function.hpp</a></code><span class="special">></span> 636</pre> 637<p> 638 This attribute is a simple wrapper around a user-defined function object. 639 Each attempt to acquire the attribute value results in the function object 640 call. The result of the call is returned as the attribute value (this implies 641 that the function must not return <code class="computeroutput"><span class="keyword">void</span></code>). 642 The function object attribute can be constructed with the <code class="computeroutput"><span class="identifier">make_function</span></code> helper function, like this: 643 </p> 644<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span> 645<span class="special">{</span> 646 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">()-></span><span class="identifier">add_global_attribute</span><span class="special">(</span><span class="string">"MyRandomAttr"</span><span class="special">,</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">make_function</span><span class="special">(&</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">rand</span><span class="special">));</span> 647<span class="special">}</span> 648</pre> 649<p> 650 Auto-generated function objects, like the ones defined in <a href="http://www.boost.org/doc/libs/release/libs/bind/bind.html" target="_top">Boost.Bind</a> 651 or STL, are also supported. 652 </p> 653<div class="note"><table border="0" summary="Note"> 654<tr> 655<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td> 656<th align="left">Note</th> 657</tr> 658<tr><td align="left" valign="top"><p> 659 Some deficient compilers may not support <code class="computeroutput"><span class="identifier">result_of</span></code> 660 construct properly. This metafunction is used in the <code class="computeroutput"><span class="identifier">make_function</span></code> 661 function to automatically detect the return type of the function object. 662 If <code class="computeroutput"><span class="identifier">result_of</span></code> breaks or 663 detects incorrect type, one can try to explicitly specify the return 664 type of the function object as a template argument to the <code class="computeroutput"><span class="identifier">make_function</span></code> function. 665 </p></td></tr> 666</table></div> 667</div> 668<div class="section"> 669<div class="titlepage"><div><div><h4 class="title"> 670<a name="log.detailed.attributes.related_components"></a><a class="link" href="attributes.html#log.detailed.attributes.related_components" title="Other attribute-related components">Other attribute-related 671 components</a> 672</h4></div></div></div> 673<div class="toc"><dl class="toc"> 674<dt><span class="section"><a href="attributes.html#log.detailed.attributes.related_components.attribute_name">Attribute 675 names</a></span></dt> 676<dt><span class="section"><a href="attributes.html#log.detailed.attributes.related_components.attribute_set">Attribute 677 set</a></span></dt> 678<dt><span class="section"><a href="attributes.html#log.detailed.attributes.related_components.attribute_value_set">Attribute 679 value set</a></span></dt> 680<dt><span class="section"><a href="attributes.html#log.detailed.attributes.related_components.value_processing">Attribute 681 value extraction and visitation</a></span></dt> 682<dt><span class="section"><a href="attributes.html#log.detailed.attributes.related_components.scoped_attributes">Scoped 683 attributes</a></span></dt> 684</dl></div> 685<div class="section"> 686<div class="titlepage"><div><div><h5 class="title"> 687<a name="log.detailed.attributes.related_components.attribute_name"></a><a class="link" href="attributes.html#log.detailed.attributes.related_components.attribute_name" title="Attribute names">Attribute 688 names</a> 689</h5></div></div></div> 690<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.attribute_name_hpp" title="Header <boost/log/attributes/attribute_name.hpp>">boost/log/attributes/attribute_name.hpp</a></code><span class="special">></span> 691</pre> 692<p> 693 Attribute names are represented with <code class="computeroutput"><a class="link" href="../../boost/log/attribute_name.html" title="Class attribute_name">attribute_name</a></code> 694 objects which are used as keys in associative containers of attributes 695 used by the library. The <code class="computeroutput"><a class="link" href="../../boost/log/attribute_name.html" title="Class attribute_name">attribute_name</a></code> 696 object can be created from a string, so most of the time its use is transparent. 697 </p> 698<p> 699 The name is not stored as a string within the <code class="computeroutput"><a class="link" href="../../boost/log/attribute_name.html" title="Class attribute_name">attribute_name</a></code> 700 object. Instead, a process-wide unique identifier is generated and associated 701 with the particular name. This association is preserved until the process 702 termination, so every time the <code class="computeroutput"><a class="link" href="../../boost/log/attribute_name.html" title="Class attribute_name">attribute_name</a></code> 703 object is created for the same name it obtains the same identifier. The 704 association is not stable across the different runs of the application 705 though. 706 </p> 707<div class="warning"><table border="0" summary="Warning"> 708<tr> 709<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../../doc/src/images/warning.png"></td> 710<th align="left">Warning</th> 711</tr> 712<tr><td align="left" valign="top"><p> 713 Since the association between string names and identifiers involves 714 some state allocation, it is not advised to use externally provided 715 or known to be changing strings for attribute names. Even if the name 716 is not used in any log records, the association is preserved anyway. 717 Continuously constructing <code class="computeroutput"><a class="link" href="../../boost/log/attribute_name.html" title="Class attribute_name">attribute_name</a></code> 718 objects with unique string names may manifest itself as a memory leak. 719 </p></td></tr> 720</table></div> 721<p> 722 Working with identifiers is much more efficient than with strings. For 723 example, copying does not involve dynamic memory allocation and comparison 724 operators are very lightweight. On the other hand, it is easy to get 725 a human-readable attribute name for presentation, if needed. 726 </p> 727<p> 728 The <code class="computeroutput"><a class="link" href="../../boost/log/attribute_name.html" title="Class attribute_name">attribute_name</a></code> 729 class supports an empty (uninitialized) state when default constructed. 730 In this state the name object is not equal to any other initialized name 731 object. Uninitialized attribute names should not be passed to the library 732 but can be useful in some contexts (e.g. when a delayed initialization 733 is desired). 734 </p> 735</div> 736<div class="section"> 737<div class="titlepage"><div><div><h5 class="title"> 738<a name="log.detailed.attributes.related_components.attribute_set"></a><a class="link" href="attributes.html#log.detailed.attributes.related_components.attribute_set" title="Attribute set">Attribute 739 set</a> 740</h5></div></div></div> 741<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.attribute_set_hpp" title="Header <boost/log/attributes/attribute_set.hpp>">boost/log/attributes/attribute_set.hpp</a></code><span class="special">></span> 742</pre> 743<p> 744 Attribute set is an unordered associative container that maps <a class="link" href="attributes.html#log.detailed.attributes.related_components.attribute_name" title="Attribute names">attribute 745 names</a> to <a class="link" href="attributes.html" title="Attributes">attributes</a>. 746 It is used in <a class="link" href="sources.html" title="Logging sources">loggers</a> and 747 the <a class="link" href="../detailed.html#log.detailed.core.core" title="Logging core">logging core</a> to store 748 source-specific, thread-specific and global attributes. The interface 749 is very similar to STL associative containers and is described in the 750 <code class="computeroutput"><a class="link" href="../../boost/log/attribute_set.html" title="Class attribute_set">attribute_set</a></code> 751 class reference. 752 </p> 753</div> 754<div class="section"> 755<div class="titlepage"><div><div><h5 class="title"> 756<a name="log.detailed.attributes.related_components.attribute_value_set"></a><a class="link" href="attributes.html#log.detailed.attributes.related_components.attribute_value_set" title="Attribute value set">Attribute 757 value set</a> 758</h5></div></div></div> 759<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.attribute_value_set_hpp" title="Header <boost/log/attributes/attribute_value_set.hpp>">boost/log/attributes/attribute_value_set.hpp</a></code><span class="special">></span> 760</pre> 761<p> 762 Attribute value set is an unordered associative container that maps 763 <a class="link" href="attributes.html#log.detailed.attributes.related_components.attribute_name" title="Attribute names">attribute 764 names</a> to <a class="link" href="attributes.html" title="Attributes">attribute values</a>. 765 This container is used in log <a class="link" href="../detailed.html#log.detailed.core.record" title="Logging records">records</a> 766 to represent attribute values. Unlike conventional containers, <code class="computeroutput"><a class="link" href="../../boost/log/attribute_value_set.html" title="Class attribute_value_set">attribute_value_set</a></code> 767 does not support removing or modifying elements after being inserted. 768 This warrants that the attribute values that participated filtering will 769 not disappear from the log record in the middle of the processing. 770 </p> 771<p> 772 Additionally, the set can be constructed from three <a class="link" href="attributes.html#log.detailed.attributes.related_components.attribute_set" title="Attribute set">attribute 773 sets</a>, which are interpreted as the sets of source-specific, thread-specific 774 and global attributes. The constructor adopts attribute values from the 775 three attribute sets into a single set of attribute values. After construction, 776 <code class="computeroutput"><a class="link" href="../../boost/log/attribute_value_set.html" title="Class attribute_value_set">attribute_value_set</a></code> 777 is considered to be in an unfrozen state. This means that the container 778 may keep references to the elements of the attribute sets used as the 779 source for the value set construction. While in this state, neither the 780 attribute sets nor the value set must not be modified in any way as this 781 may make the value set corrupted. The value set can be used for reading 782 in this state, its lookup operations will perform as usual. The value 783 set can be frozen by calling the <code class="computeroutput"><span class="identifier">freeze</span></code> 784 method; the set will no longer be attached to the original attribute 785 sets and will be available for further insertions after this call. The 786 library will ensure that the value set is always frozen when a log record 787 is returned from the logging core; the set is <span class="underline">not</span> 788 frozen during filtering though. 789 </p> 790<div class="tip"><table border="0" summary="Tip"> 791<tr> 792<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td> 793<th align="left">Tip</th> 794</tr> 795<tr><td align="left" valign="top"><p> 796 In the unfrozen state the value set may not have all attribute values 797 acquired from the attributes. It will only acquire the values as requested 798 by filters. After freezing the container has all attribute values. 799 This transition allows to optimize the library so that attribute values 800 are only acquired when needed. 801 </p></td></tr> 802</table></div> 803<p> 804 For further details on the container interface please consult the <code class="computeroutput"><a class="link" href="../../boost/log/attribute_value_set.html" title="Class attribute_value_set">attribute_value_set</a></code> 805 reference. 806 </p> 807</div> 808<div class="section"> 809<div class="titlepage"><div><div><h5 class="title"> 810<a name="log.detailed.attributes.related_components.value_processing"></a><a class="link" href="attributes.html#log.detailed.attributes.related_components.value_processing" title="Attribute value extraction and visitation">Attribute 811 value extraction and visitation</a> 812</h5></div></div></div> 813<p> 814 Since attribute values do not expose the stored value in the interface, 815 an API is needed to acquire the stored value. The library provides two 816 APIs for this purpose: value visitation and extraction. 817 </p> 818<div class="section"> 819<div class="titlepage"><div><div><h6 class="title"> 820<a name="log.detailed.attributes.related_components.value_processing.visitation"></a><a class="link" href="attributes.html#log.detailed.attributes.related_components.value_processing.visitation" title="Value visitation">Value 821 visitation</a> 822</h6></div></div></div> 823<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.value_visitation_fwd_hpp" title="Header <boost/log/attributes/value_visitation_fwd.hpp>">boost/log/attributes/value_visitation_fwd.hpp</a></code><span class="special">></span> 824<span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.value_visitation_hpp" title="Header <boost/log/attributes/value_visitation.hpp>">boost/log/attributes/value_visitation.hpp</a></code><span class="special">></span> 825</pre> 826<p> 827 Attribute value visitation implements the visitor design pattern, hence 828 the naming. The user has to provide a unary function object (a visitor) 829 which will be invoked on the stored attribute value. The caller also 830 has to provide the expected type or set of possible types of the stored 831 value. Obviously, the visitor must be capable of receiving an argument 832 of the expected type. Visitation will only succeed if the stored type 833 matches the expectation. 834 </p> 835<p> 836 In order to apply the visitor, one should call the <code class="computeroutput"><a class="link" href="../../boost/log/visit_idm46079578815792.html" title="Function template visit">visit</a></code> function on 837 the attribute value. Let's see an example: 838 </p> 839<p> 840</p> 841<pre class="programlisting"><span class="comment">// Our attribute value visitor</span> 842<span class="keyword">struct</span> <span class="identifier">print_visitor</span> 843<span class="special">{</span> 844 <span class="keyword">typedef</span> <span class="keyword">void</span> <span class="identifier">result_type</span><span class="special">;</span> 845 846 <span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="keyword">int</span> <span class="identifier">val</span><span class="special">)</span> <span class="keyword">const</span> 847 <span class="special">{</span> 848 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Visited value is int: "</span> <span class="special"><<</span> <span class="identifier">val</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 849 <span class="special">}</span> 850 851 <span class="identifier">result_type</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">string</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">val</span><span class="special">)</span> <span class="keyword">const</span> 852 <span class="special">{</span> 853 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Visited value is string: "</span> <span class="special"><<</span> <span class="identifier">val</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 854 <span class="special">}</span> 855<span class="special">};</span> 856 857<span class="keyword">void</span> <span class="identifier">print_value</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">attribute_value</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">attr</span><span class="special">)</span> 858<span class="special">{</span> 859 <span class="comment">// Define the set of expected types of the stored value</span> 860 <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span> <span class="keyword">int</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">types</span><span class="special">;</span> 861 862 <span class="comment">// Apply our visitor</span> 863 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">visitation_result</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">visit</span><span class="special"><</span> <span class="identifier">types</span> <span class="special">>(</span><span class="identifier">attr</span><span class="special">,</span> <span class="identifier">print_visitor</span><span class="special">());</span> 864 865 <span class="comment">// Check the result</span> 866 <span class="keyword">if</span> <span class="special">(</span><span class="identifier">result</span><span class="special">)</span> 867 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Visitation succeeded"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 868 <span class="keyword">else</span> 869 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Visitation failed"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 870<span class="special">}</span> 871</pre> 872<p> 873 </p> 874<p> 875 <a href="../../../../../../libs/log/example/doc/attr_value_visitation.cpp" target="_top">See 876 the complete code</a>. 877 </p> 878<p> 879 In this example we print the stored attribute value in our <code class="computeroutput"><span class="identifier">print_visitor</span></code>. We expect the attribute 880 value to have either <code class="computeroutput"><span class="keyword">int</span></code> 881 or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> stored type; only in this 882 case the visitor will be invoked and the visitation result will be 883 positive. In case of failure the <code class="computeroutput"><a class="link" href="../../boost/log/visitation_result.html" title="Class visitation_result">visitation_result</a></code> 884 class provides additional information on the failure reason. The class 885 has the method named <code class="computeroutput"><span class="identifier">code</span></code> 886 which returns visitation error code. The following error codes are 887 possible: 888 </p> 889<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 890<li class="listitem"> 891 <code class="computeroutput"><span class="identifier">ok</span></code> - visitation 892 succeeded, the visitor has been invoked; visitation result is positive 893 when this code is used 894 </li> 895<li class="listitem"> 896 <code class="computeroutput"><span class="identifier">value_not_found</span></code> 897 - visitation failed because the requested value was not found; 898 this code is used when visitation is applied to a log record or 899 a set of attribute values rather than a single value 900 </li> 901<li class="listitem"> 902 <code class="computeroutput"><span class="identifier">value_has_invalid_type</span></code> 903 - visitation failed because the value has type differing from any 904 of the expected types 905 </li> 906</ul></div> 907<p> 908 By default the visitor function result is ignored but it is possible 909 to obtain it. To do this one should use a special <code class="computeroutput"><a class="link" href="../../boost/log/save_result.html" title="Function template save_result">save_result</a></code> wrapper 910 for the visitor; the wrapper will save the visitor resulting value 911 into an external variable captured by reference. The visitor result 912 is initialized when the returned <code class="computeroutput"><a class="link" href="../../boost/log/visitation_result.html" title="Class visitation_result">visitation_result</a></code> 913 is positive. See the following example where we compute the hash value 914 on the stored value. 915 </p> 916<p> 917</p> 918<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">hash_visitor</span> 919<span class="special">{</span> 920 <span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">result_type</span><span class="special">;</span> 921 922 <span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="keyword">int</span> <span class="identifier">val</span><span class="special">)</span> <span class="keyword">const</span> 923 <span class="special">{</span> 924 <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">val</span><span class="special">;</span> 925 <span class="identifier">h</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">h</span> <span class="special"><<</span> <span class="number">15</span><span class="special">)</span> <span class="special">+</span> <span class="identifier">h</span><span class="special">;</span> 926 <span class="identifier">h</span> <span class="special">^=</span> <span class="special">(</span><span class="identifier">h</span> <span class="special">>></span> <span class="number">6</span><span class="special">)</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">h</span> <span class="special"><<</span> <span class="number">7</span><span class="special">);</span> 927 <span class="keyword">return</span> <span class="identifier">h</span><span class="special">;</span> 928 <span class="special">}</span> 929 930 <span class="identifier">result_type</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">string</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">val</span><span class="special">)</span> <span class="keyword">const</span> 931 <span class="special">{</span> 932 <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">h</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> 933 <span class="keyword">for</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">const_iterator</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">val</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">val</span><span class="special">.</span><span class="identifier">end</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> 934 <span class="identifier">h</span> <span class="special">+=</span> <span class="special">*</span><span class="identifier">it</span><span class="special">;</span> 935 936 <span class="identifier">h</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">h</span> <span class="special"><<</span> <span class="number">15</span><span class="special">)</span> <span class="special">+</span> <span class="identifier">h</span><span class="special">;</span> 937 <span class="identifier">h</span> <span class="special">^=</span> <span class="special">(</span><span class="identifier">h</span> <span class="special">>></span> <span class="number">6</span><span class="special">)</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">h</span> <span class="special"><<</span> <span class="number">7</span><span class="special">);</span> 938 <span class="keyword">return</span> <span class="identifier">h</span><span class="special">;</span> 939 <span class="special">}</span> 940<span class="special">};</span> 941 942<span class="keyword">void</span> <span class="identifier">hash_value</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">attribute_value</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">attr</span><span class="special">)</span> 943<span class="special">{</span> 944 <span class="comment">// Define the set of expected types of the stored value</span> 945 <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span> <span class="keyword">int</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">types</span><span class="special">;</span> 946 947 <span class="comment">// Apply our visitor</span> 948 <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">h</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> 949 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">visitation_result</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">visit</span><span class="special"><</span> <span class="identifier">types</span> <span class="special">>(</span><span class="identifier">attr</span><span class="special">,</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">save_result</span><span class="special">(</span><span class="identifier">hash_visitor</span><span class="special">(),</span> <span class="identifier">h</span><span class="special">));</span> 950 951 <span class="comment">// Check the result</span> 952 <span class="keyword">if</span> <span class="special">(</span><span class="identifier">result</span><span class="special">)</span> 953 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Visitation succeeded, hash value: "</span> <span class="special"><<</span> <span class="identifier">h</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 954 <span class="keyword">else</span> 955 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Visitation failed"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 956<span class="special">}</span> 957</pre> 958<p> 959 </p> 960<p> 961 <a href="../../../../../../libs/log/example/doc/attr_value_visitation.cpp" target="_top">See 962 the complete code</a>. 963 </p> 964<div class="tip"><table border="0" summary="Tip"> 965<tr> 966<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td> 967<th align="left">Tip</th> 968</tr> 969<tr><td align="left" valign="top"><p> 970 When there is no default state for the visitor result it is convenient 971 to use <a href="http://www.boost.org/doc/libs/release/libs/optional/index.html" target="_top">Boost.Optional</a> 972 to wrap the returned value. The <code class="computeroutput"><span class="identifier">optional</span></code> 973 will be initialized with the visitor result if visitation succeeded. 974 In case if visitor is polymorphic (i.e. it has different result types 975 depending on its argument type) <a href="http://www.boost.org/doc/libs/release/doc/html/variant.html" target="_top">Boost.Variant</a> 976 can be used to receive the resulting value. It is also worthwhile 977 to use an empty type, such as <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">blank</span></code>, 978 to indicate the uninitialized state of the <code class="computeroutput"><span class="identifier">variant</span></code>. 979 </p></td></tr> 980</table></div> 981<p> 982 As it has been mentioned, visitation can also be applied to log records 983 and attribute value sets. The syntax is the same, except that the attribute 984 name also has to be specified. The <code class="computeroutput"><a class="link" href="../../boost/log/visit_idm46079578815792.html" title="Function template visit">visit</a></code> algorithm will 985 try to find the attribute value by name and then apply the visitor 986 to the found element. 987 </p> 988<p> 989</p> 990<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">hash_value</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">record_view</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">rec</span><span class="special">,</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">attribute_name</span> <span class="identifier">name</span><span class="special">)</span> 991<span class="special">{</span> 992 <span class="comment">// Define the set of expected types of the stored value</span> 993 <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span> <span class="keyword">int</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">types</span><span class="special">;</span> 994 995 <span class="comment">// Apply our visitor</span> 996 <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">h</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> 997 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">visitation_result</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">visit</span><span class="special"><</span> <span class="identifier">types</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">logging</span><span class="special">::</span><span class="identifier">save_result</span><span class="special">(</span><span class="identifier">hash_visitor</span><span class="special">(),</span> <span class="identifier">h</span><span class="special">));</span> 998 999 <span class="comment">// Check the result</span> 1000 <span class="keyword">if</span> <span class="special">(</span><span class="identifier">result</span><span class="special">)</span> 1001 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Visitation succeeded, hash value: "</span> <span class="special"><<</span> <span class="identifier">h</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 1002 <span class="keyword">else</span> 1003 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Visitation failed"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 1004<span class="special">}</span> 1005</pre> 1006<p> 1007 </p> 1008<p> 1009 Also, for convenience <code class="computeroutput"><a class="link" href="../../boost/log/attribute_value.html" title="Class attribute_value">attribute_value</a></code> 1010 has the method named <code class="computeroutput"><span class="identifier">visit</span></code> 1011 with the same meaning as the free function applied to the attribute 1012 value. 1013 </p> 1014</div> 1015<div class="section"> 1016<div class="titlepage"><div><div><h6 class="title"> 1017<a name="log.detailed.attributes.related_components.value_processing.extraction"></a><a class="link" href="attributes.html#log.detailed.attributes.related_components.value_processing.extraction" title="Value extraction">Value 1018 extraction</a> 1019</h6></div></div></div> 1020<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.value_extraction_fwd_hpp" title="Header <boost/log/attributes/value_extraction_fwd.hpp>">boost/log/attributes/value_extraction_fwd.hpp</a></code><span class="special">></span> 1021<span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.value_extraction_hpp" title="Header <boost/log/attributes/value_extraction.hpp>">boost/log/attributes/value_extraction.hpp</a></code><span class="special">></span> 1022</pre> 1023<p> 1024 Attribute value extraction API allows to acquire a reference to the 1025 stored value. It does not require a visitor function object, but the 1026 user still has to provide the expected type or a set of types the stored 1027 value may have. 1028 </p> 1029<p> 1030</p> 1031<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">print_value</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">attribute_value</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">attr</span><span class="special">)</span> 1032<span class="special">{</span> 1033 <span class="comment">// Extract a reference to the stored value</span> 1034 <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">val</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">extract</span><span class="special"><</span> <span class="keyword">int</span> <span class="special">>(</span><span class="identifier">attr</span><span class="special">);</span> 1035 1036 <span class="comment">// Check the result</span> 1037 <span class="keyword">if</span> <span class="special">(</span><span class="identifier">val</span><span class="special">)</span> 1038 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Extraction succeeded: "</span> <span class="special"><<</span> <span class="identifier">val</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 1039 <span class="keyword">else</span> 1040 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Extraction failed"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 1041<span class="special">}</span> 1042</pre> 1043<p> 1044 </p> 1045<p> 1046 <a href="../../../../../../libs/log/example/doc/attr_value_extraction.cpp" target="_top">See 1047 the complete code</a>. 1048 </p> 1049<p> 1050 In this example we expect the attribute value to have the stored type 1051 <code class="computeroutput"><span class="keyword">int</span></code>. The <code class="computeroutput"><a class="link" href="../../boost/log/extract_idm46079579055520.html" title="Function template extract">extract</a></code> 1052 function attempts to extract a reference to the stored value and returns 1053 the filled <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> object if succeeded. 1054 </p> 1055<p> 1056 Value extraction can also be used with a set of expected stored types. 1057 The following code snippet demonstrates this: 1058 </p> 1059<p> 1060</p> 1061<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">print_value_multiple_types</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">attribute_value</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">attr</span><span class="special">)</span> 1062<span class="special">{</span> 1063 <span class="comment">// Define the set of expected types of the stored value</span> 1064 <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span> <span class="keyword">int</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">types</span><span class="special">;</span> 1065 1066 <span class="comment">// Extract a reference to the stored value</span> 1067 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">value_ref</span><span class="special"><</span> <span class="identifier">types</span> <span class="special">></span> <span class="identifier">val</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">extract</span><span class="special"><</span> <span class="identifier">types</span> <span class="special">>(</span><span class="identifier">attr</span><span class="special">);</span> 1068 1069 <span class="comment">// Check the result</span> 1070 <span class="keyword">if</span> <span class="special">(</span><span class="identifier">val</span><span class="special">)</span> 1071 <span class="special">{</span> 1072 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Extraction succeeded"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 1073 <span class="keyword">switch</span> <span class="special">(</span><span class="identifier">val</span><span class="special">.</span><span class="identifier">which</span><span class="special">())</span> 1074 <span class="special">{</span> 1075 <span class="keyword">case</span> <span class="number">0</span><span class="special">:</span> 1076 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"int: "</span> <span class="special"><<</span> <span class="identifier">val</span><span class="special">.</span><span class="identifier">get</span><span class="special"><</span> <span class="keyword">int</span> <span class="special">>()</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 1077 <span class="keyword">break</span><span class="special">;</span> 1078 1079 <span class="keyword">case</span> <span class="number">1</span><span class="special">:</span> 1080 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"string: "</span> <span class="special"><<</span> <span class="identifier">val</span><span class="special">.</span><span class="identifier">get</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="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 1081 <span class="keyword">break</span><span class="special">;</span> 1082 <span class="special">}</span> 1083 <span class="special">}</span> 1084 <span class="keyword">else</span> 1085 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Extraction failed"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 1086<span class="special">}</span> 1087</pre> 1088<p> 1089 </p> 1090<p> 1091 Notice that we used <code class="computeroutput"><span class="identifier">which</span></code> 1092 method of the returned reference to dispatch between possible types. 1093 The method returns the index of the type in the <code class="computeroutput"><span class="identifier">types</span></code> 1094 sequence. Also note that the <code class="computeroutput"><span class="identifier">get</span></code> 1095 method now accepts an explicit template parameter to select the reference 1096 type to acquire; naturally, this type must correspond to the actual 1097 referred type, which is warranted by the switch/case statement in our 1098 case. 1099 </p> 1100<p> 1101 Value visitation is also supported by 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> object. Here is 1102 how we compute a hash value from the extracted value: 1103 </p> 1104<p> 1105</p> 1106<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">hash_visitor</span> 1107<span class="special">{</span> 1108 <span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">result_type</span><span class="special">;</span> 1109 1110 <span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()</span> <span class="special">(</span><span class="keyword">int</span> <span class="identifier">val</span><span class="special">)</span> <span class="keyword">const</span> 1111 <span class="special">{</span> 1112 <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">h</span> <span class="special">=</span> <span class="identifier">val</span><span class="special">;</span> 1113 <span class="identifier">h</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">h</span> <span class="special"><<</span> <span class="number">15</span><span class="special">)</span> <span class="special">+</span> <span class="identifier">h</span><span class="special">;</span> 1114 <span class="identifier">h</span> <span class="special">^=</span> <span class="special">(</span><span class="identifier">h</span> <span class="special">>></span> <span class="number">6</span><span class="special">)</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">h</span> <span class="special"><<</span> <span class="number">7</span><span class="special">);</span> 1115 <span class="keyword">return</span> <span class="identifier">h</span><span class="special">;</span> 1116 <span class="special">}</span> 1117 1118 <span class="identifier">result_type</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">string</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">val</span><span class="special">)</span> <span class="keyword">const</span> 1119 <span class="special">{</span> 1120 <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">h</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> 1121 <span class="keyword">for</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">const_iterator</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">val</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">val</span><span class="special">.</span><span class="identifier">end</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> 1122 <span class="identifier">h</span> <span class="special">+=</span> <span class="special">*</span><span class="identifier">it</span><span class="special">;</span> 1123 1124 <span class="identifier">h</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">h</span> <span class="special"><<</span> <span class="number">15</span><span class="special">)</span> <span class="special">+</span> <span class="identifier">h</span><span class="special">;</span> 1125 <span class="identifier">h</span> <span class="special">^=</span> <span class="special">(</span><span class="identifier">h</span> <span class="special">>></span> <span class="number">6</span><span class="special">)</span> <span class="special">+</span> <span class="special">(</span><span class="identifier">h</span> <span class="special"><<</span> <span class="number">7</span><span class="special">);</span> 1126 <span class="keyword">return</span> <span class="identifier">h</span><span class="special">;</span> 1127 <span class="special">}</span> 1128<span class="special">};</span> 1129 1130<span class="keyword">void</span> <span class="identifier">hash_value</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">attribute_value</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">attr</span><span class="special">)</span> 1131<span class="special">{</span> 1132 <span class="comment">// Define the set of expected types of the stored value</span> 1133 <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span> <span class="keyword">int</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">types</span><span class="special">;</span> 1134 1135 <span class="comment">// Extract the stored value</span> 1136 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">value_ref</span><span class="special"><</span> <span class="identifier">types</span> <span class="special">></span> <span class="identifier">val</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">extract</span><span class="special"><</span> <span class="identifier">types</span> <span class="special">>(</span><span class="identifier">attr</span><span class="special">);</span> 1137 1138 <span class="comment">// Check the result</span> 1139 <span class="keyword">if</span> <span class="special">(</span><span class="identifier">val</span><span class="special">)</span> 1140 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Extraction succeeded, hash value: "</span> <span class="special"><<</span> <span class="identifier">val</span><span class="special">.</span><span class="identifier">apply_visitor</span><span class="special">(</span><span class="identifier">hash_visitor</span><span class="special">())</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 1141 <span class="keyword">else</span> 1142 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Extraction failed"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 1143<span class="special">}</span> 1144</pre> 1145<p> 1146 </p> 1147<p> 1148 Lastly, like with value visitation, value extraction can also be applied 1149 to log records and attribute value sets. 1150 </p> 1151<p> 1152</p> 1153<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">hash_value</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">record_view</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">rec</span><span class="special">,</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">attribute_name</span> <span class="identifier">name</span><span class="special">)</span> 1154<span class="special">{</span> 1155 <span class="comment">// Define the set of expected types of the stored value</span> 1156 <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span> <span class="keyword">int</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">types</span><span class="special">;</span> 1157 1158 <span class="comment">// Extract the stored value</span> 1159 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">value_ref</span><span class="special"><</span> <span class="identifier">types</span> <span class="special">></span> <span class="identifier">val</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">extract</span><span class="special"><</span> <span class="identifier">types</span> <span class="special">>(</span><span class="identifier">name</span><span class="special">,</span> <span class="identifier">rec</span><span class="special">);</span> 1160 1161 <span class="comment">// Check the result</span> 1162 <span class="keyword">if</span> <span class="special">(</span><span class="identifier">val</span><span class="special">)</span> 1163 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Extraction succeeded, hash value: "</span> <span class="special"><<</span> <span class="identifier">val</span><span class="special">.</span><span class="identifier">apply_visitor</span><span class="special">(</span><span class="identifier">hash_visitor</span><span class="special">())</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 1164 <span class="keyword">else</span> 1165 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Extraction failed"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 1166<span class="special">}</span> 1167</pre> 1168<p> 1169 </p> 1170<p> 1171 In addition the library provides two special variants of the <code class="computeroutput"><a class="link" href="../../boost/log/extract_idm46079579055520.html" title="Function template extract">extract</a></code> 1172 function: <code class="computeroutput"><a class="link" href="../../boost/log/extract__idm46079579026960.html" title="Function template extract_or_throw">extract_or_throw</a></code> and 1173 <code class="computeroutput"><a class="link" href="../../boost/log/extract__idm46079578995456.html" title="Function template extract_or_default">extract_or_default</a></code>. 1174 As the naming implies, the functions provide different behavior in 1175 case if the attribute value cannot be extracted. The former one throws 1176 an exception if the value cannot be extracted and the latter one returns 1177 the default value. 1178 </p> 1179<div class="warning"><table border="0" summary="Warning"> 1180<tr> 1181<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../../doc/src/images/warning.png"></td> 1182<th align="left">Warning</th> 1183</tr> 1184<tr><td align="left" valign="top"><p> 1185 Care must be taken with the <code class="computeroutput"><a class="link" href="../../boost/log/extract__idm46079578995456.html" title="Function template extract_or_default">extract_or_default</a></code> 1186 function. The function accepts the default value is accepted by constant 1187 reference, and this reference can eventually be returned from <code class="computeroutput"><a class="link" href="../../boost/log/extract__idm46079578995456.html" title="Function template extract_or_default">extract_or_default</a></code>. 1188 If a temporary object as used for the default value, user must ensure 1189 that the result of <code class="computeroutput"><a class="link" href="../../boost/log/extract__idm46079578995456.html" title="Function template extract_or_default">extract_or_default</a></code> 1190 is saved by value and not by reference. Otherwise the saved reference 1191 may become dangling when the temporary is destroyed. 1192 </p></td></tr> 1193</table></div> 1194<p> 1195 Similarly to <code class="computeroutput"><span class="identifier">visit</span></code>, 1196 the <code class="computeroutput"><a class="link" href="../../boost/log/attribute_value.html" title="Class attribute_value">attribute_value</a></code> 1197 class has methods named <code class="computeroutput"><span class="identifier">extract</span></code>, 1198 <code class="computeroutput"><span class="identifier">extract_or_throw</span></code> and 1199 <code class="computeroutput"><span class="identifier">extract_or_default</span></code> 1200 with the same meaning as the corresponding free functions applied to 1201 the attribute value. 1202 </p> 1203</div> 1204</div> 1205<div class="section"> 1206<div class="titlepage"><div><div><h5 class="title"> 1207<a name="log.detailed.attributes.related_components.scoped_attributes"></a><a class="link" href="attributes.html#log.detailed.attributes.related_components.scoped_attributes" title="Scoped attributes">Scoped 1208 attributes</a> 1209</h5></div></div></div> 1210<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../attributes.html#header.boost.log.attributes.scoped_attribute_hpp" title="Header <boost/log/attributes/scoped_attribute.hpp>">boost/log/attributes/scoped_attribute.hpp</a></code><span class="special">></span> 1211</pre> 1212<p> 1213 Scoped attributes are a powerful mechanism of tagging log records that 1214 can be used for different purposes. As the naming implies, scoped attributes 1215 are registered in the beginning of a scope and unregistered on the end 1216 of the scope. The mechanism includes the following macros: 1217 </p> 1218<pre class="programlisting"><code class="computeroutput"><a class="link" href="../../BOOST_LO_idm46079579098656.html" title="Macro BOOST_LOG_SCOPED_LOGGER_ATTR">BOOST_LOG_SCOPED_LOGGER_ATTR</a></code><span class="special">(</span><span class="identifier">logger</span><span class="special">,</span> <span class="identifier">attr_name</span><span class="special">,</span> <span class="identifier">attr</span><span class="special">);</span> 1219<code class="computeroutput"><a class="link" href="../../BOOST_LO_idm46079579093888.html" title="Macro BOOST_LOG_SCOPED_THREAD_ATTR">BOOST_LOG_SCOPED_THREAD_ATTR</a></code><span class="special">(</span><span class="identifier">attr_name</span><span class="special">,</span> <span class="identifier">attr</span><span class="special">);</span> 1220</pre> 1221<p> 1222 The first macro registers a source-specific attribute in the <code class="computeroutput"><span class="identifier">logger</span></code> logger object. The attribute 1223 name and the attribute itself are given in the <code class="computeroutput"><span class="identifier">attr_name</span></code> 1224 and <code class="computeroutput"><span class="identifier">attr</span></code> arguments. The 1225 second macro does exactly the same but the attribute is registered for 1226 the current thread in the logging core (which does not require a logger). 1227 </p> 1228<div class="note"><table border="0" summary="Note"> 1229<tr> 1230<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td> 1231<th align="left">Note</th> 1232</tr> 1233<tr><td align="left" valign="top"><p> 1234 If an attribute with the same name is already registered in the logger/logging 1235 core, the macros won't override the existing attribute and will eventually 1236 have no effect. See <a class="link" href="../rationale/why_weak_scoped_attributes.html" title="Why scoped attributes don't override existing attributes?">Rationale</a> 1237 for a more detailed explanation of the reasons for such behavior. 1238 </p></td></tr> 1239</table></div> 1240<p> 1241 Usage example follows: 1242 </p> 1243<pre class="programlisting"><span class="identifier">BOOST_LOG_DECLARE_GLOBAL_LOGGER</span><span class="special">(</span><span class="identifier">my_logger</span><span class="special">,</span> <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger_mt</span><span class="special">)</span> 1244 1245<span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span> 1246<span class="special">{</span> 1247 <span class="comment">// This log record will also be marked with the "Tag" attribute,</span> 1248 <span class="comment">// whenever it is called from the A::bar function.</span> 1249 <span class="comment">// It will not be marked when called from other places.</span> 1250 <span class="identifier">BOOST_LOG</span><span class="special">(</span><span class="identifier">get_my_logger</span><span class="special">())</span> <span class="special"><<</span> <span class="string">"A log message from foo"</span><span class="special">;</span> 1251<span class="special">}</span> 1252 1253<span class="keyword">struct</span> <span class="identifier">A</span> 1254<span class="special">{</span> 1255 <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger</span> <span class="identifier">m_Logger</span><span class="special">;</span> 1256 1257 <span class="keyword">void</span> <span class="identifier">bar</span><span class="special">()</span> 1258 <span class="special">{</span> 1259 <span class="comment">// Set a thread-wide markup tag.</span> 1260 <span class="comment">// Note the additional parentheses to form a Boost.PP sequence.</span> 1261 <span class="identifier">BOOST_LOG_SCOPED_THREAD_ATTR</span><span class="special">(</span><span class="string">"Tag"</span><span class="special">,</span> 1262 <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">constant</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">"Called from A::bar"</span><span class="special">));</span> 1263 1264 <span class="comment">// This log record will be marked</span> 1265 <span class="identifier">BOOST_LOG</span><span class="special">(</span><span class="identifier">m_Logger</span><span class="special">)</span> <span class="special"><<</span> <span class="string">"A log message from A::bar"</span><span class="special">;</span> 1266 1267 <span class="identifier">foo</span><span class="special">();</span> 1268 <span class="special">}</span> 1269<span class="special">};</span> 1270 1271<span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">*[])</span> 1272<span class="special">{</span> 1273 <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger</span> <span class="identifier">lg</span><span class="special">;</span> 1274 1275 <span class="comment">// Let's measure our application run time</span> 1276 <span class="identifier">BOOST_LOG_SCOPED_LOGGER_ATTR</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="string">"RunTime"</span><span class="special">,</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">timer</span><span class="special">());</span> 1277 1278 <span class="comment">// Mark application start.</span> 1279 <span class="comment">// The "RunTime" attribute should be nearly 0 at this point.</span> 1280 <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">"Application started"</span><span class="special">;</span> 1281 1282 <span class="comment">// Note that no other log records are affected by the "RunTime" attribute.</span> 1283 <span class="identifier">foo</span><span class="special">();</span> 1284 1285 <span class="identifier">A</span> <span class="identifier">a</span><span class="special">;</span> 1286 <span class="identifier">a</span><span class="special">.</span><span class="identifier">bar</span><span class="special">();</span> 1287 1288 <span class="comment">// Mark application ending.</span> 1289 <span class="comment">// The "RunTime" attribute will show the execution time elapsed.</span> 1290 <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">"Application ended"</span><span class="special">;</span> 1291 1292 <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> 1293<span class="special">}</span> 1294</pre> 1295<p> 1296 It is quite often convenient to mark a group of log records with a constant 1297 value in order to be able to filter the records later. The library provides 1298 two convenience macros just for this purpose: 1299 </p> 1300<pre class="programlisting"><code class="computeroutput"><a class="link" href="../../BOOST_LO_idm46079579096272.html" title="Macro BOOST_LOG_SCOPED_LOGGER_TAG">BOOST_LOG_SCOPED_LOGGER_TAG</a></code><span class="special">(</span><span class="identifier">logger</span><span class="special">,</span> <span class="identifier">tag_name</span><span class="special">,</span> <span class="identifier">tag_value</span><span class="special">);</span> 1301<code class="computeroutput"><a class="link" href="../../BOOST_LO_idm46079579091904.html" title="Macro BOOST_LOG_SCOPED_THREAD_TAG">BOOST_LOG_SCOPED_THREAD_TAG</a></code><span class="special">(</span><span class="identifier">tag_name</span><span class="special">,</span> <span class="identifier">tag_value</span><span class="special">);</span> 1302</pre> 1303<p> 1304 The macros are effectively wrappers around <code class="computeroutput"><a class="link" href="../../BOOST_LO_idm46079579098656.html" title="Macro BOOST_LOG_SCOPED_LOGGER_ATTR">BOOST_LOG_SCOPED_LOGGER_ATTR</a></code> 1305 and <code class="computeroutput"><a class="link" href="../../BOOST_LO_idm46079579093888.html" title="Macro BOOST_LOG_SCOPED_THREAD_ATTR">BOOST_LOG_SCOPED_THREAD_ATTR</a></code>, 1306 respectively. For example, the "Tag" scoped attribute from 1307 the example above can be registered like this: 1308 </p> 1309<pre class="programlisting"><span class="identifier">BOOST_LOG_SCOPED_THREAD_TAG</span><span class="special">(</span><span class="string">"Tag"</span><span class="special">,</span> <span class="string">"Called from A::bar"</span><span class="special">);</span> 1310</pre> 1311<div class="warning"><table border="0" summary="Warning"> 1312<tr> 1313<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../../doc/src/images/warning.png"></td> 1314<th align="left">Warning</th> 1315</tr> 1316<tr><td align="left" valign="top"><p> 1317 When using scoped attributes, make sure that the scoped attribute is 1318 not altered in the attribute set in which it was registered. For example, 1319 one should not clear or reinstall the attribute set of the logger if 1320 there are logger-specific scoped attributes registered in it. Otherwise 1321 the program will likely crash. This issue is especially critical in 1322 multithreaded application, when one thread may not know whether there 1323 are scoped attributes in the logger or there are not. Future releases 1324 may solve this limitation but currently the scoped attribute must remain 1325 intact until unregistered on leaving the scope. 1326 </p></td></tr> 1327</table></div> 1328<p> 1329 Although the described macros are intended to be the primary interface 1330 for the functionality, there is also a C++ interface available. It may 1331 be useful if the user decides to develop his own macros that cannot be 1332 based on the existing ones. 1333 </p> 1334<p> 1335 Any scoped attribute is attached to a generic sentry object of type 1336 <code class="computeroutput"><span class="identifier">scoped_attribute</span></code>. As 1337 long as the sentry exists, the attribute is registered. There are several 1338 functions that create sentries for source or thread-specific attributes: 1339 </p> 1340<pre class="programlisting"><span class="comment">// Source-specific scoped attribute registration</span> 1341<span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">LoggerT</span> <span class="special">></span> 1342<span class="special">[</span><span class="identifier">unspecified</span><span class="special">]</span> <span class="identifier">add_scoped_logger_attribute</span><span class="special">(</span> 1343 <span class="identifier">LoggerT</span><span class="special">&</span> <span class="identifier">l</span><span class="special">,</span> 1344 <span class="identifier">attribute_name</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">name</span><span class="special">,</span> 1345 <span class="identifier">attribute</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">attr</span><span class="special">);</span> 1346 1347<span class="comment">// Thread-specific scoped attribute registration</span> 1348<span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">CharT</span> <span class="special">></span> 1349<span class="special">[</span><span class="identifier">unspecified</span><span class="special">]</span> <span class="identifier">add_scoped_thread_attribute</span><span class="special">(</span> 1350 <span class="identifier">attribute_name</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">name</span><span class="special">,</span> 1351 <span class="identifier">attribute</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">attr</span><span class="special">);</span> 1352</pre> 1353<p> 1354 An object of the <code class="computeroutput"><span class="identifier">scoped_attribute</span></code> 1355 type is able to attach results of each of these functions on its construction. 1356 For example, <code class="computeroutput"><span class="identifier">BOOST_LOG_SCOPED_LOGGER_ATTR</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="string">"RunTime"</span><span class="special">,</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">timer</span><span class="special">())</span></code> can roughly be expanded to this: 1357 </p> 1358<pre class="programlisting"><span class="identifier">attrs</span><span class="special">::</span><span class="identifier">scoped_attribute</span> <span class="identifier">sentry</span> <span class="special">=</span> 1359 <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">add_scoped_logger_attribute</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="string">"RunTime"</span><span class="special">,</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">timer</span><span class="special">());</span> 1360</pre> 1361</div> 1362</div> 1363</div> 1364<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 1365<td align="left"></td> 1366<td align="right"><div class="copyright-footer">Copyright © 2007-2019 Andrey Semashev<p> 1367 Distributed under the Boost Software License, Version 1.0. (See accompanying 1368 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>). 1369 </p> 1370</div></td> 1371</tr></table> 1372<hr> 1373<div class="spirit-nav"> 1374<a accesskey="p" href="expressions.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="utilities.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> 1375</div> 1376</body> 1377</html> 1378