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/date_time/posix_time/posix_time.hpp>
16 #include <boost/log/core.hpp>
17 #include <boost/log/expressions.hpp>
18 #include <boost/log/attributes.hpp>
19 #include <boost/log/sources/basic_logger.hpp>
20 #include <boost/log/sources/severity_logger.hpp>
21 #include <boost/log/sources/record_ostream.hpp>
22 #include <boost/log/sinks/sync_frontend.hpp>
23 #include <boost/log/sinks/text_ostream_backend.hpp>
24 #include <boost/log/attributes/scoped_attribute.hpp>
25 #include <boost/log/utility/setup/common_attributes.hpp>
26
27 namespace logging = boost::log;
28 namespace src = boost::log::sources;
29 namespace expr = boost::log::expressions;
30 namespace sinks = boost::log::sinks;
31 namespace attrs = boost::log::attributes;
32 namespace keywords = boost::log::keywords;
33
34 // We define our own severity levels
35 enum severity_level
36 {
37 normal,
38 notification,
39 warning,
40 error,
41 critical
42 };
43
44 BOOST_LOG_ATTRIBUTE_KEYWORD(line_id, "LineID", unsigned int)
45 BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", severity_level)
46 BOOST_LOG_ATTRIBUTE_KEYWORD(tag_attr, "Tag", std::string)
47 BOOST_LOG_ATTRIBUTE_KEYWORD(scope, "Scope", attrs::named_scope::value_type)
48 BOOST_LOG_ATTRIBUTE_KEYWORD(timeline, "Timeline", attrs::timer::value_type)
49
logging_function()50 void logging_function()
51 {
52 src::severity_logger< severity_level > slg;
53
54 BOOST_LOG_SEV(slg, normal) << "A regular message";
55 BOOST_LOG_SEV(slg, warning) << "Something bad is going on but I can handle it";
56 BOOST_LOG_SEV(slg, critical) << "Everything crumbles, shoot me now!";
57 }
58
59 //[ example_tutorial_attributes_named_scope
named_scope_logging()60 void named_scope_logging()
61 {
62 BOOST_LOG_NAMED_SCOPE("named_scope_logging");
63
64 src::severity_logger< severity_level > slg;
65
66 BOOST_LOG_SEV(slg, normal) << "Hello from the function named_scope_logging!";
67 }
68 //]
69
70 //[ example_tutorial_attributes_tagged_logging
tagged_logging()71 void tagged_logging()
72 {
73 src::severity_logger< severity_level > slg;
74 slg.add_attribute("Tag", attrs::constant< std::string >("My tag value"));
75
76 BOOST_LOG_SEV(slg, normal) << "Here goes the tagged record";
77 }
78 //]
79
80 //[ example_tutorial_attributes_timed_logging
timed_logging()81 void timed_logging()
82 {
83 BOOST_LOG_SCOPED_THREAD_ATTR("Timeline", attrs::timer());
84
85 src::severity_logger< severity_level > slg;
86 BOOST_LOG_SEV(slg, normal) << "Starting to time nested functions";
87
88 logging_function();
89
90 BOOST_LOG_SEV(slg, normal) << "Stopping to time nested functions";
91 }
92 //]
93
94 // The operator puts a human-friendly representation of the severity level to the stream
operator <<(std::ostream & strm,severity_level level)95 std::ostream& operator<< (std::ostream& strm, severity_level level)
96 {
97 static const char* strings[] =
98 {
99 "normal",
100 "notification",
101 "warning",
102 "error",
103 "critical"
104 };
105
106 if (static_cast< std::size_t >(level) < sizeof(strings) / sizeof(*strings))
107 strm << strings[level];
108 else
109 strm << static_cast< int >(level);
110
111 return strm;
112 }
113
init()114 void init()
115 {
116 typedef sinks::synchronous_sink< sinks::text_ostream_backend > text_sink;
117 boost::shared_ptr< text_sink > sink = boost::make_shared< text_sink >();
118
119 sink->locked_backend()->add_stream(
120 boost::make_shared< std::ofstream >("sample.log"));
121
122 sink->set_formatter
123 (
124 expr::stream
125 << std::hex << std::setw(8) << std::setfill('0') << line_id << std::dec << std::setfill(' ')
126 << ": <" << severity << ">\t"
127 << "(" << scope << ") "
128 << expr::if_(expr::has_attr(tag_attr))
129 [
130 expr::stream << "[" << tag_attr << "] "
131 ]
132 << expr::if_(expr::has_attr(timeline))
133 [
134 expr::stream << "[" << timeline << "] "
135 ]
136 << expr::smessage
137 );
138
139 logging::core::get()->add_sink(sink);
140
141 // Add attributes
142 logging::add_common_attributes();
143 logging::core::get()->add_global_attribute("Scope", attrs::named_scope());
144 }
145
main(int,char * [])146 int main(int, char*[])
147 {
148 init();
149
150 named_scope_logging();
151 tagged_logging();
152 timed_logging();
153
154 return 0;
155 }
156