channel_feature.hpp 7.5 KB

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