exception_handling.cpp 4.4 KB

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