]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/log/doc/utilities.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / log / doc / utilities.qbk
CommitLineData
7c673cae
FG
1[/
2 Copyright Andrey Semashev 2007 - 2016.
3 Distributed under the Boost Software License, Version 1.0.
4 (See accompanying file LICENSE_1_0.txt or copy at
5 http://www.boost.org/LICENSE_1_0.txt)
6
7 This document is a part of Boost.Log library documentation.
8/]
9
10[section:utilities Utilities]
11
12[section:string_literal String literals]
13
14 #include <``[boost_log_utility_string_literal_hpp]``>
15
16String literals are used in several places throughout the library. However, this component can be successfully used outside of the library in users' code. It is header-only and does not require linking with the library binary. String literals can improve performance significantly if there is no need to modify stored strings. What is also important, since string literals do not dynamically allocate memory, it is easier to maintain exception safety when using string literals instead of regular strings.
17
18The functionality is implemented in the [class_log_basic_string_literal] class template, which is parametrized with the character and character traits, similar to `std::basic_string`. There are also two convenience typedefs provided: `string_literal` and `wstring_literal`, for narrow and wide character types, respectively. In order to ease string literal construction in generic code there is also a `str_literal` function template that accepts a string literal and returns a [class_log_basic_string_literal] instance for the appropriate character type.
19
20String literals support interface similar to STL strings, except for string modification functions. However, it is possible to assign to or clear string literals, as long as only string literals involved. Relational and stream output operators are also supported.
21
22[endsect]
23
24[section:type_dispatch Type dispatchers]
25
26 #include <``[boost_log_utility_type_dispatch_type_dispatcher_hpp]``>
27
28Type dispatchers are used throughout the library in order to work with attribute values. Dispatchers allow acquiring the stored attribute value using the Visitor concept. The most notable places where the functionality is used are filters and formatters. However, this mechanism is orthogonal to attributes and can be used for other purposes as well. Most of the time users won't need to dig into the details of type dispatchers, but this information may be useful for those who intend to extend the library and wants to understand what's under the hood.
29
30Every type dispatcher supports the [class_log_type_dispatcher] interface. When an attribute value needs to be extracted, this interface is passed to the attribute value object, which then tries to acquire the callback for the actual type of the value. All callbacks are objects of the [class_type_dispatcher_callback] class template, instantiated on the actual type of the value. If the dispatcher is able to consume the value of the requested type, it must return a non-empty callback object. When (and if) the corresponding callback is acquired, the attribute value object only has to pass the contained value to its `operator ()`.
31
32Happily, there is no need to write type dispatchers from scratch. The library provides two kinds of type dispatchers that implement the [class_log_type_dispatcher] and [class_type_dispatcher_callback] interfaces and encapsulate the callback lookup.
33
34[heading Static type dispatcher]
35
36 #include <``[boost_log_utility_type_dispatch_static_type_dispatcher_hpp]``>
37
38Static type dispatchers are used when the set of types that needs to be supported for extraction is known at compile time. The [class_log_static_type_dispatcher] class template is parametrized with an MPL type sequence of types that need to be supported. The dispatcher inherits from the [class_log_type_dispatcher] interface which provides the `get_callback` method for acquiring the function object to invoke on the stored value. All you need to do is provide a visitor function object to the dispatcher at construction point and invoke the callback when dispatching the stored value:
39
40[example_util_static_type_dispatcher]
41
42[@boost:/libs/log/example/doc/util_static_type_disp.cpp See the complete code].
43
44[heading Dynamic type dispatcher]
45
46 #include <``[boost_log_utility_type_dispatch_dynamic_type_dispatcher_hpp]``>
47
48If the set of types that have to be supported is not available at compile time, the [class_log_dynamic_type_dispatcher] class is there to help. One can use its `register_type` method to add support for a particular type. The user has to pass a function object along with the type, this functor will be called when a visitor for the specified type is invoked. Considering the `my_value` from the code sample for static type dispatcher is intact, the code can be rewritten as follows:
49
50[example_util_dynamic_type_dispatcher]
51
52[@boost:/libs/log/example/doc/util_dynamic_type_disp.cpp See the complete code].
53
54Of course, complex function objects, like those provided by __boost_bind__, are also supported.
55
56[endsect]
57
58[section:predef_types Predefined type sequences]
59
60 #include <``[boost_log_utility_type_dispatch_standard_types_hpp]``>
61 #include <``[boost_log_utility_type_dispatch_date_time_types_hpp]``>
62
63One may notice that when using type dispatchers and defining filters and formatters it may be convenient to have some predefined type sequences to designate frequently used sets of types. The library provides several such sets.
64
65[table Standard types (standard_types.hpp)
66 [[Type sequence] [Meaning]]
67 [[`integral_types`] [All integral types, including `bool`, character and 64 bit integral types, if available]]
68 [[`floating_point_types`] [Floating point types]]
69 [[`numeric_types`] [Includes `integral_types` and `floating_point_types`]]
70 [[`string_types`] [Narrow and wide string types. Currently only includes STL string types and [link log.detailed.utilities.string_literal string literals].]]
71]
72
73There are also a number of time-related type sequences available:
74
75[table Time-related types (date_time_types.hpp)
76 [[Type sequence] [Meaning]]
77 [[`native_date_time_types`] [All types defined in C/C++ standard that have both date and time portions]]
78 [[`boost_date_time_types`] [All types defined in __boost_date_time__ that have both date and time portions]]
79 [[`date_time_types`] [Includes `native_date_time_types` and `boost_date_time_types`]]
80 [[`native_date_types`] [All types defined in C/C++ standard that have date portion. Currently equivalent to `native_date_time_types`.]]
81 [[`boost_date_types`] [All types defined in __boost_date_time__ that have date portion]]
82 [[`date_types`] [Includes `native_date_types` and `boost_date_types`]]
83 [[`native_time_types`] [All types defined in C/C++ standard that have time portion. Currently equivalent to `native_date_time_types`.]]
84 [[`boost_time_types`] [All types defined in __boost_date_time__ that have time portion. Currently equivalent to `boost_date_time_types`.]]
85 [[`time_types`] [Includes `native_time_types` and `boost_time_types`]]
86 [[`native_time_duration_types`] [All types defined in C/C++ standard that are used to represent time duration. Currently only includes `double`, as the result type of the `difftime` standard function.]]
87 [[`boost_time_duration_types`] [All time duration types defined in __boost_date_time__]]
88 [[`time_duration_types`] [Includes `native_time_duration_types` and `boost_time_duration_types`]]
89 [[`boost_time_period_types`] [All time period types defined in __boost_date_time__]]
90 [[`time_period_types`] [Currently equivalent to `boost_time_period_types`]]
91]
92
93[endsect]
94
95[section:value_ref Value reference wrapper]
96
97 #include <``[boost_log_utility_value_ref_hpp]``>
98
99The [class_log_value_ref] class template is an optional reference wrapper which is used by the library to refer to the stored attribute values. To a certain degree it shares features of __boost_optional__ and __boost_variant__ components.
100
101The template has two type parameters. The first is the referred type. It can also be specified as a __boost_mpl__ type sequence, in which case the [class_log_value_ref] wrapper may refer to either type in the sequence. In this case, the `which` method will return the index of the referred type within the sequence. The second template parameter is an optional tag type which can be used to customize formatting behavior. This tag is forwarded to the [link log.detailed.utilities.manipulators.to_log `to_log`] manipulator when the wrapper is put to a [class_log_basic_formatting_ostream] stream, which is used by the library for record formatting. For an example see how attribute value extraction is implemented:
102
103[example_attr_value_extraction_multiple_types]
104
105[@boost:/libs/log/example/doc/attr_value_extraction.cpp See the complete code].
106
107The [class_log_value_ref] wrapper also supports applying a visitor function object to the referred object. This can be done by calling one of the following methods:
108
109* `apply_visitor`. This method should only be used on a valid (non-empty) reference. The method returns the visitor result.
110* `apply_visitor_optional`. The method checks if the reference is valid and applies the visitor to the referred value if it is. The method returns the visitor result wrapped into `boost::optional` which will be filled only if the reference is valid.
111* `apply_visitor_or_default`. If the reference is valid, the method applies the visitor on the referred value and returns its result. Otherwise the method returns a default value passed as the second argument.
112
113[note Regardless of the method used, the visitor function object [_must] define the `result_type` typedef. Polymorphic visitors are not supported as this would complicate the [class_log_value_ref] interface too much. This requirement also precludes free functions and C++11 lambda functions from being used as visitors. Please, use __boost_bind__ or similar wrappers in such cases.]
114
115Here is an example of applying a visitor:
116
117[example_attr_value_extraction_visitor]
118
119[endsect]
120
121[section:record_ordering Log record ordering]
122
123 #include <``[boost_log_utility_record_ordering_hpp]``>
124
125There are cases when log records need to be ordered. One possible use case is storing records in a container or a priority queue. The library provides two types of record ordering predicates out of the box:
126
127[heading Abstract record ordering]
128
129The [class_log_abstract_ordering] class allows application of a quick opaque ordering. The result of this ordering is not stable between different runs of the application and in general cannot be predicted before the predicate is applied, however it provides the best performance. The [class_log_abstract_ordering] class is a template that is specialized with an optional predicate function that will be able to compare `const void*` pointers. By default an `std::less` equivalent is used.
130
131 // A set of unique records
132 std::set< logging::record_view, logging::abstract_ordering< > > m_Records;
133
134This kind of ordering can be useful if the particular order of log records is not important but nevertheless some order is required.
135
136[heading Attribute value based ordering]
137
138This kind of ordering is implemented with the [class_log_attribute_value_ordering] class and is based on the attribute values attached to the record. The predicate will seek for an attribute value with the specified name in both records being ordered and attempt to compare the attribute values.
139
140 // Ordering type definition
141 typedef logging::attribute_value_ordering<
142 int // attribute value type
143 > ordering;
144
145 // Records organized into a queue based on the "Severity" attribute value
146 std::priority_queue<
147 logging::record_view,
148 std::vector< logging::record_view >,
149 ordering
150 > m_Records(ordering("Severity"));
151
152Like the [class_log_abstract_ordering], [class_log_attribute_value_ordering] also accepts the second optional template parameter, which should be the predicate to compare attribute values (`int`s in the example above). By default, an `std::less` equivalent is used.
153
154You can also use the [funcref boost::log::make_attr_ordering `make_attr_ordering`] generator function to automatically generate the [class_log_attribute_value_ordering] instance based on the attribute value name and the ordering function. This might be useful if the ordering function has a non-trivial type, like the ones __boost_bind__ provides.
155
156[endsect]
157
158[section:exception_handlers Exception handlers]
159
160 #include <``[boost_log_utility_exception_handler_hpp]``>
161
162The library provides exception handling hooks in different places. Tools, defined in this header, provide an easy way of implementing function objects suitable for such hooks.
163
164An exception handler is a function object that accepts no arguments. The result of the exception handler is ignored and thus should generally be `void`. Exception handlers are called from within `catch` sections by the library, therefore in order to reacquire the exception object it has to rethrow it. The header defines an [class_log_exception_handler] template functor that does just that and then forwards the exception object to a unary user-defined functional object. The [funcref boost::log::make_exception_handler `make_exception_handler`] function can be used to simplify the handler construction. All expected exception types should be specified explicitly in the call, in the order they would appear in the `catch` sections (i.e. from most specific ones to the most general ones).
165
166[example_utility_exception_handler]
167
168As you can see, you can either suppress the exception by returning normally from `operator()` in the user-defined handler functor, or rethrow the exception, in which case it will propagate further. If it appears that the exception handler is invoked for an exception type that cannot be caught by any of the specified types, the exception will be propagated without any processing. In order to catch such situations, there exists the [class_log_nothrow_exception_handler] class. It invokes the user-defined functor with no arguments if it cannot determine the exception type.
169
170[example_utility_exception_handler_nothrow]
171
172It is sometimes convenient to completely suppress all exceptions at a certain library level. The [funcref boost::log::make_exception_suppressor `make_exception_suppressor`] function creates an exception handler that simply does nothing upon exception being caught. For example, this way we can disable all exceptions from the logging library:
173
174 void init_logging()
175 {
176 boost::shared_ptr< logging::core > core = logging::core::get();
177
178 // Disable all exceptions
179 core->set_exception_handler(logging::make_exception_suppressor());
180 }
181
182[endsect]
183
184[section:manipulators Output manipulators]
185
186The library provides a number of stream manipulators that may be useful in some contexts.
187
188[section:to_log Customized logging manipulator]
189
190 #include <``[boost_log_utility_manipulators_to_log_hpp]``>
191
192The [funcref boost::log::to_log `to_log`] function creates a stream manipulator that simply outputs the adopted value to the stream. By default its behavior is equivalent to simply putting the value to the stream. However, the user is able to overload the `operator<<` for the adopted value to override formatting behavior when values are formatted for logging purposes. This is typically desired when the regular `operator<<` is employed for other tasks (such as serialization) and its behavior is neither suitable for logging nor can be easily changed. For example:
193
194[example_utility_manipulators_to_log]
195
196The second streaming statement in the `test_manip` function will invoke our custom stream insertion operator which defines special formatting rules.
197
198It is also possible to define different formatting rules for different value contexts as well. The library uses this feature to allow different formatting ruled for different attribute values, even if the stored value type is the same. To do so one has to specify an explicit template argument for [funcref boost::log::to_log `to_log`], a tag type, which will be embedded into the manipulator type and thus will allow to define different insertion operators:
199
200[example_utility_manipulators_to_log_with_tag]
201
202[@boost:/libs/log/example/doc/util_manip_to_log.cpp See the complete code].
203
204[note The library uses [class_log_basic_formatting_ostream] stream type for record formatting, so when customizing attribute value formatting rules the `operator<<` must use [class_log_basic_formatting_ostream] instead of `std::ostream`.]
205
206[endsect]
207
208[section:add_value Attribute value attaching manipulator]
209
210 #include <``[boost_log_utility_manipulators_add_value_hpp]``>
211
212The [funcref boost::log::add_value `add_value`] function creates a manipulator that attaches an attribute value to a log record. This manipulator can only be used in streaming expressions with the [class_log_basic_record_ostream] stream type (which is the case when log record message is formatted). Since the message text is only formatted after filtering, attribute values attached with this manipulator do not affect filtering and can only be used in formatters and sinks themselves.
213
214In addition to the value itself, the manipulator also requires the attribute name to be provided. For example:
215
216 // Creates a log record with attribute value "MyAttr" of type int attached
217 BOOST_LOG(lg) << logging::add_value("MyAttr", 10) << "Hello world!";
218
219[endsect]
220
221[section:dump Binary dump manipulator]
222
223 #include <``[boost_log_utility_manipulators_dump_hpp]``>
224
225The [funcref boost::log::dump `dump`] function creates a manipulator that outputs binary contents of a contiguous memory region. This can be useful for logging some low level binary data, such as encoded network packets or entries of a binary file. The use is quite straightforward:
226
227 void on_receive(std::vector< unsigned char > const& packet)
228 {
229 // Outputs something like "Packet received: 00 01 02 0a 0b 0c"
230 BOOST_LOG(lg) << "Packet received: " << logging::dump(packet.data(), packet.size());
231 }
232
233The manipulator also allows to limit the amount of data to be output, in case if the input data can be too large. Just specify the maximum number of bytes of input to dump as the last argument:
234
235 void on_receive(std::vector< unsigned char > const& packet)
236 {
237 // Outputs something like "Packet received: 00 01 02 03 04 05 06 07 and 67 bytes more"
238 BOOST_LOG(lg) << "Packet received: " << logging::dump(packet.data(), packet.size(), 8);
239 }
240
241There is another manipulator called [funcref boost::log::dump_elements `dump_elements`] for printing binary representation of non-byte array elements. The special manipulator for this case is necessary because the units of the size argument of [funcref boost::log::dump `dump`] can be confusing (is it in bytes or in elements?). Therefore [funcref boost::log::dump `dump`] will not compile when used for non-byte input data. [funcref boost::log::dump_elements `dump_elements`] accepts the same arguments, and its size-related arguments always designate the number of elements to process.
242
243 void process(std::vector< double > const& matrix)
244 {
245 // Note that dump_elements accepts the number of elements in the matrix, not its size in bytes
246 BOOST_LOG(lg) << "Matrix dump: " << logging::dump_elements(matrix.data(), matrix.size());
247 }
248
249[tip Both these manipulators can also be used with regular output streams, not necessarily loggers.]
250
251[endsect]
252
253[endsect]
254
255[section:ipc Interprocess communication tools]
256
257[section:object_name Resource name wrapper]
258
259 #include <``[boost_log_utility_ipc_object_name_hpp]``>
260
261In modern operating systems process-shared system resources are typically identified with names. Unfortunately, different systems have different requirements on the name syntax and allowed character set. Additionally, some systems offer support for namespaces in order to avoid name clashes. The [class_ipc_object_name] class is intended to hide these differences.
262
263An object name can be constructed from a UTF-8 string identifier and a scope. A portable identifier can contain the following characters:
264
265[teletype]
266
267 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
268 a b c d e f g h i j k l m n o p q r s t u v w x y z
269 0 1 2 3 4 5 6 7 8 9 . _ -
270
271[c++]
272
273[note The character set corresponds to [@http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_278 POSIX Portable Filename Character Set].]
274
275Use of other characters may result in non-portable system-specific behavior.
276
277The scope is identified with the `object_name::scope` enumeration:
278
279* `global` - The name has global scope; any process in the system has the potential to open the resource identified by the name. On some systems this scope may not be available or require elevated privileges.
280* `user` - The name is limited to processes running under the current user.
281* `session` - The name is limited to processes running in the current login session.
282* `process_group` - The name is limited to processes running in the current process group. Currently, on Windows all processes running in the current session are considered members of the same process group. This may change in future.
283
284The scopes are not overlapping. For instance, if an object is created in the global scope, the object cannot be opened with the same name but in user's scope. Some of the scopes may require elevated privileges to create or open objects in.
285
286[warning Object name scoping should not be considered a security measure. Objects may still be accessible by processes outside of their name scopes. The main purpose of the scopes is to avoid name clashes between different processes using [class_ipc_object_name]. Use access permissions for security control.]
287
288[endsect]
289
290[section:reliable_message_queue Reliable message queue]
291
292 #include <``[boost_log_utility_ipc_reliable_message_queue_hpp]``>
293
294The [class_ipc_reliable_message_queue] class implements a reliable one-way channel of passing messages from one or multiple writers to a single reader. The format of the messages is user-defined and must be consistent across all writers and the reader. The queue does not enforce any specific format of the messages, other than they should be supplied as a contiguous array of bytes. The queue internally uses a process-shared storage identified by an [link log.detailed.utilities.ipc.object_name object name] (the queue name).
295
296The queue storage is organized as a fixed number of blocks of a fixed size. The block size must be an integer power of 2 and is expressed in bytes. Each written message, together with some metadata added by the queue, consumes an integer number of blocks. Each read message received by the reader releases the blocks allocated for that message. As such the maximum size of a message is slightly less than block size times capacity of the queue. For efficiency, it is recommended to choose block size large enough to accommodate most of the messages to be passed through the queue. The queue is considered empty when no messages are enqueued (all blocks are free). The queue is considered full at the point of enqueueing a message when there is not enough free blocks to accommodate the message.
297
298The queue is reliable in that it will not drop successfully sent messages that are not received by the reader, other than the case when a non-empty queue is destroyed by the last user. If a message cannot be enqueued by the writer because the queue is full, the queue will act depending on the overflow policy specified at the queue creation:
299
300* `block_on_overflow` - Block the thread until there is enough space to enqueue the message or the operation is aborted by calling `stop_local`.
301* `fail_on_overflow` - Return an error code from the send operation. The error code is `operation_result::no_space`.
302* `throw_on_overflow` - Throw an exception from the send operation. The exception is [class_log_capacity_limit_reached].
303
304The policy is object local, i.e. different writers and the reader can have different overflow policies. Here is an example of writing to the message queue:
305
306[example_util_ipc_reliable_mq_writer]
307
308[@boost:/libs/log/example/doc/util_ipc_reliable_mq_writer.cpp See the complete code].
309
310Typically, the queue would be used for sending log records to a different process. As such, instead of using the queue for writing directly, one would use a special sink backend for that. See [link log.detailed.sink_backends.text_ipc_message_queue `text_ipc_message_queue_backend`] documentation.
311
312Receiving messages from the queue is similar. Here is an example of a log viewer that receives messages from the queue and displays them on the console.
313
314[example_sinks_ipc_receiver]
315
316[@boost:/libs/log/example/doc/sinks_ipc_receiver.cpp See the complete code].
317
318[note The queue does not guarantee any particular order of received messages from different writer threads. Messages sent by a particular writer thread will be received in the order of sending.]
319
320A blocked reader or writer can be unblocked by calling `stop_local`. After this method is called, all threads blocked on this particular object are released and return `operation_result::aborted`. The other instances of the queue (in the current or other processes) are unaffected. In order to restore the normal functioning of the queue instance after the `stop_local` call the user has to invoke `reset_local`.
321
322[endsect]
323
324[endsect]
325
326[section:setup Simplified library initialization tools]
327
328This part of the library is provided in order to simplify logging initialization and provide basic tools to develop user-specific initialization mechanisms. It is known that setup capabilities and preferences may vary widely from application to application, therefore the library does not attempt to provide a universal solution for this task. The provided tools are mostly intended to serve as a quick drop-in support for logging setup and a set of instruments to implement something more elaborate and more fitting users' needs.
329
330Some of the features described in this section will require the separate library binary, with name based on "boost_log_setup" substring. This binary depends on the main library.
331
332[section:convenience Convenience functions]
333
334 #include <``[boost_log_utility_setup_console_hpp]``>
335 #include <``[boost_log_utility_setup_file_hpp]``>
336 #include <``[boost_log_utility_setup_common_attributes_hpp]``>
337
338The library provides a number of functions that simplify some common initialization procedures, like sink and commonly used attributes registration. This is not much functionality. However, it saves a couple of minutes of learning the library for a newcomer.
339
340Logging to the application console is the simplest way to see the logging library in action. To achieve this, one can initialize the library with a single function call, like this:
341
342 int main(int, char*[])
343 {
344 // Initialize logging to std::clog
345 logging::add_console_log();
346
347 // Here we go, we can write logs right away
348 src::logger lg;
349 BOOST_LOG(lg) << "Hello world!";
350
351 return 0;
352 }
353
354Pretty easy, isn't it? There is also the `wadd_console_log` function for wide-character console. If you want to put logs to some other standard stream, you can pass the stream to the [funcref boost::log::add_console_log `add_console_log`] function as an argument. E.g. enabling logging to `std::cout` instead of `std::clog` would look like this:
355
356 logging::add_console_log(std::cout);
357
358What's important, is that you can further manage the console sink if you save the `shared_ptr` to the sink that this function returns. This allows you to set up things like filter, formatter and auto-flush flag.
359
360 int main(int, char*[])
361 {
362 // Initialize logging to std::clog
363 boost::shared_ptr<
364 sinks::synchronous_sink< sinks::text_ostream_backend >
365 > sink = logging::add_console_log();
366
367 sink->set_filter(expr::attr< int >("Severity") >= 3);
368 sink->locked_backend()->auto_flush(true);
369
370 // Here we go, we can write logs right away
371 src::logger lg;
372 BOOST_LOG(lg) << "Hello world!";
373
374 return 0;
375 }
376
377Similarly to console, one can use a single function call to enable logging to a file. All you have to do is to provide the file name:
378
379 int main(int, char*[])
380 {
381 // Initialize logging to the "test.log" file
382 logging::add_file_log("test.log");
383
384 // Here we go, we can write logs right away
385 src::logger lg;
386 BOOST_LOG(lg) << "Hello world!";
387
388 return 0;
389 }
390
391The [funcref boost::log::add_console_log `add_console_log`] and [funcref boost::log::add_file_log `add_file_log`] functions do not conflict and may be combined freely, so it is possible to set up logging to the console and a couple of files, including filtering and formatting, in about 10 lines of code.
392
393Lastly, there is an [funcref boost::log::add_common_attributes `add_common_attributes`] function that registers two frequently used attributes: "LineID" and "TimeStamp". The former counts log record being made and has attribute value `unsigned int`. The latter, as its name implies, provides the current time for each log record, in the form of `boost::posix_time::ptime` (see __boost_date_time__). These two attributes are registered globally, so they will remain available in all threads and loggers. This makes the final version of our code sample look something like this:
394
395 int main(int, char*[])
396 {
397 // Initialize sinks
398 logging::add_console_log()->set_filter(expr::attr< int >("Severity") >= 4);
399
400 logging::formatter formatter =
401 expr::stream
402 << expr::attr< unsigned int >("LineID") << ": "
403 << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d %H:%M:%S") << " *"
404 << expr::attr< int >("Severity") << "* "
405 << expr::message;
406
407 logging::add_file_log("complete.log")->set_formatter(formatter);
408
409 boost::shared_ptr<
410 sinks::synchronous_sink< sinks::text_ostream_backend >
411 > sink = logging::add_file_log("essential.log");
412 sink->set_formatter(formatter);
413 sink->set_filter(expr::attr< int >("Severity") >= 1);
414
415 // Register common attributes
416 logging::add_common_attributes();
417
418 // Here we go, we can write logs
419 src::logger lg;
420 BOOST_LOG(lg) << "Hello world!";
421
422 return 0;
423 }
424
425[endsect]
426
427[section:filter_formatter Filter and formatter parsers]
428
429 #include <``[boost_log_utility_setup_filter_parser_hpp]``>
430 #include <``[boost_log_utility_setup_formatter_parser_hpp]``>
431
432Filter and formatter parsers allow constructing filters and formatters from a descriptive string. The function `parse_filter` is responsible for recognizing filters and `parse_formatter` - for recognizing formatters.
433
434In the case of filters the string is formed of a sequence of condition expressions, interconnected with boolean operations. There are two operations supported: conjunction (designated as "&" or "and") and disjunction ("|" or "or"). Each condition itself may be either a single condition or a sub-filter, taken in round brackets. Each condition can be negated with the "!" sign or "not" keyword. The condition, if it's not a sub-filter, usually consists of an attribute name enclosed in percent characters ("%"), a relation keyword and an operand. The relation and operand may be omitted, in which case the condition is assumed to be the requirement of the attribute presence (with any type).
435
436[teletype]
437
438 filter:
439 condition { op condition }
440
441 op:
442 &
443 and
444 |
445 or
446
447 condition:
448 !condition
449 not condition
450 (filter)
451 %attribute_name%
452 %attribute_name% relation operand
453
454 relation:
455 >
456 <
457 =
458 !=
459 >=
460 <=
461 begins_with
462 ends_with
463 contains
464 matches
465
466[c++]
467
468Below are some examples of filters:
469
470[table Examples of filters
471[[Filter string] [Description]]
472[[`%Severity%`] [The filter returns `true` if an attribute value with name "Severity" is found in a log record.]]
473[[`%Severity% > 3`] [The filter returns `true` if an attribute value with name "Severity" is found and it is greater than 3. The attribute value must be of one of the [link log.detailed.utilities.predef_types integral types].]]
474[[!(`%Ratio% > 0.0 & %Ratio% <= 0.5)`] [The filter returns `true` if an attribute value with name "Ratio" of one of the [link log.detailed.utilities.predef_types floating point types] is not found or it is not between 0 and 0.5.]]
475[[`%Tag% contains "net" or %Tag% contains "io" and not %StatFlow%`] [The filter returns `true` if an attribute value with name "Tag" is found and contains words "net" or "io" and if an attribute value "StatFlow" is not found. The "Tag" attribute value must be of one of the [link log.detailed.utilities.predef_types string types], the "StatFlow" attribute value type is not considered.]]
476]
477
478The formatter string syntax is even simpler and pretty much resembles __boost_format__ format string syntax. The string is interpreted as a template which can contain attribute names enclosed with percent signs ("%"). The corresponding attribute values will replace these placeholders when the formatter is applied. The placeholder "%Message%" will be replaced with the log record text. For instance, the following formatter string:
479
480[teletype]
481
482 [%TimeStamp%] *%Severity%* %Message%
483
484[c++]
485
486will make log records look like this:
487
488[teletype]
489
490 [2008-07-05 13:44:23] *0* Hello world
491
492[c++]
493
494[note Previous releases of the library also supported the "%\_%" placeholder for the message text. This placeholder is deprecated now, although it still works for backward compatibility. Its support will be removed in future releases.]
495
496It must be noted that by default the library only supports those attribute value types [link log.detailed.utilities.predef_types which are known] at the library build time. User-defined types will not work properly in parsed filters and formatters until registered in the library. It is also possible to override formatting rules of the known types, including support for additional formatting parameters in the string template. More on this is available in the [link log.extension.settings Extending the library] section.
497
498[note The parsed formatters and filters are generally less optimal than the equivalent ones written in code with [link log.detailed.expressions template expressions]. This is because of two reasons: (\*) the programmer usually knows more about types of the attribute values that may be involved in formatting or filtering and (\*) the compiler has a better chance to optimize the formatter or filter if it is known in compile time. Therefore, when performance matters, it is advised to avoid parsed filters and formatters.]
499
500[endsect]
501
502[section:settings Library initialization from a settings container]
503
504 #include <``[boost_log_utility_setup_settings_hpp]``>
505 #include <``[boost_log_utility_setup_from_settings_hpp]``>
506
507The headers define components for library initialization from a settings container. The settings container is basically a set of named parameters divided into sections. The container is implemented with the [class_log_basic_settings] class template. There are several constraints on how parameters are stored in the container:
508
509* Every parameter must reside in a section. There can be no parameters that do not belong to a section.
510* Parameters must have names unique within the section they belong to. Parameters from different sections may have the same name.
511* Sections can nest. When read from a file or accessed from the code, section names can express arbitrary hierarchy by separating the parent and child section names with '.' (e.g. "\[Parent.Child.ChildChild\]").
512* Sections must have names unique within the enclosing section (or global scope, if the section is top level).
513
514So basically, settings container is a layered associative container, with string keys and values. In some respect it is similar to __boost_property_tree__, and in fact it supports construction from `boost::ptree`. The supported parameters are described below.
515
516[tip In the tables below, the `CharT` type denotes the character type that is used with the settings container.]
517
518[table Section "Core". Logging core settings.
519[[Parameter] [Format] [Description]]
520[[Filter] [Filter string as described [link log.detailed.utilities.setup.filter_formatter here]]
521 [Global filter to be installed to the core. If not specified, the global filter is not set.]
522]
523[[DisableLogging] ["true" or "false"]
524 [If `true`, results in calling `set_logging_enabled(false)` on the core. By default, value `false` is assumed.]
525]
526]
527
528Sink settings are divided into separate subsections within the common top-level section "Sinks" - one subsection for each sink. The subsection names denote a user-defined sink name. For example, "MyFile".
529
530[note Previous versions of the library also supported top-level sections starting with the "Sink:" prefix to describe sink parameters. This syntax is deprecated now, although it still works when parsing a settings file for backward compatibility. The parser will automatically put these sections under the "Sinks" top-level section in the resulting settings container. Support for this syntax will be removed in future releases.]
531
532[table Sections under the "Sinks" section. Common sink settings.
533[[Parameter] [Format] [Description]]
534[[Destination] [Sink target, see description]
535 [Sink backend type. Mandatory parameter. May have one of these values: [link log.detailed.sink_backends.text_ostream Console], [link log.detailed.sink_backends.text_file TextFile], [link log.detailed.sink_backends.syslog Syslog]. On Windows the following values are additionally supported: [link log.detailed.sink_backends.event_log SimpleEventLog], [link log.detailed.sink_backends.debugger Debugger]. Also, user-defined sink names may also be supported if registered by calling `register_sink_factory`.]
536]
537[[Filter] [Filter string as described [link log.detailed.utilities.setup.filter_formatter here]]
538 [Sink-specific filter. If not specified, the filter is not set.]
539]
540[[Asynchronous] ["true" or "false"]
541 [If `true`, the [link log.detailed.sink_frontends.async asynchronous sink frontend] will be used. Otherwise the [link log.detailed.sink_frontends.sync synchronous sink frontend] will be used. By default, value `false` is assumed. In single-threaded builds this parameter is not used, as [link log.detailed.sink_frontends.unlocked unlocked sink frontend] is always used.]
542]
543]
544
545Besides the common settings that all sinks support, some sink backends also accept a number of specific parameters. These parameters should be specified in the same section.
546
547[table "Console" sink settings
548[[Parameter] [Format] [Description]]
549[[Format] [Format string as described [link log.detailed.utilities.setup.filter_formatter here]]
550 [Log record formatter to be used by the sink. If not specified, the default formatter is used.]
551]
552[[AutoFlush] ["true" or "false"]
553 [Enables or disables the auto-flush feature of the backend. If not specified, the default value `false` is assumed.]
554]
555]
556
557[table "TextFile" sink settings
558[[Parameter] [Format] [Description]]
559[[FileName] [File name pattern]
560 [The file name pattern for the sink backend. This parameter is mandatory.]
561]
562[[Format] [Format string as described [link log.detailed.utilities.setup.filter_formatter here]]
563 [Log record formatter to be used by the sink. If not specified, the default formatter is used.]
564]
565[[AutoFlush] ["true" or "false"]
566 [Enables or disables the auto-flush feature of the backend. If not specified, the default value `false` is assumed.]
567]
568[[RotationSize] [Unsigned integer]
569 [File size, in bytes, upon which file rotation will be performed. If not specified, no size-based rotation will be made.]
570]
571[[RotationInterval] [Unsigned integer]
572 [Time interval, in seconds, upon which file rotation will be performed. See also the RotationTimePoint parameter and the note below.]
573]
574[[RotationTimePoint] [Time point format string, see below]
575 [Time point or a predicate that detects at what moment of time to perform log file rotation. See also the RotationInterval parameter and the note below.]
576]
577[[Target] [File system path to a directory]
578 [Target directory name, in which the rotated files will be stored. If this parameter is specified, rotated file collection is enabled. Otherwise the feature is not enabled, and all corresponding parameters are ignored.]
579]
580[[MaxSize] [Unsigned integer]
581 [Total size of files in the target directory, in bytes, upon which the oldest file will be deleted. If not specified, no size-based file cleanup will be performed.]
582]
583[[MinFreeSpace] [Unsigned integer]
584 [Minimum free space in the target directory, in bytes, upon which the oldest file will be deleted. If not specified, no space-based file cleanup will be performed.]
585]
586[[MaxFiles] [Unsigned integer]
587 [Total number of files in the target directory, upon which the oldest file will be deleted. If not specified, no count-based file cleanup will be performed.]
588]
589[[ScanForFiles] ["All" or "Matching"]
590 [Mode of scanning for old files in the target directory, see [enumref boost::log::sinks::file::scan_method `scan_method`]. If not specified, no scanning will be performed.]
591]
592]
593
594[warning The text file sink uses __boost_filesystem__ internally, which may cause problems on process termination. See [link log.rationale.why_crash_on_term here] for more details.]
595
596The time-based rotation can be set up with one of the two parameters: RotationInterval or RotationTimePoint. Not more than one of these parameters should be specified for a given sink. If none is specified, no time-based rotation will be performed.
597
598The RotationTimePoint parameter should have one of the following formats, according to the __boost_date_time_format__ format notation:
599
600* "%H:%M:%S". In this case, file rotation will be performed on a daily basis, at the specified time. For example, "12:00:00".
601* "%a %H:%M:%S" or "%A %H:%M:%S". File rotation takes place every week, on the weekday specified in the long or short form, at the specified time. For example, "Saturday 09:00:00".
602* "%d %H:%M:%S". File rotation takes place every month, on the specified day of month, at the specified time. For example, "01 23:30:00".
603
604[table "Syslog" sink settings
605[[Parameter] [Format] [Description]]
606[[Format] [Format string as described [link log.detailed.utilities.setup.filter_formatter here]]
607 [Log record formatter to be used by the sink. If not specified, the default formatter is used.]
608]
609[[LocalAddress] [An IP address]
610 [Local address to initiate connection to the syslog server. If not specified, the default local address will be used.]
611]
612[[TargetAddress] [An IP address]
613 [Remote address of the syslog server. If not specified, the local address will be used.]
614]
615]
616
617[table "SimpleEventLog" sink settings
618[[Parameter] [Format] [Description]]
619[[Format] [Format string as described [link log.detailed.utilities.setup.filter_formatter here]]
620 [Log record formatter to be used by the sink. If not specified, the default formatter is used.]
621]
622[[LogName] [A string]
623 [Log name to write events into. If not specified, the default log name will be used.]
624]
625[[LogSource] [A string]
626 [Log source to write events from. If not specified, the default source will be used.]
627]
628[[Registration] ["Never", "OnDemand" or "Forced"]
629 [Mode of log source registration in Windows registry, see [enumref boost::log::sinks::event_log::registration_mode `registration_mode`]. If not specified, on-demand registration will be performed.]
630]
631]
632
633The user is free to fill the settings container from whatever settings source he needs. The usage example is below:
634
635 void init_logging()
636 {
637 logging::settings setts;
638
639 setts["Core"]["Filter"] = "%Severity% >= warning";
640 setts["Core"]["DisableLogging"] = false;
641
642 // Subsections can be referred to with a single path
643 setts["Sinks.Console"]["Destination"] = "Console";
644 setts["Sinks.Console"]["Filter"] = "%Severity% >= fatal";
645 setts["Sinks.Console"]["AutoFlush"] = true;
646
647 // ...as well as the individual parameters
648 setts["Sinks.File.Destination"] = "TextFile";
649 setts["Sinks.File.FileName"] = "MyApp_%3N.log";
650 setts["Sinks.File.AutoFlush"] = true;
651 setts["Sinks.File.RotationSize"] = 10 * 1024 * 1024; // 10 MiB
652
653 logging::init_from_settings(setts);
654 }
655
656The settings reader also allows to be extended to support custom sink types. See the [link log.extension.settings Extending the library] section for more information.
657
658[endsect]
659
660[section:settings_file Library initialization from a settings file]
661
662 #include <``[boost_log_utility_setup_from_stream_hpp]``>
663
664Support for configuration files is a frequently requested feature of the library. And despite the fact there is no ultimately convenient and flexible format of the library settings, the library provides preliminary support for this feature. The functionality is implemented with a simple function [funcref boost::log::init_from_stream `init_from_stream`], which accepts an STL input stream and reads the library settings from it. The function then passes on the read settings to the [funcref boost::log::init_from_settings `init_from_settings`] function, described [link log.detailed.utilities.setup.settings above]. Therefore the parameter names and their meaning is the same as for the [funcref boost::log::init_from_settings `init_from_settings`] function.
665
666The settings format is quite simple and widely used. Below is the description of syntax and parameters.
667
668[teletype]
669
670 # Comments are allowed. Comment line begins with the '#' character
671 # and spans until the end of the line.
672
673 # Logging core settings section. May be omitted if no parameters specified within it.
674 [Core]
675 DisableLogging=false
676 Filter="%Severity% > 3"
677
678 # Sink settings sections
679 [Sinks.MySink1]
680
681 # Sink destination type
682 Destination=Console
683
684 # Sink-specific filter. Optional, by default no filter is applied.
685 Filter="%Target% contains \"MySink1\""
686
687 # Formatter string. Optional, by default only log record message text is written.
688 Format="<%TimeStamp%> - %Message%"
689
690 # The flag shows whether the sink should be asynchronous
691 Asynchronous=false
692
693 # Enables automatic stream flush after each log record.
694 AutoFlush=true
695
696[c++]
697
698Here's the usage example:
699
700 int main(int, char*[])
701 {
702 // Read logging settings from a file
703 std::ifstream file("settings.ini");
704 logging::init_from_stream(file);
705
706 return 0;
707 }
708
709[endsect]
710
711[endsect]
712
713[endsect]