• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *          Copyright Andrey Semashev 2007 - 2015.
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 
8 #include <cstddef>
9 #include <string>
10 #include <ostream>
11 #include <fstream>
12 #include <iomanip>
13 #include <boost/smart_ptr/shared_ptr.hpp>
14 #include <boost/smart_ptr/make_shared_object.hpp>
15 #include <boost/phoenix/bind.hpp>
16 #include <boost/date_time/posix_time/posix_time.hpp>
17 #include <boost/log/core.hpp>
18 #include <boost/log/expressions.hpp>
19 #include <boost/log/attributes.hpp>
20 #include <boost/log/sources/basic_logger.hpp>
21 #include <boost/log/sources/severity_logger.hpp>
22 #include <boost/log/sources/severity_channel_logger.hpp>
23 #include <boost/log/sources/record_ostream.hpp>
24 #include <boost/log/sinks/sync_frontend.hpp>
25 #include <boost/log/sinks/text_ostream_backend.hpp>
26 #include <boost/log/attributes/scoped_attribute.hpp>
27 #include <boost/log/utility/value_ref.hpp>
28 #include <boost/log/utility/setup/common_attributes.hpp>
29 
30 namespace logging = boost::log;
31 namespace src = boost::log::sources;
32 namespace expr = boost::log::expressions;
33 namespace sinks = boost::log::sinks;
34 namespace attrs = boost::log::attributes;
35 namespace keywords = boost::log::keywords;
36 
37 // We define our own severity levels
38 enum severity_level
39 {
40     normal,
41     notification,
42     warning,
43     error,
44     critical
45 };
46 
47 // The operator puts a human-friendly representation of the severity level to the stream
operator <<(std::ostream & strm,severity_level level)48 std::ostream& operator<< (std::ostream& strm, severity_level level)
49 {
50     static const char* strings[] =
51     {
52         "normal",
53         "notification",
54         "warning",
55         "error",
56         "critical"
57     };
58 
59     if (static_cast< std::size_t >(level) < sizeof(strings) / sizeof(*strings))
60         strm << strings[level];
61     else
62         strm << static_cast< int >(level);
63 
64     return strm;
65 }
66 
67 //[ example_tutorial_filtering
68 BOOST_LOG_ATTRIBUTE_KEYWORD(line_id, "LineID", unsigned int)
69 BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", severity_level)
70 BOOST_LOG_ATTRIBUTE_KEYWORD(tag_attr, "Tag", std::string)
71 
init()72 void init()
73 {
74     // Setup the common formatter for all sinks
75     logging::formatter fmt = expr::stream
76         << std::setw(6) << std::setfill('0') << line_id << std::setfill(' ')
77         << ": <" << severity << ">\t"
78         << expr::if_(expr::has_attr(tag_attr))
79            [
80                expr::stream << "[" << tag_attr << "] "
81            ]
82         << expr::smessage;
83 
84     // Initialize sinks
85     typedef sinks::synchronous_sink< sinks::text_ostream_backend > text_sink;
86     boost::shared_ptr< text_sink > sink = boost::make_shared< text_sink >();
87 
88     sink->locked_backend()->add_stream(
89         boost::make_shared< std::ofstream >("full.log"));
90 
91     sink->set_formatter(fmt);
92 
93     logging::core::get()->add_sink(sink);
94 
95     sink = boost::make_shared< text_sink >();
96 
97     sink->locked_backend()->add_stream(
98         boost::make_shared< std::ofstream >("important.log"));
99 
100     sink->set_formatter(fmt);
101 
102     sink->set_filter(severity >= warning || (expr::has_attr(tag_attr) && tag_attr == "IMPORTANT_MESSAGE"));
103 
104     logging::core::get()->add_sink(sink);
105 
106     // Add attributes
107     logging::add_common_attributes();
108 }
109 //]
110 
111 #if 0
112 
113 //[ example_tutorial_filtering_bind
114 bool my_filter(logging::value_ref< severity_level, tag::severity > const& level,
115                logging::value_ref< std::string, tag::tag_attr > const& tag)
116 {
117     return level >= warning || tag == "IMPORTANT_MESSAGE";
118 }
119 
120 void init()
121 {
122     //<-
123 
124     // Setup the common formatter for all sinks
125     logging::formatter fmt = expr::stream
126         << std::setw(6) << std::setfill('0') << line_id << std::setfill(' ')
127         << ": <" << severity << ">\t"
128         << expr::if_(expr::has_attr(tag_attr))
129            [
130                expr::stream << "[" << tag_attr << "] "
131            ]
132         << expr::smessage;
133 
134     // Initialize sinks
135     typedef sinks::synchronous_sink< sinks::text_ostream_backend > text_sink;
136     boost::shared_ptr< text_sink > sink = boost::make_shared< text_sink >();
137 
138     sink->locked_backend()->add_stream(
139         boost::make_shared< std::ofstream >("full.log"));
140 
141     sink->set_formatter(fmt);
142 
143     logging::core::get()->add_sink(sink);
144 
145     sink = boost::make_shared< text_sink >();
146 
147     sink->locked_backend()->add_stream(
148         boost::make_shared< std::ofstream >("important.log"));
149 
150     sink->set_formatter(fmt);
151 
152     //->
153     // ...
154 
155     namespace phoenix = boost::phoenix;
156     sink->set_filter(phoenix::bind(&my_filter, severity.or_none(), tag_attr.or_none()));
157 
158     // ...
159     //<-
160 
161     logging::core::get()->add_sink(sink);
162 
163     // Add attributes
164     logging::add_common_attributes();
165 
166     //->
167 }
168 //]
169 
170 #endif
171 
logging_function()172 void logging_function()
173 {
174     src::severity_logger< severity_level > slg;
175 
176     BOOST_LOG_SEV(slg, normal) << "A regular message";
177     BOOST_LOG_SEV(slg, warning) << "Something bad is going on but I can handle it";
178     BOOST_LOG_SEV(slg, critical) << "Everything crumbles, shoot me now!";
179 
180     {
181         BOOST_LOG_SCOPED_THREAD_TAG("Tag", "IMPORTANT_MESSAGE");
182         BOOST_LOG_SEV(slg, normal) << "An important message";
183     }
184 }
185 
main(int,char * [])186 int main(int, char*[])
187 {
188     init();
189 
190     logging_function();
191 
192     return 0;
193 }
194