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