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 channel_feature.hpp
|
Chris@16
|
9 * \author Andrey Semashev
|
Chris@16
|
10 * \date 28.02.2008
|
Chris@16
|
11 *
|
Chris@16
|
12 * The header contains implementation of a channel support feature.
|
Chris@16
|
13 */
|
Chris@16
|
14
|
Chris@16
|
15 #ifndef BOOST_LOG_SOURCES_CHANNEL_FEATURE_HPP_INCLUDED_
|
Chris@16
|
16 #define BOOST_LOG_SOURCES_CHANNEL_FEATURE_HPP_INCLUDED_
|
Chris@16
|
17
|
Chris@16
|
18 #include <string>
|
Chris@16
|
19 #include <boost/move/core.hpp>
|
Chris@16
|
20 #include <boost/move/utility.hpp>
|
Chris@16
|
21 #include <boost/log/detail/config.hpp>
|
Chris@16
|
22 #include <boost/log/detail/locks.hpp>
|
Chris@16
|
23 #include <boost/log/detail/default_attribute_names.hpp>
|
Chris@16
|
24 #include <boost/log/keywords/channel.hpp>
|
Chris@16
|
25 #include <boost/log/attributes/mutable_constant.hpp>
|
Chris@16
|
26 #include <boost/log/utility/strictest_lock.hpp>
|
Chris@16
|
27 #include <boost/log/core/record.hpp>
|
Chris@16
|
28 #include <boost/log/detail/header.hpp>
|
Chris@16
|
29
|
Chris@16
|
30 #ifdef BOOST_HAS_PRAGMA_ONCE
|
Chris@16
|
31 #pragma once
|
Chris@16
|
32 #endif
|
Chris@16
|
33
|
Chris@16
|
34 namespace boost {
|
Chris@16
|
35
|
Chris@16
|
36 BOOST_LOG_OPEN_NAMESPACE
|
Chris@16
|
37
|
Chris@16
|
38 namespace sources {
|
Chris@16
|
39
|
Chris@16
|
40 /*!
|
Chris@16
|
41 * \brief Channel feature implementation
|
Chris@16
|
42 */
|
Chris@16
|
43 template< typename BaseT, typename ChannelT >
|
Chris@16
|
44 class basic_channel_logger :
|
Chris@16
|
45 public BaseT
|
Chris@16
|
46 {
|
Chris@16
|
47 //! Base type
|
Chris@16
|
48 typedef BaseT base_type;
|
Chris@16
|
49 typedef basic_channel_logger this_type;
|
Chris@16
|
50 BOOST_COPYABLE_AND_MOVABLE_ALT(this_type)
|
Chris@16
|
51
|
Chris@16
|
52 public:
|
Chris@16
|
53 //! Character type
|
Chris@16
|
54 typedef typename base_type::char_type char_type;
|
Chris@16
|
55 //! Final type
|
Chris@16
|
56 typedef typename base_type::final_type final_type;
|
Chris@16
|
57 //! Threading model being used
|
Chris@16
|
58 typedef typename base_type::threading_model threading_model;
|
Chris@16
|
59
|
Chris@16
|
60 //! Channel type
|
Chris@16
|
61 typedef ChannelT channel_type;
|
Chris@16
|
62 //! Channel attribute type
|
Chris@16
|
63 typedef attributes::mutable_constant< channel_type > channel_attribute;
|
Chris@16
|
64
|
Chris@16
|
65 //! Lock requirement for the \c open_record_unlocked method
|
Chris@16
|
66 typedef typename strictest_lock<
|
Chris@16
|
67 typename base_type::open_record_lock,
|
Chris@16
|
68 #ifndef BOOST_LOG_NO_THREADS
|
Chris@16
|
69 boost::log::aux::exclusive_lock_guard< threading_model >
|
Chris@16
|
70 #else
|
Chris@16
|
71 no_lock< threading_model >
|
Chris@16
|
72 #endif // !defined(BOOST_LOG_NO_THREADS)
|
Chris@16
|
73 >::type open_record_lock;
|
Chris@16
|
74
|
Chris@16
|
75 //! Lock requirement for the \c swap_unlocked method
|
Chris@16
|
76 typedef typename strictest_lock<
|
Chris@16
|
77 typename base_type::swap_lock,
|
Chris@16
|
78 #ifndef BOOST_LOG_NO_THREADS
|
Chris@16
|
79 boost::log::aux::exclusive_lock_guard< threading_model >
|
Chris@16
|
80 #else
|
Chris@16
|
81 no_lock< threading_model >
|
Chris@16
|
82 #endif // !defined(BOOST_LOG_NO_THREADS)
|
Chris@16
|
83 >::type swap_lock;
|
Chris@16
|
84
|
Chris@16
|
85 private:
|
Chris@16
|
86 //! Default channel name generator
|
Chris@16
|
87 struct make_default_channel_name
|
Chris@16
|
88 {
|
Chris@16
|
89 typedef channel_type result_type;
|
Chris@16
|
90 result_type operator() () const { return result_type(); }
|
Chris@16
|
91 };
|
Chris@16
|
92
|
Chris@16
|
93 private:
|
Chris@16
|
94 //! Channel attribute
|
Chris@16
|
95 channel_attribute m_ChannelAttr;
|
Chris@16
|
96
|
Chris@16
|
97 public:
|
Chris@16
|
98 /*!
|
Chris@16
|
99 * Default constructor. The constructed logger has the default-constructed channel name.
|
Chris@16
|
100 */
|
Chris@16
|
101 basic_channel_logger() : base_type(), m_ChannelAttr(channel_type())
|
Chris@16
|
102 {
|
Chris@16
|
103 base_type::add_attribute_unlocked(boost::log::aux::default_attribute_names::channel(), m_ChannelAttr);
|
Chris@16
|
104 }
|
Chris@16
|
105 /*!
|
Chris@16
|
106 * Copy constructor
|
Chris@16
|
107 */
|
Chris@16
|
108 basic_channel_logger(basic_channel_logger const& that) :
|
Chris@16
|
109 base_type(static_cast< base_type const& >(that)),
|
Chris@16
|
110 m_ChannelAttr(that.m_ChannelAttr)
|
Chris@16
|
111 {
|
Chris@16
|
112 base_type::attributes()[boost::log::aux::default_attribute_names::channel()] = m_ChannelAttr;
|
Chris@16
|
113 }
|
Chris@16
|
114 /*!
|
Chris@16
|
115 * Move constructor
|
Chris@16
|
116 */
|
Chris@16
|
117 basic_channel_logger(BOOST_RV_REF(basic_channel_logger) that) :
|
Chris@16
|
118 base_type(boost::move(static_cast< base_type& >(that))),
|
Chris@16
|
119 m_ChannelAttr(boost::move(that.m_ChannelAttr))
|
Chris@16
|
120 {
|
Chris@16
|
121 base_type::attributes()[boost::log::aux::default_attribute_names::channel()] = m_ChannelAttr;
|
Chris@16
|
122 }
|
Chris@16
|
123 /*!
|
Chris@16
|
124 * Constructor with arguments. Allows to register a channel name attribute on construction.
|
Chris@16
|
125 *
|
Chris@16
|
126 * \param args A set of named arguments. The following arguments are supported:
|
Chris@16
|
127 * \li \c channel - a string that represents the channel name
|
Chris@16
|
128 */
|
Chris@16
|
129 template< typename ArgsT >
|
Chris@16
|
130 explicit basic_channel_logger(ArgsT const& args) :
|
Chris@16
|
131 base_type(args),
|
Chris@16
|
132 m_ChannelAttr(args[keywords::channel || make_default_channel_name()])
|
Chris@16
|
133 {
|
Chris@16
|
134 base_type::add_attribute_unlocked(boost::log::aux::default_attribute_names::channel(), m_ChannelAttr);
|
Chris@16
|
135 }
|
Chris@16
|
136
|
Chris@16
|
137 /*!
|
Chris@16
|
138 * The observer of the channel name
|
Chris@16
|
139 *
|
Chris@16
|
140 * \return The channel name that was set by the logger
|
Chris@16
|
141 */
|
Chris@16
|
142 channel_type channel() const
|
Chris@16
|
143 {
|
Chris@16
|
144 BOOST_LOG_EXPR_IF_MT(boost::log::aux::shared_lock_guard< const threading_model > lock(this->get_threading_model());)
|
Chris@16
|
145 return m_ChannelAttr.get();
|
Chris@16
|
146 }
|
Chris@16
|
147
|
Chris@16
|
148 /*!
|
Chris@16
|
149 * The setter of the channel name
|
Chris@16
|
150 *
|
Chris@16
|
151 * \param ch The channel name to be set for the logger
|
Chris@16
|
152 */
|
Chris@16
|
153 void channel(channel_type const& ch)
|
Chris@16
|
154 {
|
Chris@16
|
155 BOOST_LOG_EXPR_IF_MT(boost::log::aux::exclusive_lock_guard< threading_model > lock(this->get_threading_model());)
|
Chris@16
|
156 m_ChannelAttr.set(ch);
|
Chris@16
|
157 }
|
Chris@16
|
158
|
Chris@16
|
159 protected:
|
Chris@16
|
160 /*!
|
Chris@16
|
161 * Channel attribute accessor
|
Chris@16
|
162 */
|
Chris@16
|
163 channel_attribute const& get_channel_attribute() const { return m_ChannelAttr; }
|
Chris@16
|
164
|
Chris@16
|
165 /*!
|
Chris@16
|
166 * Unlocked \c open_record
|
Chris@16
|
167 */
|
Chris@16
|
168 template< typename ArgsT >
|
Chris@16
|
169 record open_record_unlocked(ArgsT const& args)
|
Chris@16
|
170 {
|
Chris@16
|
171 return open_record_with_channel_unlocked(args, args[keywords::channel | parameter::void_()]);
|
Chris@16
|
172 }
|
Chris@16
|
173
|
Chris@16
|
174 /*!
|
Chris@16
|
175 * Unlocked swap
|
Chris@16
|
176 */
|
Chris@16
|
177 void swap_unlocked(basic_channel_logger& that)
|
Chris@16
|
178 {
|
Chris@16
|
179 base_type::swap_unlocked(static_cast< base_type& >(that));
|
Chris@16
|
180 m_ChannelAttr.swap(that.m_ChannelAttr);
|
Chris@16
|
181 }
|
Chris@16
|
182
|
Chris@16
|
183 private:
|
Chris@16
|
184 //! The \c open_record implementation for the case when the channel is specified in log statement
|
Chris@16
|
185 template< typename ArgsT, typename T >
|
Chris@16
|
186 record open_record_with_channel_unlocked(ArgsT const& args, T const& ch)
|
Chris@16
|
187 {
|
Chris@16
|
188 m_ChannelAttr.set(ch);
|
Chris@16
|
189 return base_type::open_record_unlocked(args);
|
Chris@16
|
190 }
|
Chris@16
|
191 //! The \c open_record implementation for the case when the channel is not specified in log statement
|
Chris@16
|
192 template< typename ArgsT >
|
Chris@16
|
193 record open_record_with_channel_unlocked(ArgsT const& args, parameter::void_)
|
Chris@16
|
194 {
|
Chris@16
|
195 return base_type::open_record_unlocked(args);
|
Chris@16
|
196 }
|
Chris@16
|
197 };
|
Chris@16
|
198
|
Chris@16
|
199 /*!
|
Chris@16
|
200 * \brief Channel support feature
|
Chris@16
|
201 *
|
Chris@16
|
202 * The logger with this feature automatically registers an attribute with the specified
|
Chris@16
|
203 * on construction value, which is a channel name. The channel name can be modified
|
Chris@16
|
204 * through the logger life time, either by calling the \c channel method or by specifying
|
Chris@16
|
205 * the name in the logging statement.
|
Chris@16
|
206 *
|
Chris@16
|
207 * The type of the channel name can be customized by providing it as a template parameter
|
Chris@16
|
208 * to the feature template. By default, a string will be used.
|
Chris@16
|
209 */
|
Chris@16
|
210 template< typename ChannelT = std::string >
|
Chris@16
|
211 struct channel
|
Chris@16
|
212 {
|
Chris@16
|
213 template< typename BaseT >
|
Chris@16
|
214 struct apply
|
Chris@16
|
215 {
|
Chris@16
|
216 typedef basic_channel_logger<
|
Chris@16
|
217 BaseT,
|
Chris@16
|
218 ChannelT
|
Chris@16
|
219 > type;
|
Chris@16
|
220 };
|
Chris@16
|
221 };
|
Chris@16
|
222
|
Chris@16
|
223 } // namespace sources
|
Chris@16
|
224
|
Chris@16
|
225 BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
Chris@16
|
226
|
Chris@16
|
227 } // namespace boost
|
Chris@16
|
228
|
Chris@16
|
229 //! The macro allows to put a record with a specific channel name into log
|
Chris@16
|
230 #define BOOST_LOG_STREAM_CHANNEL(logger, chan)\
|
Chris@16
|
231 BOOST_LOG_STREAM_WITH_PARAMS((logger), (::boost::log::keywords::channel = (chan)))
|
Chris@16
|
232
|
Chris@16
|
233 #ifndef BOOST_LOG_NO_SHORTHAND_NAMES
|
Chris@16
|
234
|
Chris@16
|
235 //! An equivalent to BOOST_LOG_STREAM_CHANNEL(logger, chan)
|
Chris@16
|
236 #define BOOST_LOG_CHANNEL(logger, chan) BOOST_LOG_STREAM_CHANNEL(logger, chan)
|
Chris@16
|
237
|
Chris@16
|
238 #endif // BOOST_LOG_NO_SHORTHAND_NAMES
|
Chris@16
|
239
|
Chris@16
|
240 #include <boost/log/detail/footer.hpp>
|
Chris@16
|
241
|
Chris@16
|
242 #endif // BOOST_LOG_SOURCES_CHANNEL_FEATURE_HPP_INCLUDED_
|