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 <fstream>
11 #include <iostream>
12 #include <stdexcept>
13 #include <boost/smart_ptr/shared_ptr.hpp>
14 #include <boost/smart_ptr/make_shared_object.hpp>
15 #include <boost/thread/shared_mutex.hpp>
16 #include <boost/log/core.hpp>
17 #include <boost/log/expressions.hpp>
18 #include <boost/log/sources/basic_logger.hpp>
19 #include <boost/log/sources/severity_feature.hpp>
20 #include <boost/log/sources/exception_handler_feature.hpp>
21 #include <boost/log/sources/features.hpp>
22 #include <boost/log/sources/record_ostream.hpp>
23 #include <boost/log/sources/global_logger_storage.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/exception_handler.hpp>
28
29 namespace logging = boost::log;
30 namespace src = boost::log::sources;
31 namespace expr = boost::log::expressions;
32 namespace sinks = boost::log::sinks;
33 namespace attrs = boost::log::attributes;
34 namespace keywords = boost::log::keywords;
35
36 //[ example_sources_exception_handler
37 enum severity_level
38 {
39 normal,
40 warning,
41 error
42 };
43
44 // A logger class that allows to intercept exceptions and supports severity level
45 class my_logger_mt :
46 public src::basic_composite_logger<
47 char,
48 my_logger_mt,
49 src::multi_thread_model< boost::shared_mutex >,
50 src::features<
51 src::severity< severity_level >,
52 src::exception_handler
53 >
54 >
55 {
56 BOOST_LOG_FORWARD_LOGGER_MEMBERS(my_logger_mt)
57 };
58
BOOST_LOG_INLINE_GLOBAL_LOGGER_INIT(my_logger,my_logger_mt)59 BOOST_LOG_INLINE_GLOBAL_LOGGER_INIT(my_logger, my_logger_mt)
60 {
61 my_logger_mt lg;
62
63 // Set up exception handler: all exceptions that occur while
64 // logging through this logger, will be suppressed
65 lg.set_exception_handler(logging::make_exception_suppressor());
66
67 return lg;
68 }
69
logging_function()70 void logging_function()
71 {
72 // This will not throw
73 BOOST_LOG_SEV(my_logger::get(), normal) << "Hello, world";
74 }
75 //]
76
77 //[ example_utility_exception_handler
78 struct my_handler
79 {
80 typedef void result_type;
81
operator ()my_handler82 void operator() (std::runtime_error const& e) const
83 {
84 std::cout << "std::runtime_error: " << e.what() << std::endl;
85 }
operator ()my_handler86 void operator() (std::logic_error const& e) const
87 {
88 std::cout << "std::logic_error: " << e.what() << std::endl;
89 throw;
90 }
91 };
92
init_exception_handler()93 void init_exception_handler()
94 {
95 // Setup a global exception handler that will call my_handler::operator()
96 // for the specified exception types
97 logging::core::get()->set_exception_handler(logging::make_exception_handler<
98 std::runtime_error,
99 std::logic_error
100 >(my_handler()));
101 }
102 //]
103
104 //[ example_utility_exception_handler_nothrow
105 struct my_handler_nothrow
106 {
107 typedef void result_type;
108
operator ()my_handler_nothrow109 void operator() (std::runtime_error const& e) const
110 {
111 std::cout << "std::runtime_error: " << e.what() << std::endl;
112 }
operator ()my_handler_nothrow113 void operator() (std::logic_error const& e) const
114 {
115 std::cout << "std::logic_error: " << e.what() << std::endl;
116 throw;
117 }
operator ()my_handler_nothrow118 void operator() () const
119 {
120 std::cout << "unknown exception" << std::endl;
121 }
122 };
123
init_exception_handler_nothrow()124 void init_exception_handler_nothrow()
125 {
126 // Setup a global exception handler that will call my_handler::operator()
127 // for the specified exception types. Note the std::nothrow argument that
128 // specifies that all other exceptions should also be passed to the functor.
129 logging::core::get()->set_exception_handler(logging::make_exception_handler<
130 std::runtime_error,
131 std::logic_error
132 >(my_handler_nothrow(), std::nothrow));
133 }
134 //]
135
init()136 void init()
137 {
138 typedef sinks::synchronous_sink< sinks::text_ostream_backend > text_sink;
139 boost::shared_ptr< text_sink > sink = boost::make_shared< text_sink >();
140
141 sink->locked_backend()->add_stream(
142 boost::make_shared< std::ofstream >("sample.log"));
143
144 sink->set_formatter
145 (
146 expr::stream
147 << expr::attr< unsigned int >("LineID").or_throw() // this attribute will not be found, which will cause an exception
148 << ": <" << expr::attr< severity_level >("Severity")
149 << "> " << expr::smessage
150 );
151
152 logging::core::get()->add_sink(sink);
153
154 init_exception_handler();
155 }
156
main(int,char * [])157 int main(int, char*[])
158 {
159 init();
160 logging_function();
161
162 return 0;
163 }
164