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
40namespace boost {
41
42BOOST_LOG_OPEN_NAMESPACE
43
44namespace sinks {
45
46//! Supported IP protocol versions
47enum ip_versions
48{
49 v4,
50 v6
51};
52
53namespace 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 */
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 */
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 */
150class 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
158public:
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
167private:
168 //! Pointer to the implementation
169 implementation* m_pImpl;
170
171public:
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
257private:
258#ifndef BOOST_LOG_DOXYGEN_PASS
259 //! The method creates the backend implementation
260 template< typename ArgsT >
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
280BOOST_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

source code of boost/libs/log/include/boost/log/sinks/syslog_backend.hpp