summaryrefslogtreecommitdiff
path: root/libs/log/doc/html/log/tutorial/sources.html
blob: 26a0a636ef73b311375eaed168692b41d042f82f (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
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Creating loggers and writing logs</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="../tutorial.html" title="Tutorial">
<link rel="prev" href="sinks.html" title="Setting up sinks">
<link rel="next" href="attributes.html" title="Adding more information to log: Attributes">
</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="sinks.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="attributes.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.tutorial.sources"></a><a class="link" href="sources.html" title="Creating loggers and writing logs">Creating loggers and writing logs</a>
</h3></div></div></div>
<h5>
<a name="log.tutorial.sources.h0"></a>
        <span class="phrase"><a name="log.tutorial.sources.dedicated_logger_objects"></a></span><a class="link" href="sources.html#log.tutorial.sources.dedicated_logger_objects">Dedicated
        logger objects</a>
      </h5>
<p>
        Now that we have defined where and how the log is to be stored, it's time
        to go on and try logging. In order to do this one has to create a logging
        source. This would be a logger object in our case and it is as simple as
        that:
      </p>
<pre class="programlisting"><span class="identifier">src</span><span class="special">::</span><span class="identifier">logger</span> <span class="identifier">lg</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>
          A curious reader could have noticed that we did not create any loggers
          for trivial logging. In fact the logger is provided by the library and
          is used behind the scenes.
        </p></td></tr>
</table></div>
<p>
        Unlike sinks, sources need not be registered anywhere since they interact
        directly with the logging core. Also note that there are two versions of
        loggers provided by the library: the thread-safe ones and the non-thread-safe
        ones. For the non-thread-safe loggers it is safe for different threads to
        write logs through different instances of loggers and thus there should be
        a separate logger for each thread that writes logs. The thread-safe counterparts
        can be accessed from different threads concurrently, but this will involve
        locking and may slow things down in case of intense logging. The thread-safe
        logger types have the <code class="computeroutput"><span class="identifier">_mt</span></code>
        suffix in their name.
      </p>
<p>
        Regardless of the thread safety, all loggers provided by the library are
        default and copy-constructible and support swapping, so there should be no
        problem in making a logger a member of your class. As you will see later,
        such approach can give you additional benefits.
      </p>
<p>
        The library provides a number of loggers with different features, such as
        severity and channel support. These features can be combined with each other
        in order to construct more complex loggers. See <a class="link" href="../detailed/sources.html" title="Logging sources">here</a>
        for more details.
      </p>
<h5>
<a name="log.tutorial.sources.h1"></a>
        <span class="phrase"><a name="log.tutorial.sources.global_logger_objects"></a></span><a class="link" href="sources.html#log.tutorial.sources.global_logger_objects">Global
        logger objects</a>
      </h5>
<p>
        In case you cannot put a logger into your class (suppose you don't have one),
        the library provides a way of declaring global loggers like this:
      </p>
<pre class="programlisting"><span class="identifier">BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT</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>
</pre>
<p>
        Here <code class="computeroutput"><span class="identifier">my_logger</span></code> is a user-defined
        tag name that will be used later to retrieve the logger instance and <code class="computeroutput"><span class="identifier">logger_mt</span></code> is the logger type. Any logger
        type provided by the library or defined by the user can participate in such
        declaration. However, since the logger will have a single instance, you will
        normally want to use thread-safe loggers in a multithreaded application as
        global ones.
      </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>
          There are other macros for more sophisticated cases available. The detailed
          description is in <a class="link" href="../detailed/sources.html#log.detailed.sources.global_storage" title="Global storage for loggers">this</a>
          section.
        </p></td></tr>
</table></div>
<p>
        Later on you can acquire the logger like this:
      </p>
<pre class="programlisting"><span class="identifier">src</span><span class="special">::</span><span class="identifier">logger_mt</span><span class="special">&amp;</span> <span class="identifier">lg</span> <span class="special">=</span> <span class="identifier">my_logger</span><span class="special">::</span><span class="identifier">get</span><span class="special">();</span>
</pre>
<p>
        The <code class="computeroutput"><span class="identifier">lg</span></code> will refer to the
        one and only instance of the logger throughout the application, even if the
        application consists of multiple modules. The <code class="computeroutput"><span class="identifier">get</span></code>
        function itself is thread-safe, so there is no need in additional synchronization
        around it.
      </p>
<h5>
<a name="log.tutorial.sources.h2"></a>
        <span class="phrase"><a name="log.tutorial.sources.writing_logs"></a></span><a class="link" href="sources.html#log.tutorial.sources.writing_logs">Writing
        logs</a>
      </h5>
<p>
        No matter what kind of logger you use (class member or global, thread-safe
        or not), to write a log record into a logger you can write something like
        this:
      </p>
<p>
</p>
<pre class="programlisting"><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">lg</span><span class="special">.</span><span class="identifier">open_record</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="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="identifier">lg</span><span class="special">.</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>
</pre>
<p>
      </p>
<p>
        Here the <code class="computeroutput"><span class="identifier">open_record</span></code> function
        call determines if the record to be constructed is going to be consumed by
        at least one sink. Filtering is applied at this stage. If the record is to
        be consumed, the function returns a valid record object, and one can fill
        in the record message string. After that the record processing can be completed
        with the call to <code class="computeroutput"><span class="identifier">push_record</span></code>.
      </p>
<p>
        Of course, the above syntax can easily be wrapped in a macro and, in fact,
        users are encouraged to write their own macros instead of using the C++ logger
        interface directly. The log record above can be written like this:
      </p>
<pre class="programlisting"><span class="identifier">BOOST_LOG</span><span class="special">(</span><span class="identifier">lg</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">"Hello, World!"</span><span class="special">;</span>
</pre>
<p>
        Looks a bit shorter, doesn't it? The <code class="computeroutput"><span class="identifier">BOOST_LOG</span></code>
        macro, along with other similar ones, is defined by the library. It automatically
        provides an STL-like stream in order to format the message with ordinary
        insertion expressions. Having all that code written, compiled and executed
        you should be able to see the "Hello, World!" record in the "sample.log"
        file. You will find the full code of this section <a href="../../../../../../libs/log/example/doc/tutorial_logging.cpp" target="_top">here</a>.
      </p>
</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-2014 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="sinks.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="attributes.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>