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