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