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