| <html> |
| <head> |
| <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> |
| <title>Attributes</title> |
| <link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css"> |
| <meta name="generator" content="DocBook XSL Stylesheets V1.78.1"> |
| <link rel="home" href="../../index.html" title="Chapter 1. Boost.Log v2"> |
| <link rel="up" href="../detailed.html" title="Detailed features description"> |
| <link rel="prev" href="expressions.html" title="Lambda expressions"> |
| <link rel="next" href="utilities.html" title="Utilities"> |
| </head> |
| <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> |
| <table cellpadding="2" width="100%"><tr><td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td></tr></table> |
| <hr> |
| <div class="spirit-nav"> |
| <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> |
| </div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h3 class="title"> |
| <a name="log.detailed.attributes"></a><a class="link" href="attributes.html" title="Attributes">Attributes</a> |
| </h3></div></div></div> |
| <div class="toc"><dl class="toc"> |
| <dt><span class="section"><a href="attributes.html#log.detailed.attributes.constant">Constants</a></span></dt> |
| <dt><span class="section"><a href="attributes.html#log.detailed.attributes.mutable_constant">Mutable constants</a></span></dt> |
| <dt><span class="section"><a href="attributes.html#log.detailed.attributes.counter">Counters</a></span></dt> |
| <dt><span class="section"><a href="attributes.html#log.detailed.attributes.clock">Wall clock</a></span></dt> |
| <dt><span class="section"><a href="attributes.html#log.detailed.attributes.timer">Stop watch (timer)</a></span></dt> |
| <dt><span class="section"><a href="attributes.html#log.detailed.attributes.named_scope">Named scopes</a></span></dt> |
| <dt><span class="section"><a href="attributes.html#log.detailed.attributes.process_id">Current process |
| identifier</a></span></dt> |
| <dt><span class="section"><a href="attributes.html#log.detailed.attributes.process_name">Current process |
| name</a></span></dt> |
| <dt><span class="section"><a href="attributes.html#log.detailed.attributes.thread_id">Current thread identifier</a></span></dt> |
| <dt><span class="section"><a href="attributes.html#log.detailed.attributes.function">Function objects |
| as attributes</a></span></dt> |
| <dt><span class="section"><a href="attributes.html#log.detailed.attributes.related_components">Other attribute-related |
| components</a></span></dt> |
| </dl></div> |
| <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> |
| <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> |
| <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> |
| </pre> |
| <p> |
| All attributes in the library are implemented using the <a href="http://c2.com/cgi/wiki?PimplIdiom" target="_top">pimpl |
| idiom</a>, or more specifically - shared pimpl idiom. Every attribute |
| 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> |
| 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>. |
| The interface class only holds a reference counted pointer to the actual |
| 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 |
| classes don't have any data members. When the interface class is default |
| constructed, it creates the corresponding implementation object and initializes |
| the <code class="computeroutput"><a class="link" href="../../boost/log/attribute.html" title="Class attribute">attribute</a></code> base class |
| with a pointer to the implementation. Therefore the pimpl nature of attributes |
| is transparent for users in a typical workflow. |
| </p> |
| <p> |
| The shared pimpl design comes significant in a few cases though. One such |
| case is copying the attribute. The copy operation is shallow, so multiple |
| interface objects may refer to a single implementation object. There is no |
| 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 |
| object that does not refer to an implementation. Attributes in such empty |
| state should not be passed to the library but can be useful in some cases, |
| e.g. when a delayed variable initialization is needed. |
| </p> |
| <p> |
| 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> |
| 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>: |
| </p> |
| <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> |
| <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> |
| </pre> |
| <p> |
| In this example, the cast will succeed (i.e. the <code class="computeroutput"><span class="identifier">const_attr</span></code> |
| will be non-empty) if the attribute <code class="computeroutput"><span class="identifier">attr</span></code> |
| 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 |
| object, no data is lost in the casting process. |
| </p> |
| <p> |
| The main purpose of attributes is to generate attribute values. Values are |
| semantically distinct from the attributes. Such separation allows implementing |
| attributes that can return different values at different time points (like |
| clock-related attributes, for example) and, on the other hand, allows using |
| 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> |
| interface has a method named <code class="computeroutput"><span class="identifier">get_value</span></code> |
| that returns the actual attribute value. Attribute values are also implemented |
| 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> |
| and implementation classes derive from <code class="computeroutput"><a class="link" href="../../boost/log/attribute_value/impl.html" title="Struct impl">impl</a></code>. |
| </p> |
| <p> |
| The attribute value object is mostly intended to store the actual attribute |
| value and implement type dispatching in order to be able to extract the stored |
| value. One should not confuse the attribute value object type and the stored |
| value type. The former is in most cases not needed by users and provides |
| type erasure, but the latter is needed to be able to extract the value. For |
| brevity we call the stored attribute value type simply the attribute value |
| type in this documentation. |
| </p> |
| <div class="section"> |
| <div class="titlepage"><div><div><h4 class="title"> |
| <a name="log.detailed.attributes.constant"></a><a class="link" href="attributes.html#log.detailed.attributes.constant" title="Constants">Constants</a> |
| </h4></div></div></div> |
| <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> |
| </pre> |
| <p> |
| The most simple and frequently used attribute type is a constant value |
| 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. |
| The template is parametrized with the attribute value type. The constant |
| value should be passed to the attribute constructor. Here is an example: |
| </p> |
| <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span> |
| <span class="special">{</span> |
| <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger</span> <span class="identifier">lg</span><span class="special">;</span> |
| |
| <span class="comment">// Register a constant attribute that always yields value -5</span> |
| <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> |
| |
| <span class="comment">// Register another constant attribute. Make it a string this time.</span> |
| <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> |
| |
| <span class="comment">// There is also a convenience generator function. "MyInteger2" is constant< int > here.</span> |
| <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> |
| <span class="special">}</span> |
| </pre> |
| <p> |
| That's it, there's nothing much you can do with a constant attribute. Constants |
| are very useful when one wants to highlight some log records or just pass |
| some data to a sink backend (e.g. pass statistical parameters to the collector). |
| </p> |
| </div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h4 class="title"> |
| <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> |
| </h4></div></div></div> |
| <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> |
| </pre> |
| <p> |
| This kind of attribute is an extension for the <a class="link" href="attributes.html#log.detailed.attributes.constant" title="Constants">constant |
| 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> |
| class template has two distinctions: |
| </p> |
| <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> |
| <li class="listitem"> |
| it allows modification of the stored value without re-registering the |
| attribute |
| </li> |
| <li class="listitem"> |
| it allows synchronization of the stores and reads of the stored value |
| </li> |
| </ul></div> |
| <p> |
| In order to change the stored value of the attribute, one must call the |
| <code class="computeroutput"><span class="identifier">set</span></code> method: |
| </p> |
| <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span> |
| <span class="special">{</span> |
| <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger</span> <span class="identifier">lg</span><span class="special">;</span> |
| |
| <span class="comment">// Register a mutable constant attribute that always yields value -5</span> |
| <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> |
| <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> |
| <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> |
| |
| <span class="comment">// Change the attribute value</span> |
| <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> |
| <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> |
| <span class="special">}</span> |
| </pre> |
| <p> |
| In multithreaded applications the <code class="computeroutput"><span class="identifier">set</span></code> |
| method calls must be serialized with the <code class="computeroutput"><span class="identifier">get_value</span></code> |
| calls (which, generally speaking, happen on every log record being made). |
| By default <code class="computeroutput"><a class="link" href="../../boost/log/attributes/mutable_constant.html" title="Class template mutable_constant">mutable_constant</a></code> |
| does not serialize calls in any way, assuming that the user will do so |
| 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> |
| template provides three additional template arguments: synchronization |
| primitive type, scoped exclusive lock type and scoped shareable lock type. |
| If a synchronization primitive type is specified, the scoped exclusive |
| lock type is a mandatory parameter. If the scoped shareable lock type is |
| not specified, the attribute will fall back to the exclusive lock instead |
| of shared locks. For example: |
| </p> |
| <pre class="programlisting"><span class="comment">// This mutable constant will always lock exclusively</span> |
| <span class="comment">// either for reading or storing the value</span> |
| <span class="keyword">typedef</span> <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="comment">// attribute value type</span> |
| <span class="identifier">boost</span><span class="special">::</span><span class="identifier">mutex</span><span class="special">,</span> <span class="comment">// synchronization primitive</span> |
| <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> |
| <span class="special">></span> <span class="identifier">exclusive_mc</span><span class="special">;</span> |
| <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> |
| |
| <span class="comment">// This mutable constant will use shared clocking for reading the value</span> |
| <span class="comment">// and exclusive locking for storing</span> |
| <span class="keyword">typedef</span> <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="comment">// attribute value type</span> |
| <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> |
| <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> |
| <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> |
| <span class="special">></span> <span class="identifier">shared_mc</span><span class="special">;</span> |
| <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> |
| |
| <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> |
| <span class="special">{</span> |
| <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger_mt</span> <span class="identifier">lg</span><span class="special">;</span> |
| <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> |
| <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> |
| |
| <span class="keyword">return</span> <span class="identifier">lg</span><span class="special">;</span> |
| <span class="special">}</span> |
| |
| <span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span> |
| <span class="special">{</span> |
| <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> |
| |
| <span class="comment">// This is safe, even if executed in multiple threads</span> |
| <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> |
| <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> |
| |
| <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> |
| <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> |
| <span class="special">}</span> |
| </pre> |
| <p> |
| Mutable constants are often used as auxiliary attributes inside loggers |
| to store attributes that may change on some events. As opposed to regular |
| constants, which would require re-registering in case of value modification, |
| mutable constants allow modifying the value in-place. |
| </p> |
| </div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h4 class="title"> |
| <a name="log.detailed.attributes.counter"></a><a class="link" href="attributes.html#log.detailed.attributes.counter" title="Counters">Counters</a> |
| </h4></div></div></div> |
| <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> |
| </pre> |
| <p> |
| Counters are one of the simplest attributes that generate a new value each |
| time requested. Counters are often used to identify log records or to count |
| 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 |
| functionality. This template is parametrized with the counter value type, |
| which should support arithmetic operations, such as <code class="computeroutput"><span class="keyword">operator</span> |
| <span class="special">+</span></code> and <code class="computeroutput"><span class="keyword">operator</span> |
| <span class="special">-</span></code>. The counter attribute allows |
| specification of the initial value and step (which can be negative) on |
| construction. |
| </p> |
| <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> |
| <span class="special">{</span> |
| <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger_mt</span> <span class="identifier">lg</span><span class="special">;</span> |
| |
| <span class="comment">// This counter will count lines, starting from 0</span> |
| <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> |
| |
| <span class="comment">// This counter will count backwards, starting from 100 with step -5</span> |
| <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> |
| |
| <span class="keyword">return</span> <span class="identifier">lg</span><span class="special">;</span> |
| <span class="special">}</span> |
| |
| <span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span> |
| <span class="special">{</span> |
| <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> |
| <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> |
| <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> |
| <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> |
| <span class="special">}</span> |
| </pre> |
| <div class="note"><table border="0" summary="Note"> |
| <tr> |
| <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td> |
| <th align="left">Note</th> |
| </tr> |
| <tr><td align="left" valign="top"><p> |
| 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> |
| attribute will always have ascending or descending counter values in |
| the resulting log. In multithreaded applications counter values acquired |
| 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> |
| for a more detailed explanation on why it can happen. For this reason |
| 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> |
| attribute generates an identifier in an ascending or descending order |
| rather than that it counts log records in either order. |
| </p></td></tr> |
| </table></div> |
| </div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h4 class="title"> |
| <a name="log.detailed.attributes.clock"></a><a class="link" href="attributes.html#log.detailed.attributes.clock" title="Wall clock">Wall clock</a> |
| </h4></div></div></div> |
| <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> |
| </pre> |
| <p> |
| One of the "must-have" features of any logging library is support |
| for attaching a time stamp to every log record. The library provides two |
| attributes for this purpose: <code class="computeroutput"><span class="identifier">utc_clock</span></code> |
| and <code class="computeroutput"><span class="identifier">local_clock</span></code>. The former |
| returns the current UTC time and the latter returns the current local time. |
| In either case the returned time stamp is acquired with the maximum precision |
| 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> |
| (see <a href="http://www.boost.org/doc/libs/release/doc/html/date_time.html" target="_top">Boost.DateTime</a>). |
| The usage is quite straightforward: |
| </p> |
| <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> |
| |
| <span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span> |
| <span class="special">{</span> |
| <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">()-></span><span class="identifier">add_global_attribute</span><span class="special">(</span> |
| <span class="string">"TimeStamp"</span><span class="special">,</span> |
| <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">local_clock</span><span class="special">());</span> |
| |
| <span class="comment">// Now every log record ever made will have a time stamp attached</span> |
| <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> |
| <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> |
| <span class="special">}</span> |
| </pre> |
| </div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h4 class="title"> |
| <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> |
| </h4></div></div></div> |
| <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> |
| </pre> |
| <p> |
| The <code class="computeroutput"><a class="link" href="../../boost/log/attributes/timer.html" title="Class timer">timer</a></code> attribute |
| is very useful when there is a need to estimate the duration of some prolonged |
| process. The attribute returns the time elapsed since the attribute construction. |
| 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> |
| (see <a href="http://www.boost.org/doc/libs/release/doc/html/date_time.html" target="_top">Boost.DateTime</a>). |
| </p> |
| <pre class="programlisting"><span class="comment">// The class represents a single peer-to-peer connection</span> |
| <span class="keyword">class</span> <span class="identifier">network_connection</span> |
| <span class="special">{</span> |
| <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger</span> <span class="identifier">m_logger</span><span class="special">;</span> |
| |
| <span class="keyword">public</span><span class="special">:</span> |
| <span class="identifier">network_connection</span><span class="special">()</span> |
| <span class="special">{</span> |
| <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> |
| <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> |
| <span class="special">}</span> |
| <span class="special">~</span><span class="identifier">network_connection</span><span class="special">()</span> |
| <span class="special">{</span> |
| <span class="comment">// This log record will show the whole life time duration of the connection</span> |
| <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> |
| <span class="special">}</span> |
| <span class="special">};</span> |
| </pre> |
| <p> |
| The attribute provides high resolution of the time estimation and can even |
| be used as a simple in-place performance profiling tool. |
| </p> |
| <div class="tip"><table border="0" summary="Tip"> |
| <tr> |
| <td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td> |
| <th align="left">Tip</th> |
| </tr> |
| <tr><td align="left" valign="top"><p> |
| The <code class="computeroutput"><a class="link" href="../../boost/log/attributes/timer.html" title="Class timer">timer</a></code> |
| attribute can even be used to profile the code in different modules without |
| recompiling them. The trick is to wrap an expensive call to a foreign |
| module with the thread-specific <code class="computeroutput"><a class="link" href="../../boost/log/attributes/timer.html" title="Class timer">timer</a></code> |
| <a class="link" href="attributes.html#log.detailed.attributes.related_components.scoped_attributes" title="Scoped attributes">scoped |
| attribute</a>, which will markup all log records made from within |
| the module with time readings. |
| </p></td></tr> |
| </table></div> |
| </div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h4 class="title"> |
| <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> |
| </h4></div></div></div> |
| <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> |
| |
| <span class="comment">// Supporting headers</span> |
| <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> |
| </pre> |
| <p> |
| The logging library supports maintaining scope stack tracking during the |
| application's execution. This stack may either be written to log or be |
| used for other needs (for example, to save the exact call sequence that |
| led to an exception when throwing one). Each stack element contains the |
| 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> |
| structure template definition): |
| </p> |
| <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> |
| <li class="listitem"> |
| Scope name. It can be defined by the user or generated by the compiler, |
| but in any case it <span class="underline">must be a constant string |
| literal</span> (see <a class="link" href="../rationale.html#log.rationale.why_str_lit" title="Why string literals as scope names?">Rationale</a>). |
| </li> |
| <li class="listitem"> |
| Source file name, where the scope begins. It is usually a result of |
| the standard <code class="computeroutput"><span class="identifier">__FILE__</span></code> |
| macro expansion. Like the scope name, the file name <span class="underline">must |
| be a constant string literal</span>. |
| </li> |
| <li class="listitem"> |
| Line number in the source file. Usually it is a result of the standard |
| <code class="computeroutput"><span class="identifier">__LINE__</span></code> macro expansion. |
| </li> |
| </ul></div> |
| <p> |
| The scope stack is implemented as a thread-specific global storage internally. |
| There is the <code class="computeroutput"><a class="link" href="../../boost/log/attributes/named_scope.html" title="Class named_scope">named_scope</a></code> |
| attribute that allows hooking this stack into the logging pipeline. This |
| 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> |
| which is the instance of the scope stack. The attribute can be registered |
| in the following way: |
| </p> |
| <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> |
| </pre> |
| <p> |
| Note that it is perfectly valid to register the attribute globally because |
| the scope stack is thread-local anyway. This will also implicitly add scope |
| tracking to all threads of the application, which is often exactly what |
| is needed. |
| </p> |
| <p> |
| Now we can mark execution scopes with the macros <code class="computeroutput"><span class="identifier">BOOST_LOG_FUNCTION</span></code> |
| and <code class="computeroutput"><span class="identifier">BOOST_LOG_NAMED_SCOPE</span></code> |
| (the latter accepts the scope name as its argument). These macros automatically |
| add source position information to each scope entry. An example follows: |
| </p> |
| <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> |
| <span class="special">{</span> |
| <span class="comment">// Mark the scope of the function foo</span> |
| <span class="identifier">BOOST_LOG_FUNCTION</span><span class="special">();</span> |
| |
| <span class="keyword">switch</span> <span class="special">(</span><span class="identifier">n</span><span class="special">)</span> |
| <span class="special">{</span> |
| <span class="keyword">case</span> <span class="number">0</span><span class="special">:</span> |
| <span class="special">{</span> |
| <span class="comment">// Mark the current scope</span> |
| <span class="identifier">BOOST_LOG_NAMED_SCOPE</span><span class="special">(</span><span class="string">"case 0"</span><span class="special">);</span> |
| <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> |
| <span class="identifier">bar</span><span class="special">();</span> <span class="comment">// call some function</span> |
| <span class="special">}</span> |
| <span class="keyword">break</span><span class="special">;</span> |
| |
| <span class="keyword">case</span> <span class="number">1</span><span class="special">:</span> |
| <span class="special">{</span> |
| <span class="comment">// Mark the current scope</span> |
| <span class="identifier">BOOST_LOG_NAMED_SCOPE</span><span class="special">(</span><span class="string">"case 1"</span><span class="special">);</span> |
| <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> |
| <span class="identifier">bar</span><span class="special">();</span> <span class="comment">// call some function</span> |
| <span class="special">}</span> |
| <span class="keyword">break</span><span class="special">;</span> |
| |
| <span class="keyword">default</span><span class="special">:</span> |
| <span class="special">{</span> |
| <span class="comment">// Mark the current scope</span> |
| <span class="identifier">BOOST_LOG_NAMED_SCOPE</span><span class="special">(</span><span class="string">"default"</span><span class="special">);</span> |
| <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> |
| <span class="identifier">bar</span><span class="special">();</span> <span class="comment">// call some function</span> |
| <span class="special">}</span> |
| <span class="keyword">break</span><span class="special">;</span> |
| <span class="special">}</span> |
| <span class="special">}</span> |
| </pre> |
| <p> |
| After executing <code class="computeroutput"><span class="identifier">foo</span></code> we |
| will be able to see in the log that the <code class="computeroutput"><span class="identifier">bar</span></code> |
| function was called from <code class="computeroutput"><span class="identifier">foo</span></code> |
| and, more precisely, from the case statement that corresponds to the value |
| of <code class="computeroutput"><span class="identifier">n</span></code>. This may be very |
| 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 |
| (e.g. if <code class="computeroutput"><span class="identifier">bar</span></code> is being passed |
| invalid arguments in that particular location). |
| </p> |
| <div class="note"><table border="0" summary="Note"> |
| <tr> |
| <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td> |
| <th align="left">Note</th> |
| </tr> |
| <tr><td align="left" valign="top"><p> |
| The <code class="computeroutput"><span class="identifier">BOOST_LOG_FUNCTION</span></code> |
| macro uses compiler-specific extensions to generate the scope name from |
| the enclosing function. C++11 defines a standard macro <code class="computeroutput"><span class="identifier">__func__</span></code> for this purpose, but it is |
| not universally supported. Additionally, format of the string is not |
| standardized and may vary from one compiler to another. For this reason |
| it is generally advised to use <code class="computeroutput"><span class="identifier">BOOST_LOG_NAMED_SCOPE</span></code> |
| instead of <code class="computeroutput"><span class="identifier">BOOST_LOG_FUNCTION</span></code> |
| to ensure consistent and portable behavior. |
| </p></td></tr> |
| </table></div> |
| <p> |
| Another good use case is attaching the scope stack information to an exception. |
| With the help of <a href="http://www.boost.org/doc/libs/release/libs/exception/doc/boost-exception.html" target="_top">Boost.Exception</a>, |
| this is possible: |
| </p> |
| <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> |
| <span class="special">{</span> |
| <span class="identifier">BOOST_LOG_FUNCTION</span><span class="special">();</span> |
| |
| <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> |
| <span class="special">{</span> |
| <span class="comment">// Attach a copy of the current scope stack to the exception</span> |
| <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> |
| <span class="special"><<</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">current_scope</span><span class="special">();</span> |
| <span class="special">}</span> |
| <span class="special">}</span> |
| |
| <span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span> |
| <span class="special">{</span> |
| <span class="identifier">BOOST_LOG_FUNCTION</span><span class="special">();</span> |
| |
| <span class="keyword">try</span> |
| <span class="special">{</span> |
| <span class="identifier">bar</span><span class="special">(-</span><span class="number">1</span><span class="special">);</span> |
| <span class="special">}</span> |
| <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> |
| <span class="special">{</span> |
| <span class="comment">// Acquire the scope stack from the exception object</span> |
| <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> |
| <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> |
| <span class="special">}</span> |
| <span class="special">}</span> |
| </pre> |
| <div class="note"><table border="0" summary="Note"> |
| <tr> |
| <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td> |
| <th align="left">Note</th> |
| </tr> |
| <tr><td align="left" valign="top"><p> |
| 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> |
| support header has to be included. |
| </p></td></tr> |
| </table></div> |
| <div class="note"><table border="0" summary="Note"> |
| <tr> |
| <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td> |
| <th align="left">Note</th> |
| </tr> |
| <tr><td align="left" valign="top"><p> |
| 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> |
| attribute into the exception. Since scope stacks are maintained globally, |
| throwing an exception will cause stack unwinding and, as a result, will |
| truncate the global stack. Instead we create a copy of the scope stack |
| by calling <code class="computeroutput"><a class="link" href="../../boost/log/current_scope.html" title="Function current_scope">current_scope</a></code> at the |
| throw site. This copy will be kept intact even if the global stack instance |
| changes during the stack unwinding. |
| </p></td></tr> |
| </table></div> |
| </div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h4 class="title"> |
| <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 |
| identifier</a> |
| </h4></div></div></div> |
| <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> |
| </pre> |
| <p> |
| It is often useful to know the process identifier that produces the log, |
| especially if the log can eventually combine the output of different processes. |
| 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> |
| attribute is a constant that formats into the current process identifier. |
| 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. |
| </p> |
| <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span> |
| <span class="special">{</span> |
| <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">()-></span><span class="identifier">add_global_attribute</span><span class="special">(</span> |
| <span class="string">"ProcessID"</span><span class="special">,</span> |
| <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">current_process_id</span><span class="special">());</span> |
| <span class="special">}</span> |
| </pre> |
| </div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h4 class="title"> |
| <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 |
| name</a> |
| </h4></div></div></div> |
| <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> |
| </pre> |
| <p> |
| 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> |
| produces <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> values with the executable name |
| of the current process. |
| </p> |
| <div class="note"><table border="0" summary="Note"> |
| <tr> |
| <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td> |
| <th align="left">Note</th> |
| </tr> |
| <tr><td align="left" valign="top"><p> |
| This attribute is not universally portable, although Windows, Linux and |
| OS X are supported. The attribute may work on other POSIX systems as |
| well, but it was not tested. If the process name cannot be obtained the |
| attribute will generate a string with the process id. |
| </p></td></tr> |
| </table></div> |
| <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span> |
| <span class="special">{</span> |
| <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">()-></span><span class="identifier">add_global_attribute</span><span class="special">(</span> |
| <span class="string">"Process"</span><span class="special">,</span> |
| <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">current_process_name</span><span class="special">());</span> |
| <span class="special">}</span> |
| </pre> |
| </div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h4 class="title"> |
| <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> |
| </h4></div></div></div> |
| <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> |
| </pre> |
| <p> |
| 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> |
| 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>. |
| The attribute will generate values specific to the calling thread. The |
| usage is similar to the process id. |
| </p> |
| <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span> |
| <span class="special">{</span> |
| <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">()-></span><span class="identifier">add_global_attribute</span><span class="special">(</span> |
| <span class="string">"ThreadID"</span><span class="special">,</span> |
| <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">current_thread_id</span><span class="special">());</span> |
| <span class="special">}</span> |
| </pre> |
| <div class="tip"><table border="0" summary="Tip"> |
| <tr> |
| <td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td> |
| <th align="left">Tip</th> |
| </tr> |
| <tr><td align="left" valign="top"><p> |
| You may have noticed that the attribute is registered globally. This |
| will not result in all threads having the same ThreadID in log records |
| as the attribute will always return a thread-specific value. The additional |
| benefit is that you don't have to do a thing in the thread initialization |
| routines to have the thread-specific attribute value in log records. |
| </p></td></tr> |
| </table></div> |
| </div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h4 class="title"> |
| <a name="log.detailed.attributes.function"></a><a class="link" href="attributes.html#log.detailed.attributes.function" title="Function objects as attributes">Function objects |
| as attributes</a> |
| </h4></div></div></div> |
| <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> |
| </pre> |
| <p> |
| This attribute is a simple wrapper around a user-defined function object. |
| Each attempt to acquire the attribute value results in the function object |
| call. The result of the call is returned as the attribute value (this implies |
| that the function must not return <code class="computeroutput"><span class="keyword">void</span></code>). |
| The function object attribute can be constructed with the <code class="computeroutput"><span class="identifier">make_function</span></code> helper function, like this: |
| </p> |
| <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span> |
| <span class="special">{</span> |
| <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">()-></span><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> |
| <span class="special">}</span> |
| </pre> |
| <p> |
| 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> |
| or STL, are also supported. |
| </p> |
| <div class="note"><table border="0" summary="Note"> |
| <tr> |
| <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td> |
| <th align="left">Note</th> |
| </tr> |
| <tr><td align="left" valign="top"><p> |
| Some deficient compilers may not support <code class="computeroutput"><span class="identifier">result_of</span></code> |
| construct properly. This metafunction is used in the <code class="computeroutput"><span class="identifier">make_function</span></code> |
| function to automatically detect the return type of the function object. |
| If <code class="computeroutput"><span class="identifier">result_of</span></code> breaks or |
| detects incorrect type, one can try to explicitly specify the return |
| type of the function object as a template argument to the <code class="computeroutput"><span class="identifier">make_function</span></code> function. |
| </p></td></tr> |
| </table></div> |
| </div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h4 class="title"> |
| <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 |
| components</a> |
| </h4></div></div></div> |
| <div class="toc"><dl class="toc"> |
| <dt><span class="section"><a href="attributes.html#log.detailed.attributes.related_components.attribute_name">Attribute |
| names</a></span></dt> |
| <dt><span class="section"><a href="attributes.html#log.detailed.attributes.related_components.attribute_set">Attribute |
| set</a></span></dt> |
| <dt><span class="section"><a href="attributes.html#log.detailed.attributes.related_components.attribute_value_set">Attribute |
| value set</a></span></dt> |
| <dt><span class="section"><a href="attributes.html#log.detailed.attributes.related_components.value_processing">Attribute |
| value extraction and visitation</a></span></dt> |
| <dt><span class="section"><a href="attributes.html#log.detailed.attributes.related_components.scoped_attributes">Scoped |
| attributes</a></span></dt> |
| </dl></div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h5 class="title"> |
| <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 |
| names</a> |
| </h5></div></div></div> |
| <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> |
| </pre> |
| <p> |
| 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> |
| objects which are used as keys in associative containers of attributes |
| 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> |
| object can be created from a string, so most of the time its use is transparent. |
| </p> |
| <p> |
| 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> |
| object. Instead, a process-wide unique identifier is generated and associated |
| with the particular name. This association is preserved until the process |
| 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> |
| object is created for the same name it obtains the same identifier. The |
| association is not stable across the different runs of the application |
| though. |
| </p> |
| <div class="warning"><table border="0" summary="Warning"> |
| <tr> |
| <td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../../doc/src/images/warning.png"></td> |
| <th align="left">Warning</th> |
| </tr> |
| <tr><td align="left" valign="top"><p> |
| Since the association between string names and identifiers involves |
| some state allocation, it is not advised to use externally provided |
| or known to be changing strings for attribute names. Even if the name |
| is not used in any log records, the association is preserved anyway. |
| Continuously constructing <code class="computeroutput"><a class="link" href="../../boost/log/attribute_name.html" title="Class attribute_name">attribute_name</a></code> |
| objects with unique string names may manifest itself as a memory leak. |
| </p></td></tr> |
| </table></div> |
| <p> |
| Working with identifiers is much more efficient than with strings. For |
| example, copying does not involve dynamic memory allocation and comparison |
| operators are very lightweight. On the other hand, it is easy to get |
| a human-readable attribute name for presentation, if needed. |
| </p> |
| <p> |
| The <code class="computeroutput"><a class="link" href="../../boost/log/attribute_name.html" title="Class attribute_name">attribute_name</a></code> |
| class supports an empty (uninitialized) state when default constructed. |
| In this state the name object is not equal to any other initialized name |
| object. Uninitialized attribute names should not be passed to the library |
| but can be useful in some contexts (e.g. when a delayed initialization |
| is desired). |
| </p> |
| </div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h5 class="title"> |
| <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 |
| set</a> |
| </h5></div></div></div> |
| <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> |
| </pre> |
| <p> |
| 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 |
| names</a> to <a class="link" href="attributes.html" title="Attributes">attributes</a>. |
| It is used in <a class="link" href="sources.html" title="Logging sources">loggers</a> and |
| the <a class="link" href="../detailed.html#log.detailed.core.core" title="Logging core">logging core</a> to store |
| source-specific, thread-specific and global attributes. The interface |
| is very similar to STL associative containers and is described in the |
| <code class="computeroutput"><a class="link" href="../../boost/log/attribute_set.html" title="Class attribute_set">attribute_set</a></code> |
| class reference. |
| </p> |
| </div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h5 class="title"> |
| <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 |
| value set</a> |
| </h5></div></div></div> |
| <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> |
| </pre> |
| <p> |
| Attribute value 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 |
| names</a> to <a class="link" href="attributes.html" title="Attributes">attribute values</a>. |
| This container is used in log <a class="link" href="../detailed.html#log.detailed.core.record" title="Logging records">records</a> |
| 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> |
| does not support removing or modifying elements after being inserted. |
| This warrants that the attribute values that participated filtering will |
| not disappear from the log record in the middle of the processing. |
| </p> |
| <p> |
| 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 |
| sets</a>, which are interpreted as the sets of source-specific, thread-specific |
| and global attributes. The constructor adopts attribute values from the |
| three attribute sets into a single set of attribute values. After construction, |
| <code class="computeroutput"><a class="link" href="../../boost/log/attribute_value_set.html" title="Class attribute_value_set">attribute_value_set</a></code> |
| is considered to be in an unfrozen state. This means that the container |
| may keep references to the elements of the attribute sets used as the |
| source for the value set construction. While in this state, neither the |
| attribute sets nor the value set must not be modified in any way as this |
| may make the value set corrupted. The value set can be used for reading |
| in this state, its lookup operations will perform as usual. The value |
| set can be frozen by calling the <code class="computeroutput"><span class="identifier">freeze</span></code> |
| method; the set will no longer be attached to the original attribute |
| sets and will be available for further insertions after this call. The |
| library will ensure that the value set is always frozen when a log record |
| is returned from the logging core; the set is <span class="underline">not</span> |
| frozen during filtering though. |
| </p> |
| <div class="tip"><table border="0" summary="Tip"> |
| <tr> |
| <td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td> |
| <th align="left">Tip</th> |
| </tr> |
| <tr><td align="left" valign="top"><p> |
| In the unfrozen state the value set may not have all attribute values |
| acquired from the attributes. It will only acquire the values as requested |
| by filters. After freezing the container has all attribute values. |
| This transition allows to optimize the library so that attribute values |
| are only acquired when needed. |
| </p></td></tr> |
| </table></div> |
| <p> |
| 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> |
| reference. |
| </p> |
| </div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h5 class="title"> |
| <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 |
| value extraction and visitation</a> |
| </h5></div></div></div> |
| <p> |
| Since attribute values do not expose the stored value in the interface, |
| an API is needed to acquire the stored value. The library provides two |
| APIs for this purpose: value visitation and extraction. |
| </p> |
| <div class="section"> |
| <div class="titlepage"><div><div><h6 class="title"> |
| <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 |
| visitation</a> |
| </h6></div></div></div> |
| <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> |
| <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> |
| </pre> |
| <p> |
| Attribute value visitation implements the visitor design pattern, hence |
| the naming. The user has to provide a unary function object (a visitor) |
| which will be invoked on the stored attribute value. The caller also |
| has to provide the expected type or set of possible types of the stored |
| value. Obviously, the visitor must be capable of receiving an argument |
| of the expected type. Visitation will only succeed if the stored type |
| matches the expectation. |
| </p> |
| <p> |
| In order to apply the visitor, one should call the <code class="computeroutput"><a class="link" href="../../boost/log/visit_idp42540128.html" title="Function template visit">visit</a></code> function on |
| the attribute value. Let's see an example: |
| </p> |
| <p> |
| </p> |
| <pre class="programlisting"><span class="comment">// Our attribute value visitor</span> |
| <span class="keyword">struct</span> <span class="identifier">print_visitor</span> |
| <span class="special">{</span> |
| <span class="keyword">typedef</span> <span class="keyword">void</span> <span class="identifier">result_type</span><span class="special">;</span> |
| |
| <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> |
| <span class="special">{</span> |
| <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> |
| <span class="special">}</span> |
| |
| <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> |
| <span class="special">{</span> |
| <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> |
| <span class="special">}</span> |
| <span class="special">};</span> |
| |
| <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> |
| <span class="special">{</span> |
| <span class="comment">// Define the set of expected types of the stored value</span> |
| <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> |
| |
| <span class="comment">// Apply our visitor</span> |
| <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> |
| |
| <span class="comment">// Check the result</span> |
| <span class="keyword">if</span> <span class="special">(</span><span class="identifier">result</span><span class="special">)</span> |
| <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> |
| <span class="keyword">else</span> |
| <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> |
| <span class="special">}</span> |
| </pre> |
| <p> |
| </p> |
| <p> |
| <a href="../../../../../../libs/log/example/doc/attr_value_visitation.cpp" target="_top">See |
| the complete code</a>. |
| </p> |
| <p> |
| 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 |
| value to have either <code class="computeroutput"><span class="keyword">int</span></code> |
| or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> stored type; only in this |
| case the visitor will be invoked and the visitation result will be |
| 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> |
| class provides additional information on the failure reason. The class |
| has the method named <code class="computeroutput"><span class="identifier">code</span></code> |
| which returns visitation error code. The following error codes are |
| possible: |
| </p> |
| <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> |
| <li class="listitem"> |
| <code class="computeroutput"><span class="identifier">ok</span></code> - visitation |
| succeeded, the visitor has been invoked; visitation result is positive |
| when this code is used |
| </li> |
| <li class="listitem"> |
| <code class="computeroutput"><span class="identifier">value_not_found</span></code> |
| - visitation failed because the requested value was not found; |
| this code is used when visitation is applied to a log record or |
| a set of attribute values rather than a single value |
| </li> |
| <li class="listitem"> |
| <code class="computeroutput"><span class="identifier">value_has_invalid_type</span></code> |
| - visitation failed because the value has type differing from any |
| of the expected types |
| </li> |
| </ul></div> |
| <p> |
| By default the visitor function result is ignored but it is possible |
| 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 |
| for the visitor; the wrapper will save the visitor resulting value |
| into an external variable captured by reference. The visitor result |
| 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> |
| is positive. See the following example where we compute the hash value |
| on the stored value. |
| </p> |
| <p> |
| </p> |
| <pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">hash_visitor</span> |
| <span class="special">{</span> |
| <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> |
| |
| <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> |
| <span class="special">{</span> |
| <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> |
| <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> |
| <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> |
| <span class="keyword">return</span> <span class="identifier">h</span><span class="special">;</span> |
| <span class="special">}</span> |
| |
| <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> |
| <span class="special">{</span> |
| <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> |
| <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> |
| <span class="identifier">h</span> <span class="special">+=</span> <span class="special">*</span><span class="identifier">it</span><span class="special">;</span> |
| |
| <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> |
| <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> |
| <span class="keyword">return</span> <span class="identifier">h</span><span class="special">;</span> |
| <span class="special">}</span> |
| <span class="special">};</span> |
| |
| <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> |
| <span class="special">{</span> |
| <span class="comment">// Define the set of expected types of the stored value</span> |
| <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> |
| |
| <span class="comment">// Apply our visitor</span> |
| <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> |
| <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> |
| |
| <span class="comment">// Check the result</span> |
| <span class="keyword">if</span> <span class="special">(</span><span class="identifier">result</span><span class="special">)</span> |
| <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> |
| <span class="keyword">else</span> |
| <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> |
| <span class="special">}</span> |
| </pre> |
| <p> |
| </p> |
| <p> |
| <a href="../../../../../../libs/log/example/doc/attr_value_visitation.cpp" target="_top">See |
| the complete code</a>. |
| </p> |
| <div class="tip"><table border="0" summary="Tip"> |
| <tr> |
| <td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td> |
| <th align="left">Tip</th> |
| </tr> |
| <tr><td align="left" valign="top"><p> |
| When there is no default state for the visitor result it is convenient |
| to use <a href="http://www.boost.org/doc/libs/release/libs/optional/index.html" target="_top">Boost.Optional</a> |
| to wrap the returned value. The <code class="computeroutput"><span class="identifier">optional</span></code> |
| will be initialized with the visitor result if visitation succeeded. |
| In case if visitor is polymorphic (i.e. it has different result types |
| depending on its argument type) <a href="http://www.boost.org/doc/libs/release/doc/html/variant.html" target="_top">Boost.Variant</a> |
| can be used to receive the resulting value. It is also worthwhile |
| 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>, |
| to indicate the uninitialized state of the <code class="computeroutput"><span class="identifier">variant</span></code>. |
| </p></td></tr> |
| </table></div> |
| <p> |
| As it has been mentioned, visitation can also be applied to log records |
| and attribute value sets. The syntax is the same, except that the attribute |
| name also has to be specified. The <code class="computeroutput"><a class="link" href="../../boost/log/visit_idp42540128.html" title="Function template visit">visit</a></code> algorithm will |
| try to find the attribute value by name and then apply the visitor |
| to the found element. |
| </p> |
| <p> |
| </p> |
| <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> |
| <span class="special">{</span> |
| <span class="comment">// Define the set of expected types of the stored value</span> |
| <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> |
| |
| <span class="comment">// Apply our visitor</span> |
| <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> |
| <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> |
| |
| <span class="comment">// Check the result</span> |
| <span class="keyword">if</span> <span class="special">(</span><span class="identifier">result</span><span class="special">)</span> |
| <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> |
| <span class="keyword">else</span> |
| <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> |
| <span class="special">}</span> |
| </pre> |
| <p> |
| </p> |
| <p> |
| Also, for convenience <code class="computeroutput"><a class="link" href="../../boost/log/attribute_value.html" title="Class attribute_value">attribute_value</a></code> |
| has the method named <code class="computeroutput"><span class="identifier">visit</span></code> |
| with the same meaning as the free function applied to the attribute |
| value. |
| </p> |
| </div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h6 class="title"> |
| <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 |
| extraction</a> |
| </h6></div></div></div> |
| <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> |
| <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> |
| </pre> |
| <p> |
| Attribute value extraction API allows to acquire a reference to the |
| stored value. It does not require a visitor function object, but the |
| user still has to provide the expected type or a set of types the stored |
| value may have. |
| </p> |
| <p> |
| </p> |
| <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> |
| <span class="special">{</span> |
| <span class="comment">// Extract a reference to the stored value</span> |
| <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> |
| |
| <span class="comment">// Check the result</span> |
| <span class="keyword">if</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">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> |
| <span class="keyword">else</span> |
| <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> |
| <span class="special">}</span> |
| </pre> |
| <p> |
| </p> |
| <p> |
| <a href="../../../../../../libs/log/example/doc/attr_value_extraction.cpp" target="_top">See |
| the complete code</a>. |
| </p> |
| <p> |
| In this example we expect the attribute value to have the stored type |
| <code class="computeroutput"><span class="keyword">int</span></code>. The <code class="computeroutput"><a class="link" href="../../boost/log/extract_idp42351392.html" title="Function template extract">extract</a></code> |
| function attempts to extract a reference to the stored value and returns |
| 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. |
| </p> |
| <p> |
| Value extraction can also be used with a set of expected stored types. |
| The following code snippet demonstrates this: |
| </p> |
| <p> |
| </p> |
| <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> |
| <span class="special">{</span> |
| <span class="comment">// Define the set of expected types of the stored value</span> |
| <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> |
| |
| <span class="comment">// Extract a reference to the stored value</span> |
| <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> |
| |
| <span class="comment">// Check the result</span> |
| <span class="keyword">if</span> <span class="special">(</span><span class="identifier">val</span><span class="special">)</span> |
| <span class="special">{</span> |
| <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> |
| <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> |
| <span class="special">{</span> |
| <span class="keyword">case</span> <span class="number">0</span><span class="special">:</span> |
| <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> |
| <span class="keyword">break</span><span class="special">;</span> |
| |
| <span class="keyword">case</span> <span class="number">1</span><span class="special">:</span> |
| <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> |
| <span class="keyword">break</span><span class="special">;</span> |
| <span class="special">}</span> |
| <span class="special">}</span> |
| <span class="keyword">else</span> |
| <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> |
| <span class="special">}</span> |
| </pre> |
| <p> |
| </p> |
| <p> |
| Notice that we used <code class="computeroutput"><span class="identifier">which</span></code> |
| method of the returned reference to dispatch between possible types. |
| The method returns the index of the type in the <code class="computeroutput"><span class="identifier">types</span></code> |
| sequence. Also note that the <code class="computeroutput"><span class="identifier">get</span></code> |
| method now accepts an explicit template parameter to select the reference |
| type to acquire; naturally, this type must correspond to the actual |
| referred type, which is warranted by the switch/case statement in our |
| case. |
| </p> |
| <p> |
| 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 |
| how we compute a hash value from the extracted value: |
| </p> |
| <p> |
| </p> |
| <pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">hash_visitor</span> |
| <span class="special">{</span> |
| <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> |
| |
| <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> |
| <span class="special">{</span> |
| <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> |
| <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> |
| <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> |
| <span class="keyword">return</span> <span class="identifier">h</span><span class="special">;</span> |
| <span class="special">}</span> |
| |
| <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> |
| <span class="special">{</span> |
| <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> |
| <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> |
| <span class="identifier">h</span> <span class="special">+=</span> <span class="special">*</span><span class="identifier">it</span><span class="special">;</span> |
| |
| <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> |
| <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> |
| <span class="keyword">return</span> <span class="identifier">h</span><span class="special">;</span> |
| <span class="special">}</span> |
| <span class="special">};</span> |
| |
| <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> |
| <span class="special">{</span> |
| <span class="comment">// Define the set of expected types of the stored value</span> |
| <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> |
| |
| <span class="comment">// Extract the stored value</span> |
| <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> |
| |
| <span class="comment">// Check the result</span> |
| <span class="keyword">if</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">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> |
| <span class="keyword">else</span> |
| <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> |
| <span class="special">}</span> |
| </pre> |
| <p> |
| </p> |
| <p> |
| Lastly, like with value visitation, value extraction can also be applied |
| to log records and attribute value sets. |
| </p> |
| <p> |
| </p> |
| <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> |
| <span class="special">{</span> |
| <span class="comment">// Define the set of expected types of the stored value</span> |
| <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> |
| |
| <span class="comment">// Extract the stored value</span> |
| <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> |
| |
| <span class="comment">// Check the result</span> |
| <span class="keyword">if</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">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> |
| <span class="keyword">else</span> |
| <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> |
| <span class="special">}</span> |
| </pre> |
| <p> |
| </p> |
| <p> |
| In addition the library provides two special variants of the <code class="computeroutput"><a class="link" href="../../boost/log/extract_idp42351392.html" title="Function template extract">extract</a></code> |
| function: <code class="computeroutput"><a class="link" href="../../boost/log/extract_or_thr_idp42379312.html" title="Function template extract_or_throw">extract_or_throw</a></code> and |
| <code class="computeroutput"><a class="link" href="../../boost/log/extract_or_def_idp42410176.html" title="Function template extract_or_default">extract_or_default</a></code>. |
| As the naming implies, the functions provide different behavior in |
| case if the attribute value cannot be extracted. The former one throws |
| an exception if the value cannot be extracted and the latter one returns |
| the default value. |
| </p> |
| <div class="warning"><table border="0" summary="Warning"> |
| <tr> |
| <td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../../doc/src/images/warning.png"></td> |
| <th align="left">Warning</th> |
| </tr> |
| <tr><td align="left" valign="top"><p> |
| Care must be taken with the <code class="computeroutput"><a class="link" href="../../boost/log/extract_or_def_idp42410176.html" title="Function template extract_or_default">extract_or_default</a></code> |
| function. The function accepts the default value is accepted by constant |
| reference, and this reference can eventually be returned from <code class="computeroutput"><a class="link" href="../../boost/log/extract_or_def_idp42410176.html" title="Function template extract_or_default">extract_or_default</a></code>. |
| If a temporary object as used for the default value, user must ensure |
| that the result of <code class="computeroutput"><a class="link" href="../../boost/log/extract_or_def_idp42410176.html" title="Function template extract_or_default">extract_or_default</a></code> |
| is saved by value and not by reference. Otherwise the saved reference |
| may become dangling when the temporary is destroyed. |
| </p></td></tr> |
| </table></div> |
| <p> |
| Similarly to <code class="computeroutput"><span class="identifier">visit</span></code>, |
| the <code class="computeroutput"><a class="link" href="../../boost/log/attribute_value.html" title="Class attribute_value">attribute_value</a></code> |
| class has methods named <code class="computeroutput"><span class="identifier">extract</span></code>, |
| <code class="computeroutput"><span class="identifier">extract_or_throw</span></code> and |
| <code class="computeroutput"><span class="identifier">extract_or_default</span></code> |
| with the same meaning as the corresponding free functions applied to |
| the attribute value. |
| </p> |
| </div> |
| </div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h5 class="title"> |
| <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 |
| attributes</a> |
| </h5></div></div></div> |
| <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> |
| </pre> |
| <p> |
| Scoped attributes are a powerful mechanism of tagging log records that |
| can be used for different purposes. As the naming implies, scoped attributes |
| are registered in the beginning of a scope and unregistered on the end |
| of the scope. The mechanism includes the following macros: |
| </p> |
| <pre class="programlisting"><code class="computeroutput"><a class="link" href="../../BOOST_LOG_SCOPED_LOGGER_ATTR.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> |
| <code class="computeroutput"><a class="link" href="../../BOOST_LOG_SCOPED_THREAD_ATTR.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> |
| </pre> |
| <p> |
| The first macro registers a source-specific attribute in the <code class="computeroutput"><span class="identifier">logger</span></code> logger object. The attribute |
| name and the attribute itself are given in the <code class="computeroutput"><span class="identifier">attr_name</span></code> |
| and <code class="computeroutput"><span class="identifier">attr</span></code> arguments. The |
| second macro does exactly the same but the attribute is registered for |
| the current thread in the logging core (which does not require a logger). |
| </p> |
| <div class="note"><table border="0" summary="Note"> |
| <tr> |
| <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td> |
| <th align="left">Note</th> |
| </tr> |
| <tr><td align="left" valign="top"><p> |
| If an attribute with the same name is already registered in the logger/logging |
| core, the macros won't override the existing attribute and will eventually |
| 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> |
| for a more detailed explanation of the reasons for such behavior. |
| </p></td></tr> |
| </table></div> |
| <p> |
| Usage example follows: |
| </p> |
| <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> |
| |
| <span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span> |
| <span class="special">{</span> |
| <span class="comment">// This log record will also be marked with the "Tag" attribute,</span> |
| <span class="comment">// whenever it is called from the A::bar function.</span> |
| <span class="comment">// It will not be marked when called from other places.</span> |
| <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> |
| <span class="special">}</span> |
| |
| <span class="keyword">struct</span> <span class="identifier">A</span> |
| <span class="special">{</span> |
| <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger</span> <span class="identifier">m_Logger</span><span class="special">;</span> |
| |
| <span class="keyword">void</span> <span class="identifier">bar</span><span class="special">()</span> |
| <span class="special">{</span> |
| <span class="comment">// Set a thread-wide markup tag.</span> |
| <span class="comment">// Note the additional parentheses to form a Boost.PP sequence.</span> |
| <span class="identifier">BOOST_LOG_SCOPED_THREAD_ATTR</span><span class="special">(</span><span class="string">"Tag"</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">"Called from A::bar"</span><span class="special">));</span> |
| |
| <span class="comment">// This log record will be marked</span> |
| <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> |
| |
| <span class="identifier">foo</span><span class="special">();</span> |
| <span class="special">}</span> |
| <span class="special">};</span> |
| |
| <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> |
| <span class="special">{</span> |
| <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger</span> <span class="identifier">lg</span><span class="special">;</span> |
| |
| <span class="comment">// Let's measure our application run time</span> |
| <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> |
| |
| <span class="comment">// Mark application start.</span> |
| <span class="comment">// The "RunTime" attribute should be nearly 0 at this point.</span> |
| <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> |
| |
| <span class="comment">// Note that no other log records are affected by the "RunTime" attribute.</span> |
| <span class="identifier">foo</span><span class="special">();</span> |
| |
| <span class="identifier">A</span> <span class="identifier">a</span><span class="special">;</span> |
| <span class="identifier">a</span><span class="special">.</span><span class="identifier">bar</span><span class="special">();</span> |
| |
| <span class="comment">// Mark application ending.</span> |
| <span class="comment">// The "RunTime" attribute will show the execution time elapsed.</span> |
| <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> |
| |
| <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> |
| <span class="special">}</span> |
| </pre> |
| <p> |
| It is quite often convenient to mark a group of log records with a constant |
| value in order to be able to filter the records later. The library provides |
| two convenience macros just for this purpose: |
| </p> |
| <pre class="programlisting"><code class="computeroutput"><a class="link" href="../../BOOST_LOG_SCOPED_LOGGER_TAG.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> |
| <code class="computeroutput"><a class="link" href="../../BOOST_LOG_SCOPED_THREAD_TAG.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> |
| </pre> |
| <p> |
| The macros are effectively wrappers around <code class="computeroutput"><a class="link" href="../../BOOST_LOG_SCOPED_LOGGER_ATTR.html" title="Macro BOOST_LOG_SCOPED_LOGGER_ATTR">BOOST_LOG_SCOPED_LOGGER_ATTR</a></code> |
| and <code class="computeroutput"><a class="link" href="../../BOOST_LOG_SCOPED_THREAD_ATTR.html" title="Macro BOOST_LOG_SCOPED_THREAD_ATTR">BOOST_LOG_SCOPED_THREAD_ATTR</a></code>, |
| respectively. For example, the "Tag" scoped attribute from |
| the example above can be registered like this: |
| </p> |
| <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> |
| </pre> |
| <div class="warning"><table border="0" summary="Warning"> |
| <tr> |
| <td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../../doc/src/images/warning.png"></td> |
| <th align="left">Warning</th> |
| </tr> |
| <tr><td align="left" valign="top"><p> |
| When using scoped attributes, make sure that the scoped attribute is |
| not altered in the attribute set in which it was registered. For example, |
| one should not clear or reinstall the attribute set of the logger if |
| there are logger-specific scoped attributes registered in it. Otherwise |
| the program will likely crash. This issue is especially critical in |
| multithreaded application, when one thread may not know whether there |
| are scoped attributes in the logger or there are not. Future releases |
| may solve this limitation but currently the scoped attribute must remain |
| intact until unregistered on leaving the scope. |
| </p></td></tr> |
| </table></div> |
| <p> |
| Although the described macros are intended to be the primary interface |
| for the functionality, there is also a C++ interface available. It may |
| be useful if the user decides to develop his own macros that cannot be |
| based on the existing ones. |
| </p> |
| <p> |
| Any scoped attribute is attached to a generic sentry object of type |
| <code class="computeroutput"><span class="identifier">scoped_attribute</span></code>. As |
| long as the sentry exists, the attribute is registered. There are several |
| functions that create sentries for source or thread-specific attributes: |
| </p> |
| <pre class="programlisting"><span class="comment">// Source-specific scoped attribute registration</span> |
| <span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">LoggerT</span> <span class="special">></span> |
| <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> |
| <span class="identifier">LoggerT</span><span class="special">&</span> <span class="identifier">l</span><span class="special">,</span> |
| <span class="identifier">attribute_name</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">name</span><span class="special">,</span> |
| <span class="identifier">attribute</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">attr</span><span class="special">);</span> |
| |
| <span class="comment">// Thread-specific scoped attribute registration</span> |
| <span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">CharT</span> <span class="special">></span> |
| <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> |
| <span class="identifier">attribute_name</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">name</span><span class="special">,</span> |
| <span class="identifier">attribute</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">attr</span><span class="special">);</span> |
| </pre> |
| <p> |
| An object of the <code class="computeroutput"><span class="identifier">scoped_attribute</span></code> |
| type is able to attach results of each of these functions on its construction. |
| 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: |
| </p> |
| <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> |
| <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> |
| </pre> |
| </div> |
| </div> |
| </div> |
| <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> |
| <td align="left"></td> |
| <td align="right"><div class="copyright-footer">Copyright © 2007-2015 Andrey |
| Semashev<p> |
| Distributed under the Boost Software License, Version 1.0. (See accompanying |
| 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>). |
| </p> |
| </div></td> |
| </tr></table> |
| <hr> |
| <div class="spirit-nav"> |
| <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> |
| </div> |
| </body> |
| </html> |