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 basic_logger.hpp
|
Chris@16
|
9 * \author Andrey Semashev
|
Chris@16
|
10 * \date 08.03.2007
|
Chris@16
|
11 *
|
Chris@16
|
12 * The header contains implementation of a base class for loggers. Convenience macros
|
Chris@16
|
13 * for defining custom loggers are also provided.
|
Chris@16
|
14 */
|
Chris@16
|
15
|
Chris@16
|
16 #ifndef BOOST_LOG_SOURCES_BASIC_LOGGER_HPP_INCLUDED_
|
Chris@16
|
17 #define BOOST_LOG_SOURCES_BASIC_LOGGER_HPP_INCLUDED_
|
Chris@16
|
18
|
Chris@16
|
19 #include <exception>
|
Chris@16
|
20 #include <utility>
|
Chris@16
|
21 #include <ostream>
|
Chris@16
|
22 #include <boost/assert.hpp>
|
Chris@16
|
23 #include <boost/move/core.hpp>
|
Chris@16
|
24 #include <boost/move/utility.hpp>
|
Chris@16
|
25 #include <boost/utility/addressof.hpp>
|
Chris@16
|
26 #include <boost/preprocessor/facilities/empty.hpp>
|
Chris@16
|
27 #include <boost/preprocessor/facilities/identity.hpp>
|
Chris@16
|
28 #include <boost/preprocessor/repetition/enum_params.hpp>
|
Chris@16
|
29 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
Chris@16
|
30 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
Chris@16
|
31 #include <boost/preprocessor/seq/enum.hpp>
|
Chris@16
|
32 #include <boost/log/detail/config.hpp>
|
Chris@16
|
33 #include <boost/log/detail/parameter_tools.hpp>
|
Chris@16
|
34 #include <boost/log/attributes/attribute_set.hpp>
|
Chris@16
|
35 #include <boost/log/attributes/attribute_name.hpp>
|
Chris@16
|
36 #include <boost/log/attributes/attribute.hpp>
|
Chris@16
|
37 #include <boost/log/core/core.hpp>
|
Chris@16
|
38 #include <boost/log/core/record.hpp>
|
Chris@16
|
39 #include <boost/log/sources/features.hpp>
|
Chris@16
|
40 #include <boost/log/sources/threading_models.hpp>
|
Chris@16
|
41 #include <boost/log/detail/header.hpp>
|
Chris@16
|
42
|
Chris@16
|
43 #ifdef BOOST_HAS_PRAGMA_ONCE
|
Chris@16
|
44 #pragma once
|
Chris@16
|
45 #endif
|
Chris@16
|
46
|
Chris@16
|
47 namespace boost {
|
Chris@16
|
48
|
Chris@16
|
49 BOOST_LOG_OPEN_NAMESPACE
|
Chris@16
|
50
|
Chris@16
|
51 namespace sources {
|
Chris@16
|
52
|
Chris@16
|
53 /*!
|
Chris@16
|
54 * \brief Basic logger class
|
Chris@16
|
55 *
|
Chris@16
|
56 * The \c basic_logger class template serves as a base class for all loggers
|
Chris@16
|
57 * provided by the library. It can also be used as a base for user-defined
|
Chris@16
|
58 * loggers. The template parameters are:
|
Chris@16
|
59 *
|
Chris@16
|
60 * \li \c CharT - logging character type
|
Chris@16
|
61 * \li \c FinalT - final type of the logger that eventually derives from
|
Chris@16
|
62 * the \c basic_logger. There may be other classes in the hierarchy
|
Chris@16
|
63 * between the final class and \c basic_logger.
|
Chris@16
|
64 * \li \c ThreadingModelT - threading model policy. Must provide methods
|
Chris@16
|
65 * of the Boost.Thread locking concept used in \c basic_logger class
|
Chris@16
|
66 * and all its derivatives in the hierarchy up to the \c FinalT class.
|
Chris@16
|
67 * The \c basic_logger class itself requires methods of the
|
Chris@16
|
68 * SharedLockable concept. The threading model policy must also be
|
Chris@16
|
69 * default and copy-constructible and support member function \c swap.
|
Chris@16
|
70 * There are currently two policies provided: \c single_thread_model
|
Chris@16
|
71 * and \c multi_thread_model.
|
Chris@16
|
72 *
|
Chris@16
|
73 * The logger implements fundamental facilities of loggers, such as storing
|
Chris@16
|
74 * source-specific attribute set and formatting log record messages. The basic
|
Chris@16
|
75 * logger interacts with the logging core in order to apply filtering and
|
Chris@16
|
76 * pass records to sinks.
|
Chris@16
|
77 */
|
Chris@16
|
78 template< typename CharT, typename FinalT, typename ThreadingModelT >
|
Chris@16
|
79 class basic_logger :
|
Chris@16
|
80 public ThreadingModelT
|
Chris@16
|
81 {
|
Chris@16
|
82 typedef basic_logger this_type;
|
Chris@16
|
83 BOOST_COPYABLE_AND_MOVABLE_ALT(this_type)
|
Chris@16
|
84
|
Chris@16
|
85 public:
|
Chris@16
|
86 //! Character type
|
Chris@16
|
87 typedef CharT char_type;
|
Chris@16
|
88 //! Final logger type
|
Chris@16
|
89 typedef FinalT final_type;
|
Chris@16
|
90 //! Threading model type
|
Chris@16
|
91 typedef ThreadingModelT threading_model;
|
Chris@16
|
92
|
Chris@16
|
93 #if !defined(BOOST_LOG_NO_THREADS)
|
Chris@16
|
94 //! Lock requirement for the swap_unlocked method
|
Chris@16
|
95 typedef boost::log::aux::exclusive_lock_guard< threading_model > swap_lock;
|
Chris@16
|
96 //! Lock requirement for the add_attribute_unlocked method
|
Chris@16
|
97 typedef boost::log::aux::exclusive_lock_guard< threading_model > add_attribute_lock;
|
Chris@16
|
98 //! Lock requirement for the remove_attribute_unlocked method
|
Chris@16
|
99 typedef boost::log::aux::exclusive_lock_guard< threading_model > remove_attribute_lock;
|
Chris@16
|
100 //! Lock requirement for the remove_all_attributes_unlocked method
|
Chris@16
|
101 typedef boost::log::aux::exclusive_lock_guard< threading_model > remove_all_attributes_lock;
|
Chris@16
|
102 //! Lock requirement for the get_attributes method
|
Chris@101
|
103 typedef boost::log::aux::shared_lock_guard< const threading_model > get_attributes_lock;
|
Chris@16
|
104 //! Lock requirement for the open_record_unlocked method
|
Chris@16
|
105 typedef boost::log::aux::shared_lock_guard< threading_model > open_record_lock;
|
Chris@16
|
106 //! Lock requirement for the set_attributes method
|
Chris@16
|
107 typedef boost::log::aux::exclusive_lock_guard< threading_model > set_attributes_lock;
|
Chris@16
|
108 #else
|
Chris@16
|
109 typedef no_lock< threading_model > swap_lock;
|
Chris@16
|
110 typedef no_lock< threading_model > add_attribute_lock;
|
Chris@16
|
111 typedef no_lock< threading_model > remove_attribute_lock;
|
Chris@16
|
112 typedef no_lock< threading_model > remove_all_attributes_lock;
|
Chris@101
|
113 typedef no_lock< const threading_model > get_attributes_lock;
|
Chris@16
|
114 typedef no_lock< threading_model > open_record_lock;
|
Chris@16
|
115 typedef no_lock< threading_model > set_attributes_lock;
|
Chris@16
|
116 #endif
|
Chris@16
|
117
|
Chris@16
|
118 //! Lock requirement for the push_record_unlocked method
|
Chris@16
|
119 typedef no_lock< threading_model > push_record_lock;
|
Chris@16
|
120
|
Chris@16
|
121 private:
|
Chris@16
|
122 //! A pointer to the logging system
|
Chris@16
|
123 core_ptr m_pCore;
|
Chris@16
|
124
|
Chris@16
|
125 //! Logger-specific attribute set
|
Chris@16
|
126 attribute_set m_Attributes;
|
Chris@16
|
127
|
Chris@16
|
128 public:
|
Chris@16
|
129 /*!
|
Chris@16
|
130 * Constructor. Initializes internal data structures of the basic logger class,
|
Chris@16
|
131 * acquires reference to the logging core.
|
Chris@16
|
132 */
|
Chris@16
|
133 basic_logger() :
|
Chris@16
|
134 threading_model(),
|
Chris@16
|
135 m_pCore(core::get())
|
Chris@16
|
136 {
|
Chris@16
|
137 }
|
Chris@16
|
138 /*!
|
Chris@16
|
139 * Copy constructor. Copies all attributes from the source logger.
|
Chris@16
|
140 *
|
Chris@16
|
141 * \note Not thread-safe. The source logger must be locked in the final class before copying.
|
Chris@16
|
142 *
|
Chris@16
|
143 * \param that Source logger
|
Chris@16
|
144 */
|
Chris@16
|
145 basic_logger(basic_logger const& that) :
|
Chris@16
|
146 threading_model(static_cast< threading_model const& >(that)),
|
Chris@16
|
147 m_pCore(core::get()),
|
Chris@16
|
148 m_Attributes(that.m_Attributes)
|
Chris@16
|
149 {
|
Chris@16
|
150 }
|
Chris@16
|
151 /*!
|
Chris@16
|
152 * Move constructor. Moves all attributes from the source logger.
|
Chris@16
|
153 *
|
Chris@16
|
154 * \note Not thread-safe. The source logger must be locked in the final class before copying.
|
Chris@16
|
155 *
|
Chris@16
|
156 * \param that Source logger
|
Chris@16
|
157 */
|
Chris@16
|
158 basic_logger(BOOST_RV_REF(basic_logger) that) :
|
Chris@16
|
159 threading_model(boost::move(static_cast< threading_model& >(that)))
|
Chris@16
|
160 {
|
Chris@16
|
161 m_pCore.swap(that.m_pCore);
|
Chris@16
|
162 m_Attributes.swap(that.m_Attributes);
|
Chris@16
|
163 }
|
Chris@16
|
164 /*!
|
Chris@16
|
165 * Constructor with named arguments. The constructor ignores all arguments. The result of
|
Chris@16
|
166 * construction is equivalent to default construction.
|
Chris@16
|
167 */
|
Chris@16
|
168 template< typename ArgsT >
|
Chris@16
|
169 explicit basic_logger(ArgsT const&) :
|
Chris@16
|
170 threading_model(),
|
Chris@16
|
171 m_pCore(core::get())
|
Chris@16
|
172 {
|
Chris@16
|
173 }
|
Chris@16
|
174
|
Chris@16
|
175 protected:
|
Chris@16
|
176 /*!
|
Chris@16
|
177 * An accessor to the logging system pointer
|
Chris@16
|
178 */
|
Chris@16
|
179 core_ptr const& core() const { return m_pCore; }
|
Chris@16
|
180 /*!
|
Chris@16
|
181 * An accessor to the logger attributes
|
Chris@16
|
182 */
|
Chris@16
|
183 attribute_set& attributes() { return m_Attributes; }
|
Chris@16
|
184 /*!
|
Chris@16
|
185 * An accessor to the logger attributes
|
Chris@16
|
186 */
|
Chris@16
|
187 attribute_set const& attributes() const { return m_Attributes; }
|
Chris@16
|
188 /*!
|
Chris@16
|
189 * An accessor to the threading model base
|
Chris@16
|
190 */
|
Chris@16
|
191 threading_model& get_threading_model() { return *this; }
|
Chris@16
|
192 /*!
|
Chris@16
|
193 * An accessor to the threading model base
|
Chris@16
|
194 */
|
Chris@16
|
195 threading_model const& get_threading_model() const { return *this; }
|
Chris@16
|
196 /*!
|
Chris@16
|
197 * An accessor to the final logger
|
Chris@16
|
198 */
|
Chris@16
|
199 final_type* final_this()
|
Chris@16
|
200 {
|
Chris@16
|
201 BOOST_LOG_ASSUME(this != NULL);
|
Chris@16
|
202 return static_cast< final_type* >(this);
|
Chris@16
|
203 }
|
Chris@16
|
204 /*!
|
Chris@16
|
205 * An accessor to the final logger
|
Chris@16
|
206 */
|
Chris@16
|
207 final_type const* final_this() const
|
Chris@16
|
208 {
|
Chris@16
|
209 BOOST_LOG_ASSUME(this != NULL);
|
Chris@16
|
210 return static_cast< final_type const* >(this);
|
Chris@16
|
211 }
|
Chris@16
|
212
|
Chris@16
|
213 /*!
|
Chris@16
|
214 * Unlocked \c swap
|
Chris@16
|
215 */
|
Chris@16
|
216 void swap_unlocked(basic_logger& that)
|
Chris@16
|
217 {
|
Chris@16
|
218 get_threading_model().swap(that.get_threading_model());
|
Chris@16
|
219 m_Attributes.swap(that.m_Attributes);
|
Chris@16
|
220 }
|
Chris@16
|
221
|
Chris@16
|
222 /*!
|
Chris@16
|
223 * Unlocked \c add_attribute
|
Chris@16
|
224 */
|
Chris@16
|
225 std::pair< attribute_set::iterator, bool > add_attribute_unlocked(attribute_name const& name, attribute const& attr)
|
Chris@16
|
226 {
|
Chris@16
|
227 return m_Attributes.insert(name, attr);
|
Chris@16
|
228 }
|
Chris@16
|
229
|
Chris@16
|
230 /*!
|
Chris@16
|
231 * Unlocked \c remove_attribute
|
Chris@16
|
232 */
|
Chris@16
|
233 void remove_attribute_unlocked(attribute_set::iterator it)
|
Chris@16
|
234 {
|
Chris@16
|
235 m_Attributes.erase(it);
|
Chris@16
|
236 }
|
Chris@16
|
237
|
Chris@16
|
238 /*!
|
Chris@16
|
239 * Unlocked \c remove_all_attributes
|
Chris@16
|
240 */
|
Chris@16
|
241 void remove_all_attributes_unlocked()
|
Chris@16
|
242 {
|
Chris@16
|
243 m_Attributes.clear();
|
Chris@16
|
244 }
|
Chris@16
|
245
|
Chris@16
|
246 /*!
|
Chris@16
|
247 * Unlocked \c open_record
|
Chris@16
|
248 */
|
Chris@16
|
249 record open_record_unlocked()
|
Chris@16
|
250 {
|
Chris@16
|
251 return m_pCore->open_record(m_Attributes);
|
Chris@16
|
252 }
|
Chris@16
|
253 /*!
|
Chris@16
|
254 * Unlocked \c open_record
|
Chris@16
|
255 */
|
Chris@16
|
256 template< typename ArgsT >
|
Chris@16
|
257 record open_record_unlocked(ArgsT const&)
|
Chris@16
|
258 {
|
Chris@16
|
259 return m_pCore->open_record(m_Attributes);
|
Chris@16
|
260 }
|
Chris@16
|
261
|
Chris@16
|
262 /*!
|
Chris@16
|
263 * Unlocked \c push_record
|
Chris@16
|
264 */
|
Chris@16
|
265 void push_record_unlocked(BOOST_RV_REF(record) rec)
|
Chris@16
|
266 {
|
Chris@16
|
267 m_pCore->push_record(boost::move(rec));
|
Chris@16
|
268 }
|
Chris@16
|
269
|
Chris@16
|
270 /*!
|
Chris@16
|
271 * Unlocked \c get_attributes
|
Chris@16
|
272 */
|
Chris@16
|
273 attribute_set get_attributes_unlocked() const
|
Chris@16
|
274 {
|
Chris@16
|
275 return m_Attributes;
|
Chris@16
|
276 }
|
Chris@16
|
277
|
Chris@16
|
278 /*!
|
Chris@16
|
279 * Unlocked \c set_attributes
|
Chris@16
|
280 */
|
Chris@16
|
281 void set_attributes_unlocked(attribute_set const& attrs)
|
Chris@16
|
282 {
|
Chris@16
|
283 m_Attributes = attrs;
|
Chris@16
|
284 }
|
Chris@16
|
285
|
Chris@16
|
286 //! Assignment is closed (should be implemented through copy and swap in the final class)
|
Chris@16
|
287 BOOST_DELETED_FUNCTION(basic_logger& operator= (basic_logger const&))
|
Chris@16
|
288 };
|
Chris@16
|
289
|
Chris@16
|
290 /*!
|
Chris@16
|
291 * Free-standing swap for all loggers
|
Chris@16
|
292 */
|
Chris@16
|
293 template< typename CharT, typename FinalT, typename ThreadingModelT >
|
Chris@16
|
294 inline void swap(
|
Chris@16
|
295 basic_logger< CharT, FinalT, ThreadingModelT >& left,
|
Chris@16
|
296 basic_logger< CharT, FinalT, ThreadingModelT >& right)
|
Chris@16
|
297 {
|
Chris@16
|
298 static_cast< FinalT& >(left).swap(static_cast< FinalT& >(right));
|
Chris@16
|
299 }
|
Chris@16
|
300
|
Chris@16
|
301 /*!
|
Chris@16
|
302 * \brief A composite logger that inherits a number of features
|
Chris@16
|
303 *
|
Chris@16
|
304 * The composite logger is a helper class that simplifies feature composition into the final logger.
|
Chris@16
|
305 * The user's logger class is expected to derive from the composite logger class, instantiated with
|
Chris@16
|
306 * the character type, the user's logger class, the threading model and the list of the required features.
|
Chris@16
|
307 * The former three parameters are passed to the \c basic_logger class template. The feature list
|
Chris@16
|
308 * must be an MPL type sequence, where each element is a unary MPL metafunction class, that upon
|
Chris@16
|
309 * applying on its argument results in a logging feature class that derives from the argument.
|
Chris@16
|
310 * Every logger feature provided by the library can participate in the feature list.
|
Chris@16
|
311 */
|
Chris@16
|
312 template< typename CharT, typename FinalT, typename ThreadingModelT, typename FeaturesT >
|
Chris@16
|
313 class basic_composite_logger :
|
Chris@16
|
314 public boost::log::sources::aux::inherit_features<
|
Chris@16
|
315 basic_logger< CharT, FinalT, ThreadingModelT >,
|
Chris@16
|
316 FeaturesT
|
Chris@16
|
317 >::type
|
Chris@16
|
318 {
|
Chris@16
|
319 private:
|
Chris@16
|
320 //! Base type (the hierarchy of features)
|
Chris@16
|
321 typedef typename boost::log::sources::aux::inherit_features<
|
Chris@16
|
322 basic_logger< CharT, FinalT, ThreadingModelT >,
|
Chris@16
|
323 FeaturesT
|
Chris@16
|
324 >::type base_type;
|
Chris@16
|
325
|
Chris@16
|
326 protected:
|
Chris@16
|
327 //! The composite logger type (for use in the user's logger class)
|
Chris@16
|
328 typedef basic_composite_logger logger_base;
|
Chris@16
|
329 BOOST_COPYABLE_AND_MOVABLE_ALT(logger_base)
|
Chris@16
|
330
|
Chris@16
|
331 public:
|
Chris@16
|
332 //! Threading model being used
|
Chris@16
|
333 typedef typename base_type::threading_model threading_model;
|
Chris@16
|
334
|
Chris@16
|
335 #if !defined(BOOST_LOG_NO_THREADS)
|
Chris@16
|
336
|
Chris@16
|
337 public:
|
Chris@16
|
338 /*!
|
Chris@16
|
339 * Default constructor (default-constructs all features)
|
Chris@16
|
340 */
|
Chris@16
|
341 basic_composite_logger() {}
|
Chris@16
|
342 /*!
|
Chris@16
|
343 * Copy constructor
|
Chris@16
|
344 */
|
Chris@16
|
345 basic_composite_logger(basic_composite_logger const& that) :
|
Chris@16
|
346 base_type
|
Chris@16
|
347 ((
|
Chris@16
|
348 boost::log::aux::shared_lock_guard< const threading_model >(that.get_threading_model()),
|
Chris@16
|
349 static_cast< base_type const& >(that)
|
Chris@16
|
350 ))
|
Chris@16
|
351 {
|
Chris@16
|
352 }
|
Chris@16
|
353 /*!
|
Chris@16
|
354 * Move constructor
|
Chris@16
|
355 */
|
Chris@16
|
356 basic_composite_logger(BOOST_RV_REF(logger_base) that) :
|
Chris@16
|
357 base_type(boost::move(static_cast< base_type& >(that)))
|
Chris@16
|
358 {
|
Chris@16
|
359 }
|
Chris@16
|
360 /*!
|
Chris@16
|
361 * Constructor with named parameters
|
Chris@16
|
362 */
|
Chris@16
|
363 template< typename ArgsT >
|
Chris@16
|
364 explicit basic_composite_logger(ArgsT const& args) : base_type(args)
|
Chris@16
|
365 {
|
Chris@16
|
366 }
|
Chris@16
|
367
|
Chris@16
|
368 /*!
|
Chris@16
|
369 * The method adds an attribute to the source-specific attribute set. The attribute will be implicitly added to
|
Chris@16
|
370 * every log record made with the current logger.
|
Chris@16
|
371 *
|
Chris@16
|
372 * \param name The attribute name.
|
Chris@16
|
373 * \param attr The attribute factory.
|
Chris@16
|
374 * \return A pair of values. If the second member is \c true, then the attribute is added and the first member points to the
|
Chris@16
|
375 * attribute. Otherwise the attribute was not added and the first member points to the attribute that prevents
|
Chris@16
|
376 * addition.
|
Chris@16
|
377 */
|
Chris@16
|
378 std::pair< attribute_set::iterator, bool > add_attribute(attribute_name const& name, attribute const& attr)
|
Chris@16
|
379 {
|
Chris@16
|
380 typename base_type::add_attribute_lock lock(base_type::get_threading_model());
|
Chris@16
|
381 return base_type::add_attribute_unlocked(name, attr);
|
Chris@16
|
382 }
|
Chris@16
|
383 /*!
|
Chris@16
|
384 * The method removes an attribute from the source-specific attribute set.
|
Chris@16
|
385 *
|
Chris@16
|
386 * \pre The attribute was added with the add_attribute call for this instance of the logger.
|
Chris@16
|
387 * \post The attribute is no longer registered as a source-specific attribute for this logger. The iterator is invalidated after removal.
|
Chris@16
|
388 *
|
Chris@16
|
389 * \param it Iterator to the previously added attribute.
|
Chris@16
|
390 */
|
Chris@16
|
391 void remove_attribute(attribute_set::iterator it)
|
Chris@16
|
392 {
|
Chris@16
|
393 typename base_type::remove_attribute_lock lock(base_type::get_threading_model());
|
Chris@16
|
394 base_type::remove_attribute_unlocked(it);
|
Chris@16
|
395 }
|
Chris@16
|
396
|
Chris@16
|
397 /*!
|
Chris@16
|
398 * The method removes all attributes from the logger. All iterators and references to the removed attributes are invalidated.
|
Chris@16
|
399 */
|
Chris@16
|
400 void remove_all_attributes()
|
Chris@16
|
401 {
|
Chris@16
|
402 typename base_type::remove_all_attributes_lock lock(base_type::get_threading_model());
|
Chris@16
|
403 base_type::remove_all_attributes_unlocked();
|
Chris@16
|
404 }
|
Chris@16
|
405
|
Chris@16
|
406 /*!
|
Chris@16
|
407 * The method retrieves a copy of a set with all attributes from the logger.
|
Chris@16
|
408 *
|
Chris@16
|
409 * \return The copy of the attribute set. Attributes are shallow-copied.
|
Chris@16
|
410 */
|
Chris@16
|
411 attribute_set get_attributes() const
|
Chris@16
|
412 {
|
Chris@16
|
413 typename base_type::get_attributes_lock lock(base_type::get_threading_model());
|
Chris@16
|
414 return base_type::get_attributes_unlocked();
|
Chris@16
|
415 }
|
Chris@16
|
416
|
Chris@16
|
417 /*!
|
Chris@16
|
418 * The method installs the whole attribute set into the logger. All iterators and references to elements of
|
Chris@16
|
419 * the previous set are invalidated. Iterators to the \a attrs set are not valid to be used with the logger (that is,
|
Chris@16
|
420 * the logger owns a copy of \a attrs after completion).
|
Chris@16
|
421 *
|
Chris@16
|
422 * \param attrs The set of attributes to install into the logger. Attributes are shallow-copied.
|
Chris@16
|
423 */
|
Chris@16
|
424 void set_attributes(attribute_set const& attrs)
|
Chris@16
|
425 {
|
Chris@16
|
426 typename base_type::set_attributes_lock lock(base_type::get_threading_model());
|
Chris@16
|
427 base_type::set_attributes_unlocked(attrs);
|
Chris@16
|
428 }
|
Chris@16
|
429
|
Chris@16
|
430 /*!
|
Chris@16
|
431 * The method opens a new log record in the logging core.
|
Chris@16
|
432 *
|
Chris@16
|
433 * \return A valid record handle if the logging record is opened successfully, an invalid handle otherwise.
|
Chris@16
|
434 */
|
Chris@16
|
435 record open_record()
|
Chris@16
|
436 {
|
Chris@16
|
437 // Perform a quick check first
|
Chris@16
|
438 if (this->core()->get_logging_enabled())
|
Chris@16
|
439 {
|
Chris@16
|
440 typename base_type::open_record_lock lock(base_type::get_threading_model());
|
Chris@16
|
441 return base_type::open_record_unlocked(boost::log::aux::empty_arg_list());
|
Chris@16
|
442 }
|
Chris@16
|
443 else
|
Chris@16
|
444 return record();
|
Chris@16
|
445 }
|
Chris@16
|
446 /*!
|
Chris@16
|
447 * The method opens a new log record in the logging core.
|
Chris@16
|
448 *
|
Chris@16
|
449 * \param args A set of additional named arguments. The parameter is ignored.
|
Chris@16
|
450 * \return A valid record handle if the logging record is opened successfully, an invalid handle otherwise.
|
Chris@16
|
451 */
|
Chris@16
|
452 template< typename ArgsT >
|
Chris@16
|
453 record open_record(ArgsT const& args)
|
Chris@16
|
454 {
|
Chris@16
|
455 // Perform a quick check first
|
Chris@16
|
456 if (this->core()->get_logging_enabled())
|
Chris@16
|
457 {
|
Chris@16
|
458 typename base_type::open_record_lock lock(base_type::get_threading_model());
|
Chris@16
|
459 return base_type::open_record_unlocked(args);
|
Chris@16
|
460 }
|
Chris@16
|
461 else
|
Chris@16
|
462 return record();
|
Chris@16
|
463 }
|
Chris@16
|
464 /*!
|
Chris@16
|
465 * The method pushes the constructed message to the logging core
|
Chris@16
|
466 *
|
Chris@16
|
467 * \param rec The log record with the formatted message
|
Chris@16
|
468 */
|
Chris@16
|
469 void push_record(BOOST_RV_REF(record) rec)
|
Chris@16
|
470 {
|
Chris@16
|
471 typename base_type::push_record_lock lock(base_type::get_threading_model());
|
Chris@16
|
472 base_type::push_record_unlocked(boost::move(rec));
|
Chris@16
|
473 }
|
Chris@16
|
474 /*!
|
Chris@16
|
475 * Thread-safe implementation of swap
|
Chris@16
|
476 */
|
Chris@16
|
477 void swap(basic_composite_logger& that)
|
Chris@16
|
478 {
|
Chris@16
|
479 boost::log::aux::multiple_unique_lock2<
|
Chris@16
|
480 threading_model,
|
Chris@16
|
481 threading_model
|
Chris@16
|
482 > lock(base_type::get_threading_model(), that.get_threading_model());
|
Chris@16
|
483 base_type::swap_unlocked(that);
|
Chris@16
|
484 }
|
Chris@16
|
485
|
Chris@16
|
486 protected:
|
Chris@16
|
487 /*!
|
Chris@16
|
488 * Assignment for the final class. Threadsafe, provides strong exception guarantee.
|
Chris@16
|
489 */
|
Chris@16
|
490 FinalT& assign(FinalT const& that)
|
Chris@16
|
491 {
|
Chris@16
|
492 BOOST_LOG_ASSUME(this != NULL);
|
Chris@16
|
493 if (static_cast< FinalT* >(this) != boost::addressof(that))
|
Chris@16
|
494 {
|
Chris@16
|
495 // We'll have to explicitly create the copy in order to make sure it's unlocked when we attempt to lock *this
|
Chris@16
|
496 FinalT tmp(that);
|
Chris@16
|
497 boost::log::aux::exclusive_lock_guard< threading_model > lock(base_type::get_threading_model());
|
Chris@16
|
498 base_type::swap_unlocked(tmp);
|
Chris@16
|
499 }
|
Chris@16
|
500 return static_cast< FinalT& >(*this);
|
Chris@16
|
501 }
|
Chris@16
|
502 };
|
Chris@16
|
503
|
Chris@16
|
504 //! An optimized composite logger version with no multithreading support
|
Chris@16
|
505 template< typename CharT, typename FinalT, typename FeaturesT >
|
Chris@16
|
506 class basic_composite_logger< CharT, FinalT, single_thread_model, FeaturesT > :
|
Chris@16
|
507 public boost::log::sources::aux::inherit_features<
|
Chris@16
|
508 basic_logger< CharT, FinalT, single_thread_model >,
|
Chris@16
|
509 FeaturesT
|
Chris@16
|
510 >::type
|
Chris@16
|
511 {
|
Chris@16
|
512 private:
|
Chris@16
|
513 typedef typename boost::log::sources::aux::inherit_features<
|
Chris@16
|
514 basic_logger< CharT, FinalT, single_thread_model >,
|
Chris@16
|
515 FeaturesT
|
Chris@16
|
516 >::type base_type;
|
Chris@16
|
517
|
Chris@16
|
518 protected:
|
Chris@16
|
519 typedef basic_composite_logger logger_base;
|
Chris@16
|
520 BOOST_COPYABLE_AND_MOVABLE_ALT(logger_base)
|
Chris@16
|
521
|
Chris@16
|
522 public:
|
Chris@16
|
523 typedef typename base_type::threading_model threading_model;
|
Chris@16
|
524
|
Chris@16
|
525 #endif // !defined(BOOST_LOG_NO_THREADS)
|
Chris@16
|
526
|
Chris@16
|
527 public:
|
Chris@16
|
528 basic_composite_logger() {}
|
Chris@16
|
529 basic_composite_logger(basic_composite_logger const& that) :
|
Chris@16
|
530 base_type(static_cast< base_type const& >(that))
|
Chris@16
|
531 {
|
Chris@16
|
532 }
|
Chris@16
|
533 basic_composite_logger(BOOST_RV_REF(logger_base) that) :
|
Chris@16
|
534 base_type(boost::move(static_cast< base_type& >(that)))
|
Chris@16
|
535 {
|
Chris@16
|
536 }
|
Chris@16
|
537 template< typename ArgsT >
|
Chris@16
|
538 explicit basic_composite_logger(ArgsT const& args) : base_type(args)
|
Chris@16
|
539 {
|
Chris@16
|
540 }
|
Chris@16
|
541
|
Chris@16
|
542 std::pair< attribute_set::iterator, bool > add_attribute(attribute_name const& name, attribute const& attr)
|
Chris@16
|
543 {
|
Chris@16
|
544 return base_type::add_attribute_unlocked(name, attr);
|
Chris@16
|
545 }
|
Chris@16
|
546 void remove_attribute(attribute_set::iterator it)
|
Chris@16
|
547 {
|
Chris@16
|
548 base_type::remove_attribute_unlocked(it);
|
Chris@16
|
549 }
|
Chris@16
|
550 void remove_all_attributes()
|
Chris@16
|
551 {
|
Chris@16
|
552 base_type::remove_all_attributes_unlocked();
|
Chris@16
|
553 }
|
Chris@16
|
554 attribute_set get_attributes() const
|
Chris@16
|
555 {
|
Chris@16
|
556 return base_type::get_attributes_unlocked();
|
Chris@16
|
557 }
|
Chris@16
|
558 void set_attributes(attribute_set const& attrs)
|
Chris@16
|
559 {
|
Chris@16
|
560 base_type::set_attributes_unlocked(attrs);
|
Chris@16
|
561 }
|
Chris@16
|
562 record open_record()
|
Chris@16
|
563 {
|
Chris@16
|
564 // Perform a quick check first
|
Chris@16
|
565 if (this->core()->get_logging_enabled())
|
Chris@16
|
566 return base_type::open_record_unlocked(boost::log::aux::empty_arg_list());
|
Chris@16
|
567 else
|
Chris@16
|
568 return record();
|
Chris@16
|
569 }
|
Chris@16
|
570 template< typename ArgsT >
|
Chris@16
|
571 record open_record(ArgsT const& args)
|
Chris@16
|
572 {
|
Chris@16
|
573 // Perform a quick check first
|
Chris@16
|
574 if (this->core()->get_logging_enabled())
|
Chris@16
|
575 return base_type::open_record_unlocked(args);
|
Chris@16
|
576 else
|
Chris@16
|
577 return record();
|
Chris@16
|
578 }
|
Chris@16
|
579 void push_record(BOOST_RV_REF(record) rec)
|
Chris@16
|
580 {
|
Chris@16
|
581 base_type::push_record_unlocked(boost::move(rec));
|
Chris@16
|
582 }
|
Chris@16
|
583 void swap(basic_composite_logger& that)
|
Chris@16
|
584 {
|
Chris@16
|
585 base_type::swap_unlocked(that);
|
Chris@16
|
586 }
|
Chris@16
|
587
|
Chris@16
|
588 protected:
|
Chris@16
|
589 FinalT& assign(FinalT that)
|
Chris@16
|
590 {
|
Chris@16
|
591 base_type::swap_unlocked(that);
|
Chris@16
|
592 return static_cast< FinalT& >(*this);
|
Chris@16
|
593 }
|
Chris@16
|
594 };
|
Chris@16
|
595
|
Chris@16
|
596
|
Chris@16
|
597 #ifndef BOOST_LOG_DOXYGEN_PASS
|
Chris@16
|
598
|
Chris@16
|
599 #define BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS_IMPL(class_type, typename_keyword)\
|
Chris@16
|
600 public:\
|
Chris@16
|
601 BOOST_DEFAULTED_FUNCTION(class_type(), {})\
|
Chris@16
|
602 class_type(class_type const& that) : class_type::logger_base(\
|
Chris@16
|
603 static_cast< typename_keyword() class_type::logger_base const& >(that)) {}\
|
Chris@16
|
604 class_type(BOOST_RV_REF(class_type) that) : class_type::logger_base(\
|
Chris@16
|
605 ::boost::move(static_cast< typename_keyword() class_type::logger_base& >(that))) {}\
|
Chris@16
|
606 BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_FORWARD(class_type, class_type::logger_base)\
|
Chris@16
|
607
|
Chris@16
|
608 #endif // BOOST_LOG_DOXYGEN_PASS
|
Chris@16
|
609
|
Chris@16
|
610 #define BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS(class_type)\
|
Chris@16
|
611 BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS_IMPL(class_type, BOOST_PP_EMPTY)
|
Chris@16
|
612
|
Chris@16
|
613 #define BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS_TEMPLATE(class_type)\
|
Chris@16
|
614 BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS_IMPL(class_type, BOOST_PP_IDENTITY(typename))
|
Chris@16
|
615
|
Chris@16
|
616 #define BOOST_LOG_FORWARD_LOGGER_ASSIGNMENT(class_type)\
|
Chris@16
|
617 public:\
|
Chris@16
|
618 class_type& operator= (BOOST_COPY_ASSIGN_REF(class_type) that)\
|
Chris@16
|
619 {\
|
Chris@16
|
620 return class_type::logger_base::assign(static_cast< class_type const& >(that));\
|
Chris@16
|
621 }\
|
Chris@16
|
622 class_type& operator= (BOOST_RV_REF(class_type) that)\
|
Chris@16
|
623 {\
|
Chris@16
|
624 BOOST_LOG_EXPR_IF_MT(::boost::log::aux::exclusive_lock_guard< class_type::threading_model > lock(this->get_threading_model());)\
|
Chris@16
|
625 this->swap_unlocked(that);\
|
Chris@16
|
626 return *this;\
|
Chris@16
|
627 }
|
Chris@16
|
628
|
Chris@16
|
629 #define BOOST_LOG_FORWARD_LOGGER_ASSIGNMENT_TEMPLATE(class_type)\
|
Chris@16
|
630 public:\
|
Chris@16
|
631 class_type& operator= (BOOST_COPY_ASSIGN_REF(class_type) that)\
|
Chris@16
|
632 {\
|
Chris@16
|
633 return class_type::logger_base::assign(static_cast< class_type const& >(that));\
|
Chris@16
|
634 }\
|
Chris@16
|
635 class_type& operator= (BOOST_RV_REF(class_type) that)\
|
Chris@16
|
636 {\
|
Chris@16
|
637 BOOST_LOG_EXPR_IF_MT(::boost::log::aux::exclusive_lock_guard< typename class_type::threading_model > lock(this->get_threading_model());)\
|
Chris@16
|
638 this->swap_unlocked(that);\
|
Chris@16
|
639 return *this;\
|
Chris@16
|
640 }
|
Chris@16
|
641
|
Chris@16
|
642 #define BOOST_LOG_FORWARD_LOGGER_MEMBERS(class_type)\
|
Chris@16
|
643 BOOST_COPYABLE_AND_MOVABLE(class_type)\
|
Chris@16
|
644 BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS(class_type)\
|
Chris@16
|
645 BOOST_LOG_FORWARD_LOGGER_ASSIGNMENT(class_type)
|
Chris@16
|
646
|
Chris@16
|
647 #define BOOST_LOG_FORWARD_LOGGER_MEMBERS_TEMPLATE(class_type)\
|
Chris@16
|
648 BOOST_COPYABLE_AND_MOVABLE(class_type)\
|
Chris@16
|
649 BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS_TEMPLATE(class_type)\
|
Chris@16
|
650 BOOST_LOG_FORWARD_LOGGER_ASSIGNMENT_TEMPLATE(class_type)
|
Chris@16
|
651
|
Chris@16
|
652 } // namespace sources
|
Chris@16
|
653
|
Chris@16
|
654 BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
Chris@16
|
655
|
Chris@16
|
656 } // namespace boost
|
Chris@16
|
657
|
Chris@16
|
658 /*!
|
Chris@16
|
659 * \brief The macro declares a logger class that inherits a number of base classes
|
Chris@16
|
660 *
|
Chris@16
|
661 * \param type_name The name of the logger class to declare
|
Chris@16
|
662 * \param char_type The character type of the logger. Either char or wchar_t expected.
|
Chris@16
|
663 * \param base_seq A Boost.Preprocessor sequence of type identifiers of the base classes templates
|
Chris@16
|
664 * \param threading A threading model class
|
Chris@16
|
665 */
|
Chris@16
|
666 #define BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, char_type, base_seq, threading)\
|
Chris@16
|
667 class type_name :\
|
Chris@16
|
668 public ::boost::log::sources::basic_composite_logger<\
|
Chris@16
|
669 char_type,\
|
Chris@16
|
670 type_name,\
|
Chris@16
|
671 threading,\
|
Chris@16
|
672 ::boost::log::sources::features< BOOST_PP_SEQ_ENUM(base_seq) >\
|
Chris@16
|
673 >\
|
Chris@16
|
674 {\
|
Chris@16
|
675 BOOST_LOG_FORWARD_LOGGER_MEMBERS(type_name)\
|
Chris@16
|
676 }
|
Chris@16
|
677
|
Chris@16
|
678
|
Chris@16
|
679
|
Chris@16
|
680 #ifdef BOOST_LOG_USE_CHAR
|
Chris@16
|
681
|
Chris@16
|
682 /*!
|
Chris@16
|
683 * \brief The macro declares a narrow-char logger class that inherits a number of base classes
|
Chris@16
|
684 *
|
Chris@16
|
685 * Equivalent to BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, char, base_seq, single_thread_model)
|
Chris@16
|
686 *
|
Chris@16
|
687 * \param type_name The name of the logger class to declare
|
Chris@16
|
688 * \param base_seq A Boost.Preprocessor sequence of type identifiers of the base classes templates
|
Chris@16
|
689 */
|
Chris@16
|
690 #define BOOST_LOG_DECLARE_LOGGER(type_name, base_seq)\
|
Chris@16
|
691 BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, char, base_seq, ::boost::log::sources::single_thread_model)
|
Chris@16
|
692
|
Chris@16
|
693 #if !defined(BOOST_LOG_NO_THREADS)
|
Chris@16
|
694
|
Chris@16
|
695 /*!
|
Chris@16
|
696 * \brief The macro declares a narrow-char thread-safe logger class that inherits a number of base classes
|
Chris@16
|
697 *
|
Chris@16
|
698 * Equivalent to <tt>BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, char, base_seq, multi_thread_model< shared_mutex >)</tt>
|
Chris@16
|
699 *
|
Chris@16
|
700 * \param type_name The name of the logger class to declare
|
Chris@16
|
701 * \param base_seq A Boost.Preprocessor sequence of type identifiers of the base classes templates
|
Chris@16
|
702 */
|
Chris@16
|
703 #define BOOST_LOG_DECLARE_LOGGER_MT(type_name, base_seq)\
|
Chris@16
|
704 BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, char, base_seq,\
|
Chris@16
|
705 ::boost::log::sources::multi_thread_model< ::boost::shared_mutex >)
|
Chris@16
|
706
|
Chris@16
|
707 #endif // !defined(BOOST_LOG_NO_THREADS)
|
Chris@16
|
708 #endif // BOOST_LOG_USE_CHAR
|
Chris@16
|
709
|
Chris@16
|
710 #ifdef BOOST_LOG_USE_WCHAR_T
|
Chris@16
|
711
|
Chris@16
|
712 /*!
|
Chris@16
|
713 * \brief The macro declares a wide-char logger class that inherits a number of base classes
|
Chris@16
|
714 *
|
Chris@16
|
715 * Equivalent to BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, wchar_t, base_seq, single_thread_model)
|
Chris@16
|
716 *
|
Chris@16
|
717 * \param type_name The name of the logger class to declare
|
Chris@16
|
718 * \param base_seq A Boost.Preprocessor sequence of type identifiers of the base classes templates
|
Chris@16
|
719 */
|
Chris@16
|
720 #define BOOST_LOG_DECLARE_WLOGGER(type_name, base_seq)\
|
Chris@16
|
721 BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, wchar_t, base_seq, ::boost::log::sources::single_thread_model)
|
Chris@16
|
722
|
Chris@16
|
723 #if !defined(BOOST_LOG_NO_THREADS)
|
Chris@16
|
724
|
Chris@16
|
725 /*!
|
Chris@16
|
726 * \brief The macro declares a wide-char thread-safe logger class that inherits a number of base classes
|
Chris@16
|
727 *
|
Chris@16
|
728 * Equivalent to <tt>BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, wchar_t, base_seq, multi_thread_model< shared_mutex >)</tt>
|
Chris@16
|
729 *
|
Chris@16
|
730 * \param type_name The name of the logger class to declare
|
Chris@16
|
731 * \param base_seq A Boost.Preprocessor sequence of type identifiers of the base classes templates
|
Chris@16
|
732 */
|
Chris@16
|
733 #define BOOST_LOG_DECLARE_WLOGGER_MT(type_name, base_seq)\
|
Chris@16
|
734 BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, wchar_t, base_seq,\
|
Chris@16
|
735 ::boost::log::sources::multi_thread_model< ::boost::shared_mutex >)
|
Chris@16
|
736
|
Chris@16
|
737 #endif // !defined(BOOST_LOG_NO_THREADS)
|
Chris@16
|
738 #endif // BOOST_LOG_USE_WCHAR_T
|
Chris@16
|
739
|
Chris@16
|
740 #include <boost/log/detail/footer.hpp>
|
Chris@16
|
741
|
Chris@16
|
742 #endif // BOOST_LOG_SOURCES_BASIC_LOGGER_HPP_INCLUDED_
|