Mercurial > hg > vamp-build-and-test
diff DEPENDENCIES/generic/include/boost/log/sinks/event_log_backend.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DEPENDENCIES/generic/include/boost/log/sinks/event_log_backend.hpp Tue Aug 05 11:11:38 2014 +0100 @@ -0,0 +1,662 @@ +/* + * Copyright Andrey Semashev 2007 - 2013. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + */ +/*! + * \file event_log_backend.hpp + * \author Andrey Semashev + * \date 07.11.2008 + * + * The header contains a logging sink backend that uses Windows NT event log API + * for signaling application events. + */ + +#ifndef BOOST_LOG_SINKS_EVENT_LOG_BACKEND_HPP_INCLUDED_ +#define BOOST_LOG_SINKS_EVENT_LOG_BACKEND_HPP_INCLUDED_ + +#include <boost/log/detail/config.hpp> + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#ifndef BOOST_LOG_WITHOUT_EVENT_LOG + +#include <map> +#include <vector> +#include <string> +#include <iosfwd> +#include <boost/filesystem/path.hpp> +#include <boost/log/detail/light_function.hpp> +#include <boost/log/detail/parameter_tools.hpp> +#include <boost/log/attributes/attribute_value_set.hpp> +#include <boost/log/keywords/message_file.hpp> +#include <boost/log/keywords/log_name.hpp> +#include <boost/log/keywords/log_source.hpp> +#include <boost/log/keywords/registration.hpp> +#include <boost/log/keywords/target.hpp> +#include <boost/log/sinks/basic_sink_backend.hpp> +#include <boost/log/sinks/frontend_requirements.hpp> +#include <boost/log/sinks/attribute_mapping.hpp> +#include <boost/log/sinks/event_log_constants.hpp> +#include <boost/log/core/record_view.hpp> +#include <boost/log/expressions/formatter.hpp> +#include <boost/log/detail/header.hpp> + +namespace boost { + +BOOST_LOG_OPEN_NAMESPACE + +namespace sinks { + +namespace event_log { + + //! Event log source registration modes + enum registration_mode + { + never, //!< Never register event source, even if it's not registered + on_demand, //!< Register if the source is not registered yet + forced //!< Register always, event if the source is already registered + }; + + /*! + * \brief Straightforward event type mapping + * + * This type of mapping assumes that attribute with a particular name always + * provides values that map directly onto the native event types. The mapping + * simply returns the extracted attribute value converted to the native event type. + */ + template< typename AttributeValueT = int > + class direct_event_type_mapping : + public basic_direct_mapping< event_type, AttributeValueT > + { + //! Base type + typedef basic_direct_mapping< event_type, AttributeValueT > base_type; + + public: + /*! + * Constructor + * + * \param name Attribute name + */ + explicit direct_event_type_mapping(attribute_name const& name) : + base_type(name, info) + { + } + }; + + /*! + * \brief Customizable event type mapping + * + * The class allows to setup a custom mapping between an attribute and native event types. + * The mapping should be initialized similarly to the standard \c map container, by using + * indexing operator and assignment. + */ + template< typename AttributeValueT = int > + class custom_event_type_mapping : + public basic_custom_mapping< event_type, AttributeValueT > + { + //! Base type + typedef basic_custom_mapping< event_type, AttributeValueT > base_type; + + public: + /*! + * Constructor + * + * \param name Attribute name + */ + explicit custom_event_type_mapping(attribute_name const& name) : + base_type(name, info) + { + } + }; + + /*! + * \brief Straightforward event ID mapping + * + * This type of mapping assumes that attribute with a particular name always + * provides values that map directly onto the event identifiers. The mapping + * simply returns the extracted attribute value converted to the event ID. + */ + template< typename AttributeValueT = int > + class direct_event_id_mapping : + public basic_direct_mapping< event_id, AttributeValueT > + { + //! Base type + typedef basic_direct_mapping< event_id, AttributeValueT > base_type; + + public: + /*! + * Constructor + * + * \param name Attribute name + */ + explicit direct_event_id_mapping(attribute_name const& name) : + base_type(name, make_event_id(0)) + { + } + }; + + /*! + * \brief Customizable event ID mapping + * + * The class allows to setup a custom mapping between an attribute and event identifiers. + * The mapping should be initialized similarly to the standard \c map container, by using + * indexing operator and assignment. + */ + template< typename AttributeValueT = int > + class custom_event_id_mapping : + public basic_custom_mapping< event_id, AttributeValueT > + { + //! Base type + typedef basic_custom_mapping< event_id, AttributeValueT > base_type; + + public: + /*! + * Constructor + * + * \param name Attribute name + */ + explicit custom_event_id_mapping(attribute_name const& name) : + base_type(name, make_event_id(0)) + { + } + }; + + /*! + * \brief Straightforward event category mapping + * + * This type of mapping assumes that attribute with a particular name always + * provides values that map directly onto the event categories. The mapping + * simply returns the extracted attribute value converted to the event category. + */ + template< typename AttributeValueT = int > + class direct_event_category_mapping : + public basic_direct_mapping< event_category, AttributeValueT > + { + //! Base type + typedef basic_direct_mapping< event_category, AttributeValueT > base_type; + + public: + /*! + * Constructor + * + * \param name Attribute name + */ + explicit direct_event_category_mapping(attribute_name const& name) : + base_type(name, make_event_category(0)) + { + } + }; + + /*! + * \brief Customizable event category mapping + * + * The class allows to setup a custom mapping between an attribute and event categories. + * The mapping should be initialized similarly to the standard \c map container, by using + * indexing operator and assignment. + */ + template< typename AttributeValueT = int > + class custom_event_category_mapping : + public basic_custom_mapping< event_category, AttributeValueT > + { + //! Base type + typedef basic_custom_mapping< event_category, AttributeValueT > base_type; + + public: + /*! + * Constructor + * + * \param name Attribute name + */ + explicit custom_event_category_mapping(attribute_name const& name) : + base_type(name, make_event_category(0)) + { + } + }; + + /*! + * \brief An event composer + * + * This class is a function object that extracts event identifier from the attribute values set + * and formats insertion strings for the particular event. Each insertion string is formatted with + * a distinct formatter, which can be created just like regular sinks formatters. + * + * Before using, the composer must be initialized with the following information: + * \li Event identifier extraction logic. One can use \c basic_direct_event_id_mapping or + * \c basic_custom_event_id_mapping classes in order to create such extractor and pass it + * to the composer constructor. + * \li Event identifiers and insertion string formatters. The composer provides the following + * syntax to provide this information: + * + * \code + * event_composer comp; + * comp[MY_EVENT_ID1] % formatter1 % ... % formatterN; + * comp[MY_EVENT_ID2] % formatter1 % ... % formatterN; + * ... + * \endcode + * + * The event identifiers in square brackets are provided by the message compiler generated + * header (the actual names are specified in the .mc file). The formatters represent + * the insertion strings that will be used to replace placeholders in event messages, + * thus the number and the order of the formatters must correspond to the message definition. + */ + template< typename CharT > + class BOOST_LOG_API basic_event_composer + { + public: + //! Character type + typedef CharT char_type; + //! String type to be used as a message text holder + typedef std::basic_string< char_type > string_type; + + //! Event identifier mapper type + typedef boost::log::aux::light_function< event_id (record_view const&) > event_id_mapper_type; + + //! Type of an insertion composer (a formatter) + typedef basic_formatter< char_type > formatter_type; + //! Type of the composed insertions list + typedef std::vector< string_type > insertion_list; + + private: + //! \cond + + //! The class that implements formatting of insertion strings + class insertion_composer; + + //! Type of the events map + typedef std::map< event_id, insertion_composer > event_map; + + //! A smart reference that puts formatters into the composer + class event_map_reference; + friend class event_map_reference; + class event_map_reference + { + private: + //! Event identifier + event_id m_ID; + //! A reference to the object that created the reference + basic_event_composer< char_type >& m_Owner; + //! A hint for the owner to optimize insertion + insertion_composer* m_Composer; + + public: + //! Initializing constructor + explicit event_map_reference(event_id id, basic_event_composer< char_type >& owner) : + m_ID(id), + m_Owner(owner), + m_Composer(0) + { + } + //! The operator puts the formatter into the composer + template< typename FormatterT > + event_map_reference& operator% (FormatterT const& fmt) + { + m_Composer = m_Owner.add_formatter(m_ID, m_Composer, formatter_type(fmt)); + return *this; + } + }; + + //! \endcond + + private: + //! The mapper that will extract the event identifier + event_id_mapper_type m_EventIDMapper; + //! The map of event identifiers and their insertion composers + event_map m_EventMap; + + public: + /*! + * Default constructor. Creates an empty map of events. + * + * \param id_mapper An event identifier mapping function that will be used to extract event ID from attribute values + */ + explicit basic_event_composer(event_id_mapper_type const& id_mapper); + /*! + * Copy constructor. Performs a deep copy of the object. + */ + basic_event_composer(basic_event_composer const& that); + /*! + * Destructor + */ + ~basic_event_composer(); + + /*! + * Assignment. Provides strong exception guarantee. + */ + basic_event_composer& operator= (basic_event_composer that); + /*! + * Swaps \c *this and \c that objects. + */ + void swap(basic_event_composer& that); + /*! + * Initiates creation of a new event description. The result of the operator can be used to + * add formatters for insertion strings construction. The returned reference type is implementation detail. + * + * \param id Event identifier. + */ + event_map_reference operator[] (event_id id); + /*! + * Initiates creation of a new event description. The result of the operator can be used to + * add formatters for insertion strings construction. The returned reference type is implementation detail. + * + * \param id Event identifier. + */ + event_map_reference operator[] (int id); + /*! + * Event composition operator. Extracts an event identifier from the attribute values by calling event ID mapper. + * Then runs all formatters that were registered for the event with the extracted ID. The results of formatting + * are returned in the \a insertions parameter. + * + * \param rec Log record view + * \param insertions A sequence of formatted insertion strings + * \return An event identifier that was extracted from \c attributes + */ + event_id operator() (record_view const& rec, insertion_list& insertions) const; + + private: +#ifndef BOOST_LOG_DOXYGEN_PASS + //! Adds a formatter to the insertion composers list + insertion_composer* add_formatter(event_id id, insertion_composer* composer, formatter_type const& fmt); +#endif // BOOST_LOG_DOXYGEN_PASS + }; + +#ifdef BOOST_LOG_USE_CHAR + typedef basic_event_composer< char > event_composer; //!< Convenience typedef for narrow-character logging +#endif +#ifdef BOOST_LOG_USE_WCHAR_T + typedef basic_event_composer< wchar_t > wevent_composer; //!< Convenience typedef for wide-character logging +#endif + +} // namespace event_log + +/*! + * \brief An implementation of a simple logging sink backend that emits events into Windows NT event log + * + * The sink uses Windows NT 5 (Windows 2000) and later event log API to emit events + * to an event log. The sink acts as an event source in terms of the API, it implements all needed resources + * and source registration in the Windows registry that is needed for the event delivery. + * + * The backend performs message text formatting. The composed text is then passed as the first + * and only string parameter of the event. The resource embedded into the backend describes the event + * so that the parameter is inserted into the event description text, thus making it visible + * in the event log. + * + * The backend allows to customize mapping of application severity levels to the native Windows event types. + * This allows to write portable code even if OS-specific sinks, such as this one, are used. + * + * \note Since the backend registers itself into Windows registry as the resource file that contains + * event description, it is important to keep the library binary in a stable place of the filesystem. + * Otherwise Windows might not be able to load event resources from the library and display + * events correctly. + * + * \note It is known that Windows is not able to find event resources in the application executable, + * which is linked against the static build of the library. Users are advised to use dynamic + * builds of the library to solve this problem. + */ +template< typename CharT > +class basic_simple_event_log_backend : + public basic_formatted_sink_backend< CharT, concurrent_feeding > +{ + //! Base type + typedef basic_formatted_sink_backend< CharT, concurrent_feeding > base_type; + //! Implementation type + struct implementation; + +public: + //! Character type + typedef typename base_type::char_type char_type; + //! String type to be used as a message text holder + typedef typename base_type::string_type string_type; + + //! Mapper type for the event type + typedef boost::log::aux::light_function< event_log::event_type (record_view const&) > event_type_mapper_type; + +private: + //! Pointer to the backend implementation that hides various types from windows.h + implementation* m_pImpl; + +public: + /*! + * Default constructor. Registers event source with name based on the application + * executable file name in the Application log. If such a registration is already + * present, it is not overridden. + */ + BOOST_LOG_API basic_simple_event_log_backend(); + /*! + * Constructor. Registers event log source with the specified parameters. + * The following named parameters are supported: + * + * \li \c target - Specifies an UNC path to the remote server which log records should be sent to. + * The local machine will be used to process log records, if not specified. + * \li \c log_name - Specifies the log in which the source should be registered. + * The result of \c get_default_log_name is used, if the parameter is not specified. + * \li \c log_source - Specifies the source name. The result of \c get_default_source_name + * is used, if the parameter is not specified. + * \li \c registration - Specifies the event source registration mode in the Windows registry. + * Can have values of the \c registration_mode enum. Default value: \c on_demand. + * + * \param args A set of named parameters. + */ +#ifndef BOOST_LOG_DOXYGEN_PASS + BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_CALL(basic_simple_event_log_backend, construct) +#else + template< typename... ArgsT > + explicit basic_simple_event_log_backend(ArgsT... const& args); +#endif + + /*! + * Destructor. Unregisters event source. The log source description is not removed from the Windows registry. + */ + BOOST_LOG_API ~basic_simple_event_log_backend(); + + /*! + * The method installs the function object that maps application severity levels to WinAPI event types + */ + BOOST_LOG_API void set_event_type_mapper(event_type_mapper_type const& mapper); + + /*! + * \returns Default log name: Application + */ + BOOST_LOG_API static string_type get_default_log_name(); + /*! + * \returns Default log source name that is based on the application executable file name and the sink name + */ + BOOST_LOG_API static string_type get_default_source_name(); + + /*! + * The method puts the formatted message to the event log + */ + BOOST_LOG_API void consume(record_view const& rec, string_type const& formatted_message); + +private: +#ifndef BOOST_LOG_DOXYGEN_PASS + //! Constructs backend implementation + template< typename ArgsT > + void construct(ArgsT const& args) + { + construct( + args[keywords::target | string_type()], + args[keywords::log_name || &basic_simple_event_log_backend::get_default_log_name], + args[keywords::log_source || &basic_simple_event_log_backend::get_default_source_name], + args[keywords::registration | event_log::on_demand]); + } + BOOST_LOG_API void construct( + string_type const& target, + string_type const& log_name, + string_type const& source_name, + event_log::registration_mode reg_mode); +#endif // BOOST_LOG_DOXYGEN_PASS +}; + +/*! + * \brief An implementation of a logging sink backend that emits events into Windows NT event log + * + * The sink uses Windows NT 5 (Windows 2000) and later event log API to emit events + * to an event log. The sink acts as an event source. Unlike \c basic_simple_event_log_backend, + * this sink backend allows users to specify the custom event message file and supports + * mapping attribute values onto several insertion strings. Although it requires considerably + * more scaffolding than the simple backend, this allows to support localizable event descriptions. + * + * Besides the file name of the module with event resources, the backend provides the following + * customizations: + * \li Remote server UNC address, log name and source name. These parameters have similar meaning + * to \c basic_simple_event_log_backend. + * \li Event type and category mappings. These are function object that allow to map attribute + * values to the according event parameters. One can use mappings in the \c event_log namespace. + * \li Event composer. This function object extracts event identifier and formats string insertions, + * that will be used by the API to compose the final event message text. + */ +template< typename CharT > +class basic_event_log_backend : + public basic_sink_backend< synchronized_feeding > +{ + //! Base type + typedef basic_sink_backend< synchronized_feeding > base_type; + //! Implementation type + struct implementation; + +public: + //! Character type + typedef CharT char_type; + //! String type + typedef std::basic_string< char_type > string_type; + //! Type of the composed insertions list + typedef std::vector< string_type > insertion_list; + + //! Mapper type for the event type + typedef boost::log::aux::light_function< event_log::event_type (record_view const&) > event_type_mapper_type; + //! Mapper type for the event category + typedef boost::log::aux::light_function< event_log::event_category (record_view const&) > event_category_mapper_type; + //! Event composer type + typedef boost::log::aux::light_function< event_log::event_id (record_view const&, insertion_list&) > event_composer_type; + +private: + //! Pointer to the backend implementation that hides various types from windows.h + implementation* m_pImpl; + +public: + /*! + * Constructor. Registers event source with name based on the application + * executable file name in the Application log. If such a registration is already + * present, it is not overridden. + */ + template< typename T > + explicit basic_event_log_backend(std::basic_string< T > const& message_file_name) + { + construct(keywords::message_file = message_file_name); + } + /*! + * Constructor. Registers event source with name based on the application + * executable file name in the Application log. If such a registration is already + * present, it is not overridden. + */ + explicit basic_event_log_backend(filesystem::path const& message_file_name) + { + construct(keywords::message_file = message_file_name); + } + /*! + * Constructor. Registers event log source with the specified parameters. + * The following named parameters are supported: + * + * \li \c message_file - Specifies the file name that contains resources that + * describe events and categories. + * \li \c target - Specifies an UNC path to the remote server to which log records should be sent to. + * The local machine will be used to process log records, if not specified. + * \li \c log_name - Specifies the log in which the source should be registered. + * The result of \c get_default_log_name is used, if the parameter is not specified. + * \li \c log_source - Specifies the source name. The result of \c get_default_source_name + * is used, if the parameter is not specified. + * \li \c registration - Specifies the event source registration mode in the Windows registry. + * Can have values of the \c registration_mode enum. Default value: \c on_demand. + * + * \param args A set of named parameters. + */ +#ifndef BOOST_LOG_DOXYGEN_PASS + BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_CALL(basic_event_log_backend, construct) +#else + template< typename... ArgsT > + explicit basic_event_log_backend(ArgsT... const& args); +#endif + + /*! + * Destructor. Unregisters event source. The log source description is not removed from the Windows registry. + */ + BOOST_LOG_API ~basic_event_log_backend(); + + /*! + * The method creates an event in the event log + * + * \param rec Log record to consume + */ + BOOST_LOG_API void consume(record_view const& rec); + + /*! + * The method installs the function object that maps application severity levels to WinAPI event types + */ + BOOST_LOG_API void set_event_type_mapper(event_type_mapper_type const& mapper); + + /*! + * The method installs the function object that extracts event category from attribute values + */ + BOOST_LOG_API void set_event_category_mapper(event_category_mapper_type const& mapper); + + /*! + * The method installs the function object that extracts event identifier from the attributes and creates + * insertion strings that will replace placeholders in the event message. + */ + BOOST_LOG_API void set_event_composer(event_composer_type const& composer); + + /*! + * \returns Default log name: Application + */ + BOOST_LOG_API static string_type get_default_log_name(); + /*! + * \returns Default log source name that is based on the application executable file name and the sink name + */ + BOOST_LOG_API static string_type get_default_source_name(); + +private: +#ifndef BOOST_LOG_DOXYGEN_PASS + //! Constructs backend implementation + template< typename ArgsT > + void construct(ArgsT const& args) + { + construct( + filesystem::path(args[keywords::message_file]), + args[keywords::target | string_type()], + args[keywords::log_name || &basic_event_log_backend::get_default_log_name], + args[keywords::log_source || &basic_event_log_backend::get_default_source_name], + args[keywords::registration | event_log::on_demand]); + } + BOOST_LOG_API void construct( + filesystem::path const& message_file_name, + string_type const& target, + string_type const& log_name, + string_type const& source_name, + event_log::registration_mode reg_mode); +#endif // BOOST_LOG_DOXYGEN_PASS +}; + +#ifdef BOOST_LOG_USE_CHAR +typedef basic_simple_event_log_backend< char > simple_event_log_backend; //!< Convenience typedef for narrow-character logging +typedef basic_event_log_backend< char > event_log_backend; //!< Convenience typedef for narrow-character logging +#endif +#ifdef BOOST_LOG_USE_WCHAR_T +typedef basic_simple_event_log_backend< wchar_t > wsimple_event_log_backend; //!< Convenience typedef for wide-character logging +typedef basic_event_log_backend< wchar_t > wevent_log_backend; //!< Convenience typedef for wide-character logging +#endif + +} // namespace sinks + +BOOST_LOG_CLOSE_NAMESPACE // namespace log + +} // namespace boost + +#include <boost/log/detail/footer.hpp> + +#endif // BOOST_LOG_WITHOUT_EVENT_LOG + +#endif // BOOST_LOG_SINKS_EVENT_LOG_BACKEND_HPP_INCLUDED_