1 | #include <boost/log/sources/record_ostream.hpp>
|
---|
2 | #include <boost/log/attributes.hpp>
|
---|
3 | #include <boost/log/expressions.hpp>
|
---|
4 | #include <boost/log/sinks/async_frontend.hpp>
|
---|
5 | #include <boost/log/sinks/text_ostream_backend.hpp>
|
---|
6 | #include <boost/log/sources/severity_channel_logger.hpp>
|
---|
7 | #include <boost/log/core.hpp>
|
---|
8 | #include <boost/core/null_deleter.hpp>
|
---|
9 | #include <boost/make_shared.hpp>
|
---|
10 |
|
---|
11 | #include <iostream>
|
---|
12 | #include <fstream>
|
---|
13 |
|
---|
14 | enum Level {
|
---|
15 | A, B, C
|
---|
16 | };
|
---|
17 |
|
---|
18 | enum Group {
|
---|
19 | G0, G1, G2
|
---|
20 | };
|
---|
21 |
|
---|
22 | std::ostream& operator<<(
|
---|
23 | std::ostream& stream,
|
---|
24 | const Level& level
|
---|
25 | ) {
|
---|
26 | static const std::array<std::string, 3> strings = {
|
---|
27 | "A", "B", "C"
|
---|
28 | };
|
---|
29 | const auto levelIndex =
|
---|
30 | static_cast<int>(level)-static_cast<int>(Level::A);
|
---|
31 | assert(levelIndex >= 0);
|
---|
32 | assert(levelIndex < strings.size());
|
---|
33 |
|
---|
34 | return stream << strings[levelIndex];
|
---|
35 | }
|
---|
36 |
|
---|
37 | std::ostream& operator<<(
|
---|
38 | std::ostream& stream,
|
---|
39 | const Group& group
|
---|
40 | ) {
|
---|
41 | static const std::array<std::string, 3> strings = {
|
---|
42 | "G0", "G1", "G2"
|
---|
43 | };
|
---|
44 | const auto groupIndex =
|
---|
45 | static_cast<int>(group) - static_cast<int>(Group::G0);
|
---|
46 | assert(groupIndex >= 0);
|
---|
47 | assert(groupIndex < strings.size());
|
---|
48 |
|
---|
49 | return stream << strings[groupIndex];
|
---|
50 | }
|
---|
51 |
|
---|
52 | namespace
|
---|
53 | {
|
---|
54 | BOOST_LOG_ATTRIBUTE_KEYWORD(level, "Severity", Level)
|
---|
55 | BOOST_LOG_ATTRIBUTE_KEYWORD(group, "Channel", Group)
|
---|
56 | }
|
---|
57 |
|
---|
58 | namespace blog = boost::log;
|
---|
59 | namespace expr = blog::expressions;
|
---|
60 |
|
---|
61 | void formatter(
|
---|
62 | blog::record_view const& record,
|
---|
63 | blog::formatting_ostream& stream
|
---|
64 | ) {
|
---|
65 | stream << "[" << record[level] << "]";
|
---|
66 | stream << "[" << record[group] << "]";
|
---|
67 | stream << " " << record[expr::smessage];
|
---|
68 | }
|
---|
69 |
|
---|
70 | typedef blog::sinks::asynchronous_sink<
|
---|
71 | boost::log::sinks::text_ostream_backend
|
---|
72 | > async_sink_t;
|
---|
73 |
|
---|
74 | auto async_sink0 = boost::make_shared<async_sink_t>();
|
---|
75 | auto async_sink1 = boost::make_shared<async_sink_t>();
|
---|
76 |
|
---|
77 | void init()
|
---|
78 | {
|
---|
79 | async_sink0->locked_backend()->add_stream(
|
---|
80 | boost::shared_ptr<std::ostream>(&std::cout, boost::null_deleter{})
|
---|
81 | );
|
---|
82 | async_sink0->set_formatter(&formatter);
|
---|
83 | blog::core::get()->add_sink(async_sink0);
|
---|
84 |
|
---|
85 | async_sink1->locked_backend()->add_stream(
|
---|
86 | boost::make_shared<std::ofstream>("xxx.log")
|
---|
87 | );
|
---|
88 | async_sink1->set_formatter(&formatter);
|
---|
89 | blog::core::get()->add_sink(async_sink1);
|
---|
90 | }
|
---|
91 |
|
---|
92 | void deinit()
|
---|
93 | {
|
---|
94 | blog::core::get()->remove_sink(async_sink0); // No logs going into sink
|
---|
95 | async_sink0->stop(); // Stop the feed loop
|
---|
96 | async_sink0->flush(); // All the waiting records are flushed to sink
|
---|
97 |
|
---|
98 | blog::core::get()->remove_sink(async_sink1); // No logs going into sink
|
---|
99 | async_sink1->stop(); // Stop the feed loop
|
---|
100 | async_sink1->flush(); // All the waiting records are flushed to sink
|
---|
101 | }
|
---|
102 |
|
---|
103 | // Run this program several times. From time to time (timing issue?) you will see:
|
---|
104 | // [][G0] Foo bar
|
---|
105 | // [B][] Foo bar
|
---|
106 | int main()
|
---|
107 | {
|
---|
108 | init();
|
---|
109 | blog::sources::severity_channel_logger_mt<Level, Group> log;
|
---|
110 |
|
---|
111 | BOOST_LOG_CHANNEL_SEV(log, Group::G0, Level::B) << "Foo bar";
|
---|
112 |
|
---|
113 | deinit();
|
---|
114 |
|
---|
115 | std::cin.get();
|
---|
116 |
|
---|
117 | return 0;
|
---|
118 | }
|
---|