• 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 <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