Chris@16: /* Chris@101: * Copyright Andrey Semashev 2007 - 2015. Chris@16: * Distributed under the Boost Software License, Version 1.0. Chris@16: * (See accompanying file LICENSE_1_0.txt or copy at Chris@16: * http://www.boost.org/LICENSE_1_0.txt) Chris@16: */ Chris@16: /*! Chris@16: * \file text_multifile_backend.hpp Chris@16: * \author Andrey Semashev Chris@16: * \date 09.06.2009 Chris@16: * Chris@16: * The header contains implementation of a text multi-file sink backend. Chris@16: */ Chris@16: Chris@16: #ifndef BOOST_LOG_SINKS_TEXT_MULTIFILE_BACKEND_HPP_INCLUDED_ Chris@16: #define BOOST_LOG_SINKS_TEXT_MULTIFILE_BACKEND_HPP_INCLUDED_ Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #ifdef BOOST_HAS_PRAGMA_ONCE Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: BOOST_LOG_OPEN_NAMESPACE Chris@16: Chris@16: namespace sinks { Chris@16: Chris@16: namespace file { Chris@16: Chris@16: /*! Chris@16: * An adapter class that allows to use regular formatters as file name generators. Chris@16: */ Chris@16: template< typename FormatterT > Chris@16: class file_name_composer_adapter Chris@16: { Chris@16: public: Chris@16: //! Functor result type Chris@16: typedef filesystem::path result_type; Chris@16: //! File name character type Chris@16: typedef result_type::string_type::value_type native_char_type; Chris@16: //! The adopted formatter type Chris@16: typedef FormatterT formatter_type; Chris@16: //! Formatting stream type Chris@16: typedef basic_formatting_ostream< native_char_type > stream_type; Chris@16: Chris@16: private: Chris@16: //! The adopted formatter Chris@16: formatter_type m_Formatter; Chris@16: //! Formatted file name storage Chris@16: mutable result_type::string_type m_FileName; Chris@16: //! Formatting stream Chris@16: mutable stream_type m_FormattingStream; Chris@16: Chris@16: public: Chris@16: /*! Chris@16: * Initializing constructor Chris@16: */ Chris@16: explicit file_name_composer_adapter(formatter_type const& formatter, std::locale const& loc = std::locale()) : Chris@16: m_Formatter(formatter), Chris@16: m_FormattingStream(m_FileName) Chris@16: { Chris@16: m_FormattingStream.exceptions(std::ios_base::badbit | std::ios_base::failbit); Chris@16: m_FormattingStream.imbue(loc); Chris@16: } Chris@16: /*! Chris@16: * Copy constructor Chris@16: */ Chris@16: file_name_composer_adapter(file_name_composer_adapter const& that) : Chris@16: m_Formatter(that.m_Formatter), Chris@16: m_FormattingStream(m_FileName) Chris@16: { Chris@16: m_FormattingStream.exceptions(std::ios_base::badbit | std::ios_base::failbit); Chris@16: m_FormattingStream.imbue(that.m_FormattingStream.getloc()); Chris@16: } Chris@16: /*! Chris@16: * Assignment Chris@16: */ Chris@16: file_name_composer_adapter& operator= (file_name_composer_adapter const& that) Chris@16: { Chris@16: m_Formatter = that.m_Formatter; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: /*! Chris@16: * The operator generates a file name based on the log record Chris@16: */ Chris@16: result_type operator() (record_view const& rec) const Chris@16: { Chris@16: boost::log::aux::cleanup_guard< stream_type > cleanup1(m_FormattingStream); Chris@16: boost::log::aux::cleanup_guard< result_type::string_type > cleanup2(m_FileName); Chris@16: Chris@16: m_Formatter(rec, m_FormattingStream); Chris@16: m_FormattingStream.flush(); Chris@16: Chris@16: return result_type(m_FileName); Chris@16: } Chris@16: }; Chris@16: Chris@16: /*! Chris@16: * The function adopts a log record formatter into a file name generator Chris@16: */ Chris@16: template< typename FormatterT > Chris@16: inline file_name_composer_adapter< FormatterT > as_file_name_composer( Chris@16: FormatterT const& fmt, std::locale const& loc = std::locale()) Chris@16: { Chris@16: return file_name_composer_adapter< FormatterT >(fmt, loc); Chris@16: } Chris@16: Chris@16: } // namespace file Chris@16: Chris@16: Chris@16: /*! Chris@16: * \brief An implementation of a text multiple files logging sink backend Chris@16: * Chris@16: * The sink backend puts formatted log records to one of the text files. Chris@16: * The particular file is chosen upon each record's attribute values, which allows Chris@16: * to distribute records into individual files or to group records related to Chris@16: * some entity or process in a separate file. Chris@16: */ Chris@16: class text_multifile_backend : Chris@16: public basic_formatted_sink_backend< char > Chris@16: { Chris@16: //! Base type Chris@16: typedef basic_formatted_sink_backend< char > base_type; Chris@16: Chris@16: public: Chris@16: //! Character type Chris@16: typedef base_type::char_type char_type; Chris@16: //! String type to be used as a message text holder Chris@16: typedef base_type::string_type string_type; Chris@16: Chris@16: //! File name composer functor type Chris@16: typedef boost::log::aux::light_function< filesystem::path (record_view const&) > file_name_composer_type; Chris@16: Chris@16: private: Chris@16: //! \cond Chris@16: Chris@16: struct implementation; Chris@16: implementation* m_pImpl; Chris@16: Chris@16: //! \endcond Chris@16: Chris@16: public: Chris@16: /*! Chris@16: * Default constructor. The constructed sink backend has no file name composer and Chris@16: * thus will not write any files. Chris@16: */ Chris@16: BOOST_LOG_API text_multifile_backend(); Chris@16: Chris@16: /*! Chris@16: * Destructor Chris@16: */ Chris@16: BOOST_LOG_API ~text_multifile_backend(); Chris@16: Chris@16: /*! Chris@16: * The method sets file name composer functional object. Log record formatters are accepted, too. Chris@16: * Chris@16: * \param composer File name composer functor Chris@16: */ Chris@16: template< typename ComposerT > Chris@16: void set_file_name_composer(ComposerT const& composer) Chris@16: { Chris@16: set_file_name_composer_internal(composer); Chris@16: } Chris@16: Chris@16: /*! Chris@16: * The method writes the message to the sink Chris@16: */ Chris@16: BOOST_LOG_API void consume(record_view const& rec, string_type const& formatted_message); Chris@16: Chris@16: private: Chris@16: #ifndef BOOST_LOG_DOXYGEN_PASS Chris@16: //! The method sets the file name composer Chris@16: BOOST_LOG_API void set_file_name_composer_internal(file_name_composer_type const& composer); Chris@16: #endif // BOOST_LOG_DOXYGEN_PASS Chris@16: }; Chris@16: Chris@16: } // namespace sinks Chris@16: Chris@16: BOOST_LOG_CLOSE_NAMESPACE // namespace log Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // BOOST_LOG_SINKS_TEXT_MULTIFILE_BACKEND_HPP_INCLUDED_