channel_feature.hpp 7.3 KB

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