Chris@16: /* Chris@101: * Copyright Andrey Semashev 2007 - 2015. Chris@16: * Distributed under the Boost Software License, Version 1.0. Chris@16: * (See accompanying file LICENSE_1_0.txt or copy at Chris@16: * http://www.boost.org/LICENSE_1_0.txt) Chris@16: */ Chris@16: /*! Chris@16: * \file channel_feature.hpp Chris@16: * \author Andrey Semashev Chris@16: * \date 28.02.2008 Chris@16: * Chris@16: * The header contains implementation of a channel support feature. Chris@16: */ Chris@16: Chris@16: #ifndef BOOST_LOG_SOURCES_CHANNEL_FEATURE_HPP_INCLUDED_ Chris@16: #define BOOST_LOG_SOURCES_CHANNEL_FEATURE_HPP_INCLUDED_ Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #ifdef BOOST_HAS_PRAGMA_ONCE Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: BOOST_LOG_OPEN_NAMESPACE Chris@16: Chris@16: namespace sources { Chris@16: Chris@16: /*! Chris@16: * \brief Channel feature implementation Chris@16: */ Chris@16: template< typename BaseT, typename ChannelT > Chris@16: class basic_channel_logger : Chris@16: public BaseT Chris@16: { Chris@16: //! Base type Chris@16: typedef BaseT base_type; Chris@16: typedef basic_channel_logger this_type; Chris@16: BOOST_COPYABLE_AND_MOVABLE_ALT(this_type) Chris@16: Chris@16: public: Chris@16: //! Character type Chris@16: typedef typename base_type::char_type char_type; Chris@16: //! Final type Chris@16: typedef typename base_type::final_type final_type; Chris@16: //! Threading model being used Chris@16: typedef typename base_type::threading_model threading_model; Chris@16: Chris@16: //! Channel type Chris@16: typedef ChannelT channel_type; Chris@16: //! Channel attribute type Chris@16: typedef attributes::mutable_constant< channel_type > channel_attribute; Chris@16: Chris@16: //! Lock requirement for the \c open_record_unlocked method Chris@16: typedef typename strictest_lock< Chris@16: typename base_type::open_record_lock, Chris@16: #ifndef BOOST_LOG_NO_THREADS Chris@16: boost::log::aux::exclusive_lock_guard< threading_model > Chris@16: #else Chris@16: no_lock< threading_model > Chris@16: #endif // !defined(BOOST_LOG_NO_THREADS) Chris@16: >::type open_record_lock; Chris@16: Chris@16: //! Lock requirement for the \c swap_unlocked method Chris@16: typedef typename strictest_lock< Chris@16: typename base_type::swap_lock, Chris@16: #ifndef BOOST_LOG_NO_THREADS Chris@16: boost::log::aux::exclusive_lock_guard< threading_model > Chris@16: #else Chris@16: no_lock< threading_model > Chris@16: #endif // !defined(BOOST_LOG_NO_THREADS) Chris@16: >::type swap_lock; Chris@16: Chris@16: private: Chris@16: //! Default channel name generator Chris@16: struct make_default_channel_name Chris@16: { Chris@16: typedef channel_type result_type; Chris@16: result_type operator() () const { return result_type(); } Chris@16: }; Chris@16: Chris@16: private: Chris@16: //! Channel attribute Chris@16: channel_attribute m_ChannelAttr; Chris@16: Chris@16: public: Chris@16: /*! Chris@16: * Default constructor. The constructed logger has the default-constructed channel name. Chris@16: */ Chris@16: basic_channel_logger() : base_type(), m_ChannelAttr(channel_type()) Chris@16: { Chris@16: base_type::add_attribute_unlocked(boost::log::aux::default_attribute_names::channel(), m_ChannelAttr); Chris@16: } Chris@16: /*! Chris@16: * Copy constructor Chris@16: */ Chris@16: basic_channel_logger(basic_channel_logger const& that) : Chris@16: base_type(static_cast< base_type const& >(that)), Chris@16: m_ChannelAttr(that.m_ChannelAttr) Chris@16: { Chris@16: base_type::attributes()[boost::log::aux::default_attribute_names::channel()] = m_ChannelAttr; Chris@16: } Chris@16: /*! Chris@16: * Move constructor Chris@16: */ Chris@16: basic_channel_logger(BOOST_RV_REF(basic_channel_logger) that) : Chris@16: base_type(boost::move(static_cast< base_type& >(that))), Chris@16: m_ChannelAttr(boost::move(that.m_ChannelAttr)) Chris@16: { Chris@16: base_type::attributes()[boost::log::aux::default_attribute_names::channel()] = m_ChannelAttr; Chris@16: } Chris@16: /*! Chris@16: * Constructor with arguments. Allows to register a channel name attribute on construction. Chris@16: * Chris@16: * \param args A set of named arguments. The following arguments are supported: Chris@16: * \li \c channel - a string that represents the channel name Chris@16: */ Chris@16: template< typename ArgsT > Chris@16: explicit basic_channel_logger(ArgsT const& args) : Chris@16: base_type(args), Chris@16: m_ChannelAttr(args[keywords::channel || make_default_channel_name()]) Chris@16: { Chris@16: base_type::add_attribute_unlocked(boost::log::aux::default_attribute_names::channel(), m_ChannelAttr); Chris@16: } Chris@16: Chris@16: /*! Chris@16: * The observer of the channel name Chris@16: * Chris@16: * \return The channel name that was set by the logger Chris@16: */ Chris@16: channel_type channel() const Chris@16: { Chris@16: BOOST_LOG_EXPR_IF_MT(boost::log::aux::shared_lock_guard< const threading_model > lock(this->get_threading_model());) Chris@16: return m_ChannelAttr.get(); Chris@16: } Chris@16: Chris@16: /*! Chris@16: * The setter of the channel name Chris@16: * Chris@16: * \param ch The channel name to be set for the logger Chris@16: */ Chris@16: void channel(channel_type const& ch) Chris@16: { Chris@16: BOOST_LOG_EXPR_IF_MT(boost::log::aux::exclusive_lock_guard< threading_model > lock(this->get_threading_model());) Chris@16: m_ChannelAttr.set(ch); Chris@16: } Chris@16: Chris@16: protected: Chris@16: /*! Chris@16: * Channel attribute accessor Chris@16: */ Chris@16: channel_attribute const& get_channel_attribute() const { return m_ChannelAttr; } Chris@16: Chris@16: /*! Chris@16: * Unlocked \c open_record Chris@16: */ Chris@16: template< typename ArgsT > Chris@16: record open_record_unlocked(ArgsT const& args) Chris@16: { Chris@16: return open_record_with_channel_unlocked(args, args[keywords::channel | parameter::void_()]); Chris@16: } Chris@16: Chris@16: /*! Chris@16: * Unlocked swap Chris@16: */ Chris@16: void swap_unlocked(basic_channel_logger& that) Chris@16: { Chris@16: base_type::swap_unlocked(static_cast< base_type& >(that)); Chris@16: m_ChannelAttr.swap(that.m_ChannelAttr); Chris@16: } Chris@16: Chris@16: private: Chris@16: //! The \c open_record implementation for the case when the channel is specified in log statement Chris@16: template< typename ArgsT, typename T > Chris@16: record open_record_with_channel_unlocked(ArgsT const& args, T const& ch) Chris@16: { Chris@16: m_ChannelAttr.set(ch); Chris@16: return base_type::open_record_unlocked(args); Chris@16: } Chris@16: //! The \c open_record implementation for the case when the channel is not specified in log statement Chris@16: template< typename ArgsT > Chris@16: record open_record_with_channel_unlocked(ArgsT const& args, parameter::void_) Chris@16: { Chris@16: return base_type::open_record_unlocked(args); Chris@16: } Chris@16: }; Chris@16: Chris@16: /*! Chris@16: * \brief Channel support feature Chris@16: * Chris@16: * The logger with this feature automatically registers an attribute with the specified Chris@16: * on construction value, which is a channel name. The channel name can be modified Chris@16: * through the logger life time, either by calling the \c channel method or by specifying Chris@16: * the name in the logging statement. Chris@16: * Chris@16: * The type of the channel name can be customized by providing it as a template parameter Chris@16: * to the feature template. By default, a string will be used. Chris@16: */ Chris@16: template< typename ChannelT = std::string > Chris@16: struct channel Chris@16: { Chris@16: template< typename BaseT > Chris@16: struct apply Chris@16: { Chris@16: typedef basic_channel_logger< Chris@16: BaseT, Chris@16: ChannelT Chris@16: > type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: } // namespace sources Chris@16: Chris@16: BOOST_LOG_CLOSE_NAMESPACE // namespace log Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: //! The macro allows to put a record with a specific channel name into log Chris@16: #define BOOST_LOG_STREAM_CHANNEL(logger, chan)\ Chris@16: BOOST_LOG_STREAM_WITH_PARAMS((logger), (::boost::log::keywords::channel = (chan))) Chris@16: Chris@16: #ifndef BOOST_LOG_NO_SHORTHAND_NAMES Chris@16: Chris@16: //! An equivalent to BOOST_LOG_STREAM_CHANNEL(logger, chan) Chris@16: #define BOOST_LOG_CHANNEL(logger, chan) BOOST_LOG_STREAM_CHANNEL(logger, chan) Chris@16: Chris@16: #endif // BOOST_LOG_NO_SHORTHAND_NAMES Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // BOOST_LOG_SOURCES_CHANNEL_FEATURE_HPP_INCLUDED_