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