summaryrefslogtreecommitdiff
path: root/libs/log/doc/html/log/detailed.html
blob: 56608fb5bd3b58f30f50bb317c55cf525a224e04 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Detailed features description</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&#160;1.&#160;Boost.Log v2">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.Log v2">
<link rel="prev" href="tutorial/wide_char.html" title="Wide character logging">
<link rel="next" href="detailed/sources.html" title="Logging sources">
</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="tutorial/wide_char.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="detailed/sources.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="log.detailed"></a><a class="link" href="detailed.html" title="Detailed features description">Detailed features description</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="detailed.html#log.detailed.core">Core facilities</a></span></dt>
<dt><span class="section"><a href="detailed/sources.html">Logging sources</a></span></dt>
<dt><span class="section"><a href="detailed/sink_frontends.html">Sink frontends</a></span></dt>
<dt><span class="section"><a href="detailed/sink_backends.html">Sink backends</a></span></dt>
<dt><span class="section"><a href="detailed/expressions.html">Lambda expressions</a></span></dt>
<dt><span class="section"><a href="detailed/attributes.html">Attributes</a></span></dt>
<dt><span class="section"><a href="detailed/utilities.html">Utilities</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="log.detailed.core"></a><a class="link" href="detailed.html#log.detailed.core" title="Core facilities">Core facilities</a>
</h3></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="detailed.html#log.detailed.core.record">Logging records</a></span></dt>
<dt><span class="section"><a href="detailed.html#log.detailed.core.core">Logging core</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="log.detailed.core.record"></a><a class="link" href="detailed.html#log.detailed.core.record" title="Logging records">Logging records</a>
</h4></div></div></div>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../core_components.html#header.boost.log.core.record_hpp" title="Header &lt;boost/log/core/record.hpp&gt;">boost/log/core/record.hpp</a></code><span class="special">&gt;</span>
</pre>
<p>
          All the information that the logging library processes is packed into a
          single object of type <code class="computeroutput"><a class="link" href="../boost/log/record.html" title="Class record">record</a></code>.
          All attached data, including the message text, is represented as named
          attribute values that can be fetched and processed by filters, formatters
          and sinks. Particular attribute values can be accessed in different ways,
          here are a few quick examples:
        </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
              Through <a class="link" href="detailed/attributes.html#log.detailed.attributes.related_components.value_processing" title="Attribute value extraction and visitation">value
              visitation and extraction</a>.
            </li></ul></div>
<p>
</p>
<pre class="programlisting"><span class="keyword">enum</span> <span class="identifier">severity_level</span> <span class="special">{</span> <span class="special">...</span> <span class="special">};</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">&lt;&lt;</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="identifier">strm</span><span class="special">,</span> <span class="identifier">severity_level</span> <span class="identifier">level</span><span class="special">);</span>

<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="identifier">severity_level</span> <span class="identifier">level</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">&lt;&lt;</span> <span class="identifier">level</span> <span class="special">&lt;&lt;</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="comment">// Prints severity level through visitation API</span>
<span class="keyword">void</span> <span class="identifier">print_severity_visitation</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">record</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rec</span><span class="special">)</span>
<span class="special">{</span>
    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">visit</span><span class="special">&lt;</span> <span class="identifier">severity_level</span> <span class="special">&gt;(</span><span class="string">"Severity"</span><span class="special">,</span> <span class="identifier">rec</span><span class="special">,</span> <span class="identifier">print_visitor</span><span class="special">());</span>
<span class="special">}</span>

<span class="comment">// Prints severity level through extraction API</span>
<span class="keyword">void</span> <span class="identifier">print_severity_extraction</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">record</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rec</span><span class="special">)</span>
<span class="special">{</span>
    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">value_ref</span><span class="special">&lt;</span> <span class="identifier">severity_level</span> <span class="special">&gt;</span> <span class="identifier">level</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">extract</span><span class="special">&lt;</span> <span class="identifier">severity_level</span> <span class="special">&gt;(</span><span class="string">"Severity"</span><span class="special">,</span> <span class="identifier">rec</span><span class="special">);</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">level</span> <span class="special">&lt;&lt;</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>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
              By searching the <a class="link" href="detailed/attributes.html#log.detailed.attributes.related_components.attribute_value_set" title="Attribute value set">set
              of attribute values</a> accessible with the <code class="computeroutput"><span class="identifier">attribute_values</span></code>
              method of the record.
            </li></ul></div>
<p>
</p>
<pre class="programlisting"><span class="comment">// Prints severity level by searching the attribute values</span>
<span class="keyword">void</span> <span class="identifier">print_severity_lookup</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">record</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rec</span><span class="special">)</span>
<span class="special">{</span>
    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">attribute_value_set</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">values</span> <span class="special">=</span> <span class="identifier">rec</span><span class="special">.</span><span class="identifier">attribute_values</span><span class="special">();</span>
    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">attribute_value_set</span><span class="special">::</span><span class="identifier">const_iterator</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">values</span><span class="special">.</span><span class="identifier">find</span><span class="special">(</span><span class="string">"Severity"</span><span class="special">);</span>
    <span class="keyword">if</span> <span class="special">(</span><span class="identifier">it</span> <span class="special">!=</span> <span class="identifier">values</span><span class="special">.</span><span class="identifier">end</span><span class="special">())</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">&amp;</span> <span class="identifier">value</span> <span class="special">=</span> <span class="identifier">it</span><span class="special">-&gt;</span><span class="identifier">second</span><span class="special">;</span>

        <span class="comment">// A single attribute value can also be visited or extracted</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">value</span><span class="special">.</span><span class="identifier">extract</span><span class="special">&lt;</span> <span class="identifier">severity_level</span> <span class="special">&gt;()</span> <span class="special">&lt;&lt;</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>
</pre>
<p>
        </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
              By applying the subscript operator with the attribute keyword. This
              is actually a convenience wrapper around the value extraction API.
            </li></ul></div>
<p>
</p>
<pre class="programlisting"><span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">severity</span><span class="special">,</span> <span class="string">"Severity"</span><span class="special">,</span> <span class="identifier">severity_level</span><span class="special">)</span>

<span class="comment">// Prints severity level by using the subscript operator</span>
<span class="keyword">void</span> <span class="identifier">print_severity_subscript</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">record</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rec</span><span class="special">)</span>
<span class="special">{</span>
    <span class="comment">// Use the attribute keyword to communicate the name and type of the value</span>
    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">value_ref</span><span class="special">&lt;</span> <span class="identifier">severity_level</span><span class="special">,</span> <span class="identifier">tag</span><span class="special">::</span><span class="identifier">severity</span> <span class="special">&gt;</span> <span class="identifier">level</span> <span class="special">=</span> <span class="identifier">rec</span><span class="special">[</span><span class="identifier">severity</span><span class="special">];</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">level</span> <span class="special">&lt;&lt;</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>
          Log records cannot be copied, only moved. A record can be default-constructed
          in which case it is in an empty state; such records are mostly unusable
          and should not be passed to the library for processing. Non-empty log records
          can only be created by the <a class="link" href="detailed.html#log.detailed.core.core" title="Logging core">logging
          core</a> as a result of successful filtering. The non-empty record contains
          attribute values acquired from attributes. More attribute values can be
          added to the non-empty record after filtering. The added values will not
          affect filtering results but can still be used by formatters and sinks.
        </p>
<p>
          In multithreaded environments, after being constructed a non-empty log
          record is considered to be tied to the current thread as it may refer to
          some thread-specific resources. For example, the record may contain an
          attribute value which refers to the named scope list which is stored on
          the stack. For this reason log records must not be passed between different
          threads.
        </p>
<h6>
<a name="log.detailed.core.record.h0"></a>
          <span class="phrase"><a name="log.detailed.core.record.record_views"></a></span><a class="link" href="detailed.html#log.detailed.core.record.record_views">Record
          views</a>
        </h6>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../core_components.html#header.boost.log.core.record_view_hpp" title="Header &lt;boost/log/core/record_view.hpp&gt;">boost/log/core/record_view.hpp</a></code><span class="special">&gt;</span>
</pre>
<p>
          While records are used for filling the information, the library uses another
          type to actually process it. Record views provide a similar interface to
          records with a few notable distinctions:
        </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
              Record views are immutable. This prevents formatters and sinks from
              modifying the record while it is being processed.
            </li>
<li class="listitem">
              Record views are copyable. Since its contents are constant, the copy
              operation is shallow and therefore cheap.
            </li>
</ul></div>
<p>
          The library will automatically create a record view from the record by
          calling the <code class="computeroutput"><span class="identifier">lock</span></code> method.
          The call will also make sure the resulting view is not attached to the
          current thread if a sink is asynchronous. The <code class="computeroutput"><span class="identifier">lock</span></code>
          call is a one time operation; the record is left in the empty state afterwards.
          All APIs for interacting with attribute values described for log records
          are also applicable to record views and can be used in custom formatters
          and sinks.
        </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="log.detailed.core.core"></a><a class="link" href="detailed.html#log.detailed.core.core" title="Logging core">Logging core</a>
</h4></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="detailed.html#log.detailed.core.core.attribute_sets">Attribute
          sets</a></span></dt>
<dt><span class="section"><a href="detailed.html#log.detailed.core.core.filtering">Global filtering</a></span></dt>
<dt><span class="section"><a href="detailed.html#log.detailed.core.core.sinks">Sink management</a></span></dt>
<dt><span class="section"><a href="detailed.html#log.detailed.core.core.exception_handling">Exception
          handling</a></span></dt>
<dt><span class="section"><a href="detailed.html#log.detailed.core.core.record_feeding">Feeding log
          records</a></span></dt>
</dl></div>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><code class="computeroutput"><a class="link" href="../core_components.html#header.boost.log.core.core_hpp" title="Header &lt;boost/log/core/core.hpp&gt;">boost/log/core/core.hpp</a></code><span class="special">&gt;</span>
</pre>
<p>
          The logging core is a central hub that provides the following facilities:
        </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
              Maintains global and thread-specific attribute sets.
            </li>
<li class="listitem">
              Performs global filtering of log records.
            </li>
<li class="listitem">
              Dispatches log records between sinks by applying sink-specific filters.
            </li>
<li class="listitem">
              Provides a global hook for exception handlers.
            </li>
<li class="listitem">
              Provides an entry point for log sources to put log records to.
            </li>
<li class="listitem">
              Provides the <code class="computeroutput"><span class="identifier">flush</span></code>
              method that can be used to enforce the synchronized state for all log
              sinks.
            </li>
</ul></div>
<p>
          The logging core is an application-wide singleton, thus every logging source
          has access to it. The core instance is accessible with the static method
          <code class="computeroutput"><span class="identifier">get</span></code>.
        </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">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span> <span class="special">&gt;</span> <span class="identifier">core</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">();</span>

    <span class="comment">// ...</span>
<span class="special">}</span>
</pre>
<div class="section">
<div class="titlepage"><div><div><h5 class="title">
<a name="log.detailed.core.core.attribute_sets"></a><a class="link" href="detailed.html#log.detailed.core.core.attribute_sets" title="Attribute sets">Attribute
          sets</a>
</h5></div></div></div>
<p>
            In order to add or remove global or thread-specific attributes to the
            core there are corresponding methods: <code class="computeroutput"><span class="identifier">add_global_attribute</span></code>,
            <code class="computeroutput"><span class="identifier">remove_global_attribute</span></code>,
            <code class="computeroutput"><span class="identifier">add_thread_attribute</span></code>
            and <code class="computeroutput"><span class="identifier">remove_thread_attribute</span></code>.
            Attribute sets provide interface similar to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span></code>,
            so the <code class="computeroutput"><span class="identifier">add_</span><span class="special">*</span></code>
            methods accept an attribute name string (key) and a pointer to the attribute
            (mapped value) and return a pair of iterator and boolean value, like
            <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span> <span class="special">...</span> <span class="special">&gt;::</span><span class="identifier">insert</span></code> does. The <code class="computeroutput"><span class="identifier">remove_</span><span class="special">*</span></code> methods accept an iterator to a previously
            added attribute.
          </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">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span> <span class="special">&gt;</span> <span class="identifier">core</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">();</span>

    <span class="comment">// Add a global attribute</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">attribute_set</span><span class="special">::</span><span class="identifier">iterator</span><span class="special">,</span> <span class="keyword">bool</span> <span class="special">&gt;</span> <span class="identifier">res</span> <span class="special">=</span>
        <span class="identifier">core</span><span class="special">-&gt;</span><span class="identifier">add_global_attribute</span><span class="special">(</span><span class="string">"LineID"</span><span class="special">,</span> <span class="identifier">attrs</span><span class="special">::</span><span class="identifier">counter</span><span class="special">&lt;</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="special">&gt;());</span>

    <span class="comment">// ...</span>

    <span class="comment">// Remove the added attribute</span>
    <span class="identifier">core</span><span class="special">-&gt;</span><span class="identifier">remove_global_attribute</span><span class="special">(</span><span class="identifier">res</span><span class="special">.</span><span class="identifier">first</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>
              It must be said that all methods of logging core are thread-safe in
              multithreaded environments. However, that may not be true for other
              components, such as iterators or attribute sets.
            </p></td></tr>
</table></div>
<p>
            It is possible to acquire a copy of the whole attribute set (global or
            thread-specific) or install it into the core. Methods <code class="computeroutput"><span class="identifier">get_global_attributes</span></code>,
            <code class="computeroutput"><span class="identifier">set_global_attributes</span></code>,
            <code class="computeroutput"><span class="identifier">get_thread_attributes</span></code>
            and <code class="computeroutput"><span class="identifier">set_thread_attributes</span></code>
            serve this purpose.
          </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>
              After installing a whole attribute set into the core, all iterators
              that were previously returned by the corresponding <code class="computeroutput"><span class="identifier">add_</span><span class="special">*</span></code> methods are invalidated. In particular,
              it affects <a class="link" href="detailed/attributes.html#log.detailed.attributes.related_components.scoped_attributes" title="Scoped attributes">scoped
              attributes</a>, so the user must be careful when to switch attribute
              sets.
            </p></td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h5 class="title">
<a name="log.detailed.core.core.filtering"></a><a class="link" href="detailed.html#log.detailed.core.core.filtering" title="Global filtering">Global filtering</a>
</h5></div></div></div>
<p>
            Global filtering is handled by the filter function object, which can
            be provided with the <code class="computeroutput"><span class="identifier">set_filter</span></code>
            method. More on creating filters appears in <a class="link" href="detailed/expressions.html#log.detailed.expressions.predicates" title="Predicate expressions">this
            section</a>. Here it will suffice to say that the filter accepts a
            set of attribute values and returns a boolean value that tells whether
            a log record with these attribute values passed filtering or not. The
            global filter is applied to every log record made throughout the application,
            so it can be used to wipe out excessive log records quickly.
          </p>
<p>
            The global filter can be removed by the <code class="computeroutput"><span class="identifier">reset_filter</span></code>
            method. When there is no filter set in the core it is assumed that no
            records are filtered away. This is the default after initial construction
            of the logging core.
          </p>
<pre class="programlisting"><span class="keyword">enum</span> <span class="identifier">severity_level</span>
<span class="special">{</span>
    <span class="identifier">normal</span><span class="special">,</span>
    <span class="identifier">warning</span><span class="special">,</span>
    <span class="identifier">error</span><span class="special">,</span>
    <span class="identifier">critical</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</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span> <span class="special">&gt;</span> <span class="identifier">core</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">();</span>

    <span class="comment">// Set a global filter so that only error messages are logged</span>
    <span class="identifier">core</span><span class="special">-&gt;</span><span class="identifier">set_filter</span><span class="special">(</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special">&lt;</span> <span class="identifier">severity_level</span> <span class="special">&gt;(</span><span class="string">"Severity"</span><span class="special">)</span> <span class="special">&gt;=</span> <span class="identifier">error</span><span class="special">);</span>

    <span class="comment">// ...</span>
<span class="special">}</span>
</pre>
<p>
            The core also provides another way to disable logging. By calling the
            <code class="computeroutput"><span class="identifier">set_logging_enabled</span></code> with
            a boolean argument one may completely disable or re-enable logging, including
            applying filtering. Disabling logging with this method may be more beneficial
            in terms of application performance than setting a global filter that
            always fails.
          </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h5 class="title">
<a name="log.detailed.core.core.sinks"></a><a class="link" href="detailed.html#log.detailed.core.core.sinks" title="Sink management">Sink management</a>
</h5></div></div></div>
<p>
            After global filtering is applied, log sinks step into action. In order
            to add and remove sinks the core provides <code class="computeroutput"><span class="identifier">add_sink</span></code>
            and <code class="computeroutput"><span class="identifier">remove_sink</span></code> methods.
            Both these methods accept a pointer to the sink. The <code class="computeroutput"><span class="identifier">add_sink</span></code>
            will add the sink to the core if it's not added already. The <code class="computeroutput"><span class="identifier">remove_sink</span></code> method will seek for the
            provided sink in an internal list of previously added sinks and remove
            the sink if it finds it. The order in which the core processes sinks
            internally is unspecified.
          </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">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span> <span class="special">&gt;</span> <span class="identifier">core</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">();</span>

    <span class="comment">// Set a sink that will write log records to the console</span>
    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">text_ostream_backend</span> <span class="special">&gt;</span> <span class="identifier">backend</span> <span class="special">=</span>
        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">text_ostream_backend</span> <span class="special">&gt;();</span>
    <span class="identifier">backend</span><span class="special">-&gt;</span><span class="identifier">add_stream</span><span class="special">(</span>
        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">&gt;(&amp;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">clog</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">null_deleter</span><span class="special">()));</span>

    <span class="keyword">typedef</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">unlocked_sink</span><span class="special">&lt;</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">text_ostream_backend</span> <span class="special">&gt;</span> <span class="identifier">sink_t</span><span class="special">;</span>
    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">sink_t</span> <span class="special">&gt;</span> <span class="identifier">sink</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">sink_t</span> <span class="special">&gt;(</span><span class="identifier">backend</span><span class="special">);</span>
    <span class="identifier">core</span><span class="special">-&gt;</span><span class="identifier">add_sink</span><span class="special">(</span><span class="identifier">sink</span><span class="special">);</span>

    <span class="comment">// ...</span>

    <span class="comment">// Remove the sink</span>
    <span class="identifier">core</span><span class="special">-&gt;</span><span class="identifier">remove_sink</span><span class="special">(</span><span class="identifier">sink</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
            You can read more on the design of sinks in the following sections:
            <a class="link" href="detailed/sink_frontends.html" title="Sink frontends">Sink Frontends</a> and
            <a class="link" href="detailed/sink_backends.html" title="Sink backends">Sink Backends</a>.
          </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h5 class="title">
<a name="log.detailed.core.core.exception_handling"></a><a class="link" href="detailed.html#log.detailed.core.core.exception_handling" title="Exception handling">Exception
          handling</a>
</h5></div></div></div>
<p>
            The core provides a way to set up centralized exception handling. If
            an exception takes place during filtering or processing in one of the
            added sinks, the core will invoke an exception handler if one was installed
            with the <code class="computeroutput"><span class="identifier">set_exception_handler</span></code>
            method. An exception handler is a nullary function object that is invoked
            from within a <code class="computeroutput"><span class="keyword">catch</span></code> clause.
            The library provides <a class="link" href="detailed/utilities.html#log.detailed.utilities.exception_handlers" title="Exception handlers">tools</a>
            to simplify exception handlers construction.
          </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 exception handler in the logging core is global and thus is intended
              to perform some common actions on errors. Logging sinks and sources
              also provide exception handling facilities (see <a class="link" href="detailed/sink_frontends.html#log.detailed.sink_frontends.basic_services.exception_handling" title="Exception handling">here</a>
              and <a class="link" href="detailed/sources.html#log.detailed.sources.exception_handling" title="Loggers with exception handling support">here</a>),
              which can be used to do a finer grained error processing.
            </p></td></tr>
</table></div>
<p>
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">my_handler</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="keyword">void</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">runtime_error</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">e</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">&lt;&lt;</span> <span class="string">"std::runtime_error: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">()</span> <span class="special">&lt;&lt;</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="keyword">void</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">logic_error</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">e</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">&lt;&lt;</span> <span class="string">"std::logic_error: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
        <span class="keyword">throw</span><span class="special">;</span>
    <span class="special">}</span>
<span class="special">};</span>

<span class="keyword">void</span> <span class="identifier">init_exception_handler</span><span class="special">()</span>
<span class="special">{</span>
    <span class="comment">// Setup a global exception handler that will call my_handler::operator()</span>
    <span class="comment">// for the specified exception types</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">()-&gt;</span><span class="identifier">set_exception_handler</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">make_exception_handler</span><span class="special">&lt;</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">runtime_error</span><span class="special">,</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">logic_error</span>
    <span class="special">&gt;(</span><span class="identifier">my_handler</span><span class="special">()));</span>
<span class="special">}</span>
</pre>
<p>
          </p>
</div>
<div class="section">
<div class="titlepage"><div><div><h5 class="title">
<a name="log.detailed.core.core.record_feeding"></a><a class="link" href="detailed.html#log.detailed.core.core.record_feeding" title="Feeding log records">Feeding log
          records</a>
</h5></div></div></div>
<p>
            One of the most important functions of the logging core is providing
            an entry point for all logging sources to feed log records into. This
            is done with the <code class="computeroutput"><span class="identifier">open_record</span></code>
            and <code class="computeroutput"><span class="identifier">push_record</span></code> methods.
          </p>
<p>
            The first method is used to initiate the record logging process. It accepts
            the source-specific set of attributes. The method constructs a common
            set of attribute values of the three sets of attributes (global, thread-specific
            and source-specific) and applies filtering. If the filtering succeeded,
            i.e. at least one sink accepts a record with these attribute values,
            the method returns a non-empty <a class="link" href="detailed.html#log.detailed.core.record" title="Logging records">record
            object</a>, which can be used to fill in the log record message. If
            the filtering failed, an empty record object is returned.
          </p>
<p>
            When the log source is ready to complete the logging procedure, it has
            to call the <code class="computeroutput"><span class="identifier">push_record</span></code>
            method with the record returned by the <code class="computeroutput"><span class="identifier">open_record</span></code>
            method. Note that one should not call <code class="computeroutput"><span class="identifier">push_record</span></code>
            with an empty record. The record should be passed as rvalue reference.
            During the call the record view will be constructed from the record.
            The view will then be passed on to the sinks that accepted it during
            filtering. This may involve record formatting and further processing,
            like storing it into a file or sending it over the network. After that
            the record object can be destroyed.
          </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">logging_function</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">attribute_set</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">attrs</span><span class="special">)</span>
<span class="special">{</span>
    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span> <span class="special">&gt;</span> <span class="identifier">core</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">();</span>

    <span class="comment">// Attempt to open a log record</span>
    <span class="identifier">logging</span><span class="special">::</span><span class="identifier">record</span> <span class="identifier">rec</span> <span class="special">=</span> <span class="identifier">core</span><span class="special">-&gt;</span><span class="identifier">open_record</span><span class="special">(</span><span class="identifier">attrs</span><span class="special">);</span>
    <span class="keyword">if</span> <span class="special">(</span><span class="identifier">rec</span><span class="special">)</span>
    <span class="special">{</span>
        <span class="comment">// Ok, the record is accepted. Compose the message now.</span>
        <span class="identifier">logging</span><span class="special">::</span><span class="identifier">record_ostream</span> <span class="identifier">strm</span><span class="special">(</span><span class="identifier">rec</span><span class="special">);</span>
        <span class="identifier">strm</span> <span class="special">&lt;&lt;</span> <span class="string">"Hello, World!"</span><span class="special">;</span>
        <span class="identifier">strm</span><span class="special">.</span><span class="identifier">flush</span><span class="special">();</span>

        <span class="comment">// Deliver the record to the sinks.</span>
        <span class="identifier">core</span><span class="special">-&gt;</span><span class="identifier">push_record</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">rec</span><span class="special">));</span>
    <span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
          </p>
<p>
            All this logic is usually hidden in the loggers and macros provided by
            the library. However, this may be useful for those developing new log
            sources.
          </p>
</div>
</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 &#169; 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="tutorial/wide_char.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="detailed/sources.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>