syslog_backend.hpp 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  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 syslog_backend.hpp
  9. * \author Andrey Semashev
  10. * \date 08.01.2008
  11. *
  12. * The header contains implementation of a Syslog sink backend along with its setup facilities.
  13. */
  14. #ifndef BOOST_LOG_SINKS_SYSLOG_BACKEND_HPP_INCLUDED_
  15. #define BOOST_LOG_SINKS_SYSLOG_BACKEND_HPP_INCLUDED_
  16. #include <boost/log/detail/config.hpp>
  17. #ifdef BOOST_HAS_PRAGMA_ONCE
  18. #pragma once
  19. #endif
  20. #ifndef BOOST_LOG_WITHOUT_SYSLOG
  21. #include <string>
  22. #include <boost/log/detail/asio_fwd.hpp>
  23. #include <boost/log/detail/light_function.hpp>
  24. #include <boost/log/detail/parameter_tools.hpp>
  25. #include <boost/log/sinks/basic_sink_backend.hpp>
  26. #include <boost/log/sinks/syslog_constants.hpp>
  27. #include <boost/log/sinks/attribute_mapping.hpp>
  28. #include <boost/log/attributes/attribute_value_set.hpp>
  29. #include <boost/log/keywords/facility.hpp>
  30. #include <boost/log/keywords/use_impl.hpp>
  31. #include <boost/log/keywords/ident.hpp>
  32. #include <boost/log/keywords/ip_version.hpp>
  33. #include <boost/log/detail/header.hpp>
  34. namespace boost {
  35. BOOST_LOG_OPEN_NAMESPACE
  36. namespace sinks {
  37. //! Supported IP protocol versions
  38. enum ip_versions
  39. {
  40. v4,
  41. v6
  42. };
  43. namespace syslog {
  44. //! The enumeration defined the possible implementation types for the syslog backend
  45. enum impl_types
  46. {
  47. #ifdef BOOST_LOG_USE_NATIVE_SYSLOG
  48. native = 0 //!< Use native syslog API
  49. #ifndef BOOST_LOG_NO_ASIO
  50. ,
  51. #endif
  52. #endif
  53. #ifndef BOOST_LOG_NO_ASIO
  54. udp_socket_based = 1 //!< Use UDP sockets, according to RFC3164
  55. #endif
  56. };
  57. /*!
  58. * \brief Straightforward severity level mapping
  59. *
  60. * This type of mapping assumes that attribute with a particular name always
  61. * provides values that map directly onto the Syslog levels. The mapping
  62. * simply returns the extracted attribute value converted to the Syslog severity level.
  63. */
  64. template< typename AttributeValueT = int >
  65. class direct_severity_mapping :
  66. public basic_direct_mapping< level, AttributeValueT >
  67. {
  68. //! Base type
  69. typedef basic_direct_mapping< level, AttributeValueT > base_type;
  70. public:
  71. /*!
  72. * Constructor
  73. *
  74. * \param name Attribute name
  75. */
  76. explicit direct_severity_mapping(attribute_name const& name) :
  77. base_type(name, info)
  78. {
  79. }
  80. };
  81. /*!
  82. * \brief Customizable severity level mapping
  83. *
  84. * The class allows to setup a custom mapping between an attribute and Syslog severity levels.
  85. * The mapping should be initialized similarly to the standard \c map container, by using
  86. * indexing operator and assignment.
  87. */
  88. template< typename AttributeValueT = int >
  89. class custom_severity_mapping :
  90. public basic_custom_mapping< level, AttributeValueT >
  91. {
  92. //! Base type
  93. typedef basic_custom_mapping< level, AttributeValueT > base_type;
  94. public:
  95. /*!
  96. * Constructor
  97. *
  98. * \param name Attribute name
  99. */
  100. explicit custom_severity_mapping(attribute_name const& name) :
  101. base_type(name, info)
  102. {
  103. }
  104. };
  105. } // namespace syslog
  106. /*!
  107. * \brief An implementation of a syslog sink backend
  108. *
  109. * The backend provides support for the syslog protocol, defined in RFC3164.
  110. * The backend sends log records to a remote host via UDP. The host name can
  111. * be specified by calling the \c set_target_address method. By default log
  112. * records will be sent to localhost:514. The local address can be specified
  113. * as well, by calling the \c set_local_address method. By default syslog
  114. * packets will be sent from any local address available.
  115. *
  116. * It is safe to create several sink backends with the same local addresses -
  117. * the backends within the process will share the same socket. The same applies
  118. * to different processes that use the syslog backends to send records from
  119. * the same socket. However, it is not guaranteed to work if some third party
  120. * facility is using the socket.
  121. *
  122. * On systems with native syslog implementation it may be preferable to utilize
  123. * the POSIX syslog API instead of direct socket management in order to bypass
  124. * possible security limitations that may be in action. To do so one has to pass
  125. * the <tt>use_impl = native</tt> to the backend constructor. Note, however,
  126. * that in that case you will only have one chance to specify syslog facility and
  127. * process identification string - on the first native syslog backend construction.
  128. * Other native syslog backends will ignore these parameters.
  129. * Obviously, the \c set_local_address and \c set_target_address
  130. * methods have no effect for native backends. Using <tt>use_impl = native</tt>
  131. * on platforms with no native support for POSIX syslog API will have no effect.
  132. */
  133. class syslog_backend :
  134. public basic_formatted_sink_backend< char >
  135. {
  136. //! Base type
  137. typedef basic_formatted_sink_backend< char > base_type;
  138. //! Implementation type
  139. struct implementation;
  140. public:
  141. //! Character type
  142. typedef base_type::char_type char_type;
  143. //! String type that is used to pass message test
  144. typedef base_type::string_type string_type;
  145. //! Syslog severity level mapper type
  146. typedef boost::log::aux::light_function< syslog::level (record_view const&) > severity_mapper_type;
  147. private:
  148. //! Pointer to the implementation
  149. implementation* m_pImpl;
  150. public:
  151. /*!
  152. * Constructor. Creates a UDP socket-based backend with <tt>syslog::user</tt> facility code.
  153. * IPv4 protocol will be used.
  154. */
  155. BOOST_LOG_API syslog_backend();
  156. /*!
  157. * Constructor. Creates a sink backend with the specified named parameters.
  158. * The following named parameters are supported:
  159. *
  160. * \li \c facility - Specifies the facility code. If not specified, <tt>syslog::user</tt> will be used.
  161. * \li \c use_impl - Specifies the backend implementation. Can be one of:
  162. * \li \c native - Use the native syslog API, if available. If no native API
  163. * is available, it is equivalent to \c udp_socket_based.
  164. * \li \c udp_socket_based - Use the UDP socket-based implementation, conforming to
  165. * RFC3164 protocol specification. This is the default.
  166. * \li \c ip_version - Specifies IP protocol version to use, in case if socket-based implementation
  167. * is used. Can be either \c v4 (the default one) or \c v6.
  168. * \li \c ident - Process identification string. This parameter is only supported by native syslog implementation.
  169. */
  170. #ifndef BOOST_LOG_DOXYGEN_PASS
  171. BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_CALL(syslog_backend, construct)
  172. #else
  173. template< typename... ArgsT >
  174. explicit syslog_backend(ArgsT... const& args);
  175. #endif
  176. /*!
  177. * Destructor
  178. */
  179. BOOST_LOG_API ~syslog_backend();
  180. /*!
  181. * The method installs the function object that maps application severity levels to syslog levels
  182. */
  183. BOOST_LOG_API void set_severity_mapper(severity_mapper_type const& mapper);
  184. #if !defined(BOOST_LOG_NO_ASIO)
  185. /*!
  186. * The method sets the local host name which log records will be sent from. The host name
  187. * is resolved to obtain the final IP address.
  188. *
  189. * \note Does not have effect if the backend was constructed to use native syslog API
  190. *
  191. * \param addr The local address
  192. * \param port The local port number
  193. */
  194. BOOST_LOG_API void set_local_address(std::string const& addr, unsigned short port = 514);
  195. /*!
  196. * The method sets the local address which log records will be sent from.
  197. *
  198. * \note Does not have effect if the backend was constructed to use native syslog API
  199. *
  200. * \param addr The local address
  201. * \param port The local port number
  202. */
  203. BOOST_LOG_API void set_local_address(boost::asio::ip::address const& addr, unsigned short port = 514);
  204. /*!
  205. * The method sets the remote host name where log records will be sent to. The host name
  206. * is resolved to obtain the final IP address.
  207. *
  208. * \note Does not have effect if the backend was constructed to use native syslog API
  209. *
  210. * \param addr The remote host address
  211. * \param port The port number on the remote host
  212. */
  213. BOOST_LOG_API void set_target_address(std::string const& addr, unsigned short port = 514);
  214. /*!
  215. * The method sets the address of the remote host where log records will be sent to.
  216. *
  217. * \note Does not have effect if the backend was constructed to use native syslog API
  218. *
  219. * \param addr The remote host address
  220. * \param port The port number on the remote host
  221. */
  222. BOOST_LOG_API void set_target_address(boost::asio::ip::address const& addr, unsigned short port = 514);
  223. #endif // !defined(BOOST_LOG_NO_ASIO)
  224. /*!
  225. * The method passes the formatted message to the syslog API or sends to a syslog server
  226. */
  227. BOOST_LOG_API void consume(record_view const& rec, string_type const& formatted_message);
  228. private:
  229. #ifndef BOOST_LOG_DOXYGEN_PASS
  230. //! The method creates the backend implementation
  231. template< typename ArgsT >
  232. void construct(ArgsT const& args)
  233. {
  234. construct(
  235. args[keywords::facility | syslog::user],
  236. #if !defined(BOOST_LOG_NO_ASIO)
  237. args[keywords::use_impl | syslog::udp_socket_based],
  238. #else
  239. args[keywords::use_impl | syslog::native],
  240. #endif
  241. args[keywords::ip_version | v4],
  242. args[keywords::ident | std::string()]);
  243. }
  244. BOOST_LOG_API void construct(
  245. syslog::facility facility, syslog::impl_types use_impl, ip_versions ip_version, std::string const& ident);
  246. #endif // BOOST_LOG_DOXYGEN_PASS
  247. };
  248. } // namespace sinks
  249. BOOST_LOG_CLOSE_NAMESPACE // namespace log
  250. } // namespace boost
  251. #include <boost/log/detail/footer.hpp>
  252. #endif // BOOST_LOG_WITHOUT_SYSLOG
  253. #endif // BOOST_LOG_SINKS_SYSLOG_BACKEND_HPP_INCLUDED_