text_multifile_backend.hpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /*
  2. * Copyright Andrey Semashev 2007 - 2013.
  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/cleanup_scope_guard.hpp>
  27. #include <boost/log/sinks/basic_sink_backend.hpp>
  28. #include <boost/log/utility/formatting_ostream.hpp>
  29. #include <boost/log/detail/header.hpp>
  30. #ifdef BOOST_HAS_PRAGMA_ONCE
  31. #pragma once
  32. #endif
  33. namespace boost {
  34. BOOST_LOG_OPEN_NAMESPACE
  35. namespace sinks {
  36. namespace file {
  37. /*!
  38. * An adapter class that allows to use regular formatters as file name generators.
  39. */
  40. template< typename FormatterT >
  41. class file_name_composer_adapter
  42. {
  43. public:
  44. //! Functor result type
  45. typedef filesystem::path result_type;
  46. //! File name character type
  47. typedef result_type::string_type::value_type native_char_type;
  48. //! The adopted formatter type
  49. typedef FormatterT formatter_type;
  50. //! Formatting stream type
  51. typedef basic_formatting_ostream< native_char_type > stream_type;
  52. private:
  53. //! The adopted formatter
  54. formatter_type m_Formatter;
  55. //! Formatted file name storage
  56. mutable result_type::string_type m_FileName;
  57. //! Formatting stream
  58. mutable stream_type m_FormattingStream;
  59. public:
  60. /*!
  61. * Initializing constructor
  62. */
  63. explicit file_name_composer_adapter(formatter_type const& formatter, std::locale const& loc = std::locale()) :
  64. m_Formatter(formatter),
  65. m_FormattingStream(m_FileName)
  66. {
  67. m_FormattingStream.exceptions(std::ios_base::badbit | std::ios_base::failbit);
  68. m_FormattingStream.imbue(loc);
  69. }
  70. /*!
  71. * Copy constructor
  72. */
  73. file_name_composer_adapter(file_name_composer_adapter const& that) :
  74. m_Formatter(that.m_Formatter),
  75. m_FormattingStream(m_FileName)
  76. {
  77. m_FormattingStream.exceptions(std::ios_base::badbit | std::ios_base::failbit);
  78. m_FormattingStream.imbue(that.m_FormattingStream.getloc());
  79. }
  80. /*!
  81. * Assignment
  82. */
  83. file_name_composer_adapter& operator= (file_name_composer_adapter const& that)
  84. {
  85. m_Formatter = that.m_Formatter;
  86. return *this;
  87. }
  88. /*!
  89. * The operator generates a file name based on the log record
  90. */
  91. result_type operator() (record_view const& rec) const
  92. {
  93. boost::log::aux::cleanup_guard< stream_type > cleanup1(m_FormattingStream);
  94. boost::log::aux::cleanup_guard< result_type::string_type > cleanup2(m_FileName);
  95. m_Formatter(rec, m_FormattingStream);
  96. m_FormattingStream.flush();
  97. return result_type(m_FileName);
  98. }
  99. };
  100. /*!
  101. * The function adopts a log record formatter into a file name generator
  102. */
  103. template< typename FormatterT >
  104. inline file_name_composer_adapter< FormatterT > as_file_name_composer(
  105. FormatterT const& fmt, std::locale const& loc = std::locale())
  106. {
  107. return file_name_composer_adapter< FormatterT >(fmt, loc);
  108. }
  109. } // namespace file
  110. /*!
  111. * \brief An implementation of a text multiple files logging sink backend
  112. *
  113. * The sink backend puts formatted log records to one of the text files.
  114. * The particular file is chosen upon each record's attribute values, which allows
  115. * to distribute records into individual files or to group records related to
  116. * some entity or process in a separate file.
  117. */
  118. class text_multifile_backend :
  119. public basic_formatted_sink_backend< char >
  120. {
  121. //! Base type
  122. typedef basic_formatted_sink_backend< char > base_type;
  123. public:
  124. //! Character type
  125. typedef base_type::char_type char_type;
  126. //! String type to be used as a message text holder
  127. typedef base_type::string_type string_type;
  128. //! File name composer functor type
  129. typedef boost::log::aux::light_function< filesystem::path (record_view const&) > file_name_composer_type;
  130. private:
  131. //! \cond
  132. struct implementation;
  133. implementation* m_pImpl;
  134. //! \endcond
  135. public:
  136. /*!
  137. * Default constructor. The constructed sink backend has no file name composer and
  138. * thus will not write any files.
  139. */
  140. BOOST_LOG_API text_multifile_backend();
  141. /*!
  142. * Destructor
  143. */
  144. BOOST_LOG_API ~text_multifile_backend();
  145. /*!
  146. * The method sets file name composer functional object. Log record formatters are accepted, too.
  147. *
  148. * \param composer File name composer functor
  149. */
  150. template< typename ComposerT >
  151. void set_file_name_composer(ComposerT const& composer)
  152. {
  153. set_file_name_composer_internal(composer);
  154. }
  155. /*!
  156. * The method writes the message to the sink
  157. */
  158. BOOST_LOG_API void consume(record_view const& rec, string_type const& formatted_message);
  159. private:
  160. #ifndef BOOST_LOG_DOXYGEN_PASS
  161. //! The method sets the file name composer
  162. BOOST_LOG_API void set_file_name_composer_internal(file_name_composer_type const& composer);
  163. #endif // BOOST_LOG_DOXYGEN_PASS
  164. };
  165. } // namespace sinks
  166. BOOST_LOG_CLOSE_NAMESPACE // namespace log
  167. } // namespace boost
  168. #include <boost/log/detail/footer.hpp>
  169. #endif // BOOST_LOG_SINKS_TEXT_MULTIFILE_BACKEND_HPP_INCLUDED_