text_multifile_backend.hpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  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. * \file text_multifile_backend.hpp
  9. * \author Andrey Semashev
  10. * \date 09.06.2009
  11. *
  12. * The header contains implementation of a text multi-file sink backend.
  13. */
  14. #ifndef BOOST_LOG_SINKS_TEXT_MULTIFILE_BACKEND_HPP_INCLUDED_
  15. #define BOOST_LOG_SINKS_TEXT_MULTIFILE_BACKEND_HPP_INCLUDED_
  16. #include <ios>
  17. #include <string>
  18. #include <locale>
  19. #include <ostream>
  20. #include <boost/mpl/if.hpp>
  21. #include <boost/mpl/bool.hpp>
  22. #include <boost/type_traits/is_same.hpp>
  23. #include <boost/filesystem/path.hpp>
  24. #include <boost/log/detail/config.hpp>
  25. #include <boost/log/detail/light_function.hpp>
  26. #include <boost/log/detail/parameter_tools.hpp>
  27. #include <boost/log/detail/cleanup_scope_guard.hpp>
  28. #include <boost/log/keywords/auto_newline_mode.hpp>
  29. #include <boost/log/sinks/auto_newline_mode.hpp>
  30. #include <boost/log/sinks/basic_sink_backend.hpp>
  31. #include <boost/log/utility/formatting_ostream.hpp>
  32. #include <boost/log/detail/header.hpp>
  33. #ifdef BOOST_HAS_PRAGMA_ONCE
  34. #pragma once
  35. #endif
  36. namespace boost {
  37. BOOST_LOG_OPEN_NAMESPACE
  38. namespace sinks {
  39. namespace file {
  40. /*!
  41. * An adapter class that allows to use regular formatters as file name generators.
  42. */
  43. template< typename FormatterT >
  44. class file_name_composer_adapter
  45. {
  46. public:
  47. //! Functor result type
  48. typedef filesystem::path result_type;
  49. //! File name character type
  50. typedef result_type::string_type::value_type native_char_type;
  51. //! The adopted formatter type
  52. typedef FormatterT formatter_type;
  53. //! Formatting stream type
  54. typedef basic_formatting_ostream< native_char_type > stream_type;
  55. private:
  56. //! The adopted formatter
  57. formatter_type m_Formatter;
  58. //! Formatted file name storage
  59. mutable result_type::string_type m_FileName;
  60. //! Formatting stream
  61. mutable stream_type m_FormattingStream;
  62. public:
  63. /*!
  64. * Initializing constructor
  65. */
  66. explicit file_name_composer_adapter(formatter_type const& formatter, std::locale const& loc = std::locale()) :
  67. m_Formatter(formatter),
  68. m_FormattingStream(m_FileName)
  69. {
  70. m_FormattingStream.exceptions(std::ios_base::badbit | std::ios_base::failbit);
  71. m_FormattingStream.imbue(loc);
  72. }
  73. /*!
  74. * Copy constructor
  75. */
  76. file_name_composer_adapter(file_name_composer_adapter const& that) :
  77. m_Formatter(that.m_Formatter),
  78. m_FormattingStream(m_FileName)
  79. {
  80. m_FormattingStream.exceptions(std::ios_base::badbit | std::ios_base::failbit);
  81. m_FormattingStream.imbue(that.m_FormattingStream.getloc());
  82. }
  83. /*!
  84. * Assignment
  85. */
  86. file_name_composer_adapter& operator= (file_name_composer_adapter const& that)
  87. {
  88. m_Formatter = that.m_Formatter;
  89. return *this;
  90. }
  91. /*!
  92. * The operator generates a file name based on the log record
  93. */
  94. result_type operator() (record_view const& rec) const
  95. {
  96. boost::log::aux::cleanup_guard< stream_type > cleanup1(m_FormattingStream);
  97. boost::log::aux::cleanup_guard< result_type::string_type > cleanup2(m_FileName);
  98. m_Formatter(rec, m_FormattingStream);
  99. m_FormattingStream.flush();
  100. return result_type(m_FileName);
  101. }
  102. };
  103. /*!
  104. * The function adopts a log record formatter into a file name generator
  105. *
  106. * \param fmt The formatter function object to adopt
  107. * \param loc The locale to use to character code conversion and formatting
  108. */
  109. template< typename FormatterT >
  110. inline file_name_composer_adapter< FormatterT > as_file_name_composer(
  111. FormatterT const& fmt, std::locale const& loc = std::locale())
  112. {
  113. return file_name_composer_adapter< FormatterT >(fmt, loc);
  114. }
  115. } // namespace file
  116. /*!
  117. * \brief An implementation of a text multiple files logging sink backend
  118. *
  119. * The sink backend puts formatted log records to one of the text files.
  120. * The particular file is chosen upon each record's attribute values, which allows
  121. * to distribute records into individual files or to group records related to
  122. * some entity or process in a separate file.
  123. */
  124. class text_multifile_backend :
  125. public basic_formatted_sink_backend< char >
  126. {
  127. //! Base type
  128. typedef basic_formatted_sink_backend< char > base_type;
  129. public:
  130. //! Character type
  131. typedef base_type::char_type char_type;
  132. //! String type to be used as a message text holder
  133. typedef base_type::string_type string_type;
  134. //! File name composer functor type
  135. typedef boost::log::aux::light_function< filesystem::path (record_view const&) > file_name_composer_type;
  136. private:
  137. //! \cond
  138. struct implementation;
  139. implementation* m_pImpl;
  140. //! \endcond
  141. public:
  142. /*!
  143. * Default constructor. The constructed sink backend has no file name composer and
  144. * thus will not write any files. All other parameters are set to their defaults.
  145. */
  146. BOOST_LOG_API text_multifile_backend();
  147. /*!
  148. * Constructor. Creates a sink backend with the specified named parameters.
  149. * The following named parameters are supported:
  150. *
  151. * \li \c auto_newline_mode - Specifies automatic trailing newline insertion mode. Must be a value of
  152. * the \c auto_newline_mode enum. By default, is <tt>auto_newline_mode::insert_if_missing</tt>.
  153. */
  154. #ifndef BOOST_LOG_DOXYGEN_PASS
  155. BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_CALL(text_multifile_backend, construct)
  156. #else
  157. template< typename... ArgsT >
  158. explicit text_multifile_backend(ArgsT... const& args);
  159. #endif
  160. /*!
  161. * Destructor
  162. */
  163. BOOST_LOG_API ~text_multifile_backend();
  164. /*!
  165. * The method sets file name composer functional object. Log record formatters are accepted, too.
  166. *
  167. * \param composer File name composer functor
  168. */
  169. template< typename ComposerT >
  170. void set_file_name_composer(ComposerT const& composer)
  171. {
  172. set_file_name_composer_internal(composer);
  173. }
  174. /*!
  175. * Selects whether a trailing newline should be automatically inserted after every log record. See
  176. * \c auto_newline_mode description for the possible modes of operation.
  177. *
  178. * \param mode The trailing newline insertion mode.
  179. */
  180. BOOST_LOG_API void set_auto_newline_mode(auto_newline_mode mode);
  181. /*!
  182. * The method writes the message to the sink
  183. */
  184. BOOST_LOG_API void consume(record_view const& rec, string_type const& formatted_message);
  185. private:
  186. #ifndef BOOST_LOG_DOXYGEN_PASS
  187. //! Constructor implementation
  188. template< typename ArgsT >
  189. void construct(ArgsT const& args)
  190. {
  191. construct(args[keywords::auto_newline_mode | insert_if_missing]);
  192. }
  193. //! Constructor implementation
  194. BOOST_LOG_API void construct(auto_newline_mode auto_newline);
  195. //! The method sets the file name composer
  196. BOOST_LOG_API void set_file_name_composer_internal(file_name_composer_type const& composer);
  197. #endif // BOOST_LOG_DOXYGEN_PASS
  198. };
  199. } // namespace sinks
  200. BOOST_LOG_CLOSE_NAMESPACE // namespace log
  201. } // namespace boost
  202. #include <boost/log/detail/footer.hpp>
  203. #endif // BOOST_LOG_SINKS_TEXT_MULTIFILE_BACKEND_HPP_INCLUDED_