switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Utils / Logger / SyslogUDPTarget.hh
1 // $Id$
2 //
3 // Copyright (C) 2008
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief SyslogUDPTarget public header */
30
31 #ifndef HH_SENF_Utils_Logger_SyslogUDPTarget_
32 #define HH_SENF_Utils_Logger_SyslogUDPTarget_ 1
33
34 // Custom includes
35 #include <syslog.h>
36 #include "LogFormat.hh"
37 #include "Target.hh"
38 #include <senf/Socket/Protocols/INet/INetAddressing.hh>
39 #include <senf/Socket/ClientSocketHandle.hh>
40 #include <senf/Socket/FramingPolicy.hh>
41 #include <senf/Socket/ReadWritePolicy.hh>
42 #include <senf/Socket/CommunicationPolicy.hh>
43
44 //#include "SyslogUDPTarget.mpp"
45 //-/////////////////////////////////////////////////////////////////////////////////////////////////
46
47 namespace senf {
48 namespace log {
49
50     /** \brief Log target writing UDP syslog packets
51
52         The SyslogUDPTarget will send all %log messages directly via UDP to a target host. This
53         host should have a syslog daemon or relay running. The protocol is defined in <a
54         href="http://tools.ietf.org/html/rfc3164">RFC-3164</a>.
55
56         This %log target has some important benefits:
57
58         \li It will never block. It may however lose %log messages.
59         \li It does \e not add timestamp information locally.
60
61         These are \e advantages since this makes SyslogUDPTarget a very reliable high-performance
62         logging target.
63
64         Valid facility values are from <tt>man 3 syslog</tt>:
65
66         \par ""
67            <tt>LOG_AUTHPRIV</tt>, <tt>LOG_CRON</tt>, <tt>LOG_DAEMON</tt>, <tt>LOG_FTP</tt>,
68            <tt>LOG_KERN</tt>, <tt>LOG_LOCAL0</tt>, <tt>LOG_LOCAL1</tt>, <tt>LOG_LOCAL2</tt>,
69            <tt>LOG_LOCAL3</tt>, <tt>LOG_LOCAL4</tt>, <tt>LOG_LOCAL5</tt>, <tt>LOG_LOCAL6</tt>,
70            <tt>LOG_LOCAL7</tt>, <tt>LOG_LPR</tt>, <tt>LOG_MAIL</tt>, <tt>LOG_NEWS</tt>,
71            <tt>LOG_SYSLOG</tt>, <tt>LOG_USER</tt>, <tt>LOG_UUCP</tt>
72
73         the default facility is <tt>LOG_USER</tt>
74
75         The SENF %log levels are mapped to syslog levels in the following way:
76
77         <table class="senf fixedcolumn">
78         <tr><td>senf::log::VERBOSE</td>   <td>\c LOG_DEBUG</td></tr>
79         <tr><td>senf::log::NOTICE</td>    <td>\c LOG_INFO</td></tr>
80         <tr><td>senf::log::MESSAGE</td>   <td>\c LOG_NOTICE</td></tr>
81         <tr><td>senf::log::IMPORTANT</td> <td>\c LOG_WARNING</td></tr>
82         <tr><td>senf::log::CRITICAL</td>  <td>\c LOG_CRIT</td></tr>
83         <tr><td>senf::log::FATAL</td>     <td>\c LOG_EMERG</td></tr>
84         </table>
85
86         \note Since the UDP syslog packets are limited to 1024 characters and there must be some
87             space left so a relay may optionally add a timestamp and hostname section, the %log
88             messages are split after 896 characters. Additionally the %log messages are split at each
89             newline char since non-printable characters are not allowed.
90
91         \implementation The RFC only \e recommends the exact message format. This allows us to
92             include the \c PRI part but skip the \c HEADER part (which includes the timestamp and
93             hostname) for better performance. We add a space after the \c PRI to force the syslog
94             daemon to skip the \c HEADER part.
95
96         \ingroup targets
97      */
98     class SyslogUDPTarget
99         : public Target, private detail::LogFormat
100     {
101     public:
102         //-////////////////////////////////////////////////////////////////////////
103         // Types
104
105         //-////////////////////////////////////////////////////////////////////////
106         ///\name Structors and default members
107         //\{
108
109         explicit SyslogUDPTarget(INet4Address const & target, int facility = LOG_USER);
110         explicit SyslogUDPTarget(INet4SocketAddress const & target, int facility = LOG_USER);
111         explicit SyslogUDPTarget(INet6Address const & target, int facility = LOG_USER);
112         explicit SyslogUDPTarget(INet6SocketAddress const & target, int facility = LOG_USER);
113
114         //\}
115         //-////////////////////////////////////////////////////////////////////////
116
117         using detail::LogFormat::showTime;
118         using detail::LogFormat::showStream;
119         using detail::LogFormat::showLevel;
120         using detail::LogFormat::showArea;
121         using detail::LogFormat::timeFormat;
122         using detail::LogFormat::tag;
123
124         bool syslog() const;            ///< \c true, if using syslog format, \c false otherwise
125                                         /**< When syslog format is disabled, messages are not
126                                              formated as valid syslog messages but sent using plain
127                                              UDP. */
128         void syslog(bool enabled=true); ///< Set syslog format
129
130     private:
131         void init();
132         void v_write(time_type timestamp, std::string const & stream,
133                      std::string const & area, unsigned level,
134                      std::string const & message);
135
136         void consoleFormat(std::ostream & os);
137
138         int facility_;
139         typedef senf::ClientSocketHandle< senf::MakeSocketPolicy<
140             senf::DatagramFramingPolicy,
141             senf::ConnectedCommunicationPolicy,
142             senf::WriteablePolicy>::policy > Handle;
143         Handle handle_;
144         bool syslogFormat_;
145
146     public:
147         enum LogFacility {
148             AUTHPRIV = LOG_AUTHPRIV,
149             CRON = LOG_CRON,
150             DAEMON = LOG_DAEMON,
151             FTP = LOG_FTP,
152             KERN = LOG_KERN,
153             LOCAL0 = LOG_LOCAL0,
154             LOCAL1 = LOG_LOCAL1,
155             LOCAL2 = LOG_LOCAL2,
156             LOCAL3 = LOG_LOCAL3,
157             LOCAL4 = LOG_LOCAL4,
158             LOCAL5 = LOG_LOCAL5,
159             LOCAL6 = LOG_LOCAL6,
160             LOCAL7 = LOG_LOCAL7,
161             LPR = LOG_LPR,
162             MAIL = LOG_MAIL,
163             NEWS = LOG_NEWS,
164             SYSLOG = LOG_SYSLOG,
165             USER = LOG_USER,
166             UUCP = LOG_UUCP
167         };
168
169     private:
170
171         struct RegisterConsole {
172             RegisterConsole();
173             static boost::shared_ptr<console::DirectoryNode> create(
174                 INet4SocketAddress const & target, LogFacility facility = USER);
175             static boost::shared_ptr<console::DirectoryNode> create(
176                 INet4Address const & target, LogFacility facility = USER);
177             static boost::shared_ptr<console::DirectoryNode> create(
178                 INet6SocketAddress const & target, LogFacility facility = USER);
179             static boost::shared_ptr<console::DirectoryNode> create(
180                 INet6Address const & target, LogFacility facility = USER);
181             static RegisterConsole instance;
182         };
183     };
184
185 }}
186
187 //-/////////////////////////////////////////////////////////////////////////////////////////////////
188 #include "SyslogUDPTarget.cci"
189 //#include "SyslogUDPTarget.ct"
190 //#include "SyslogUDPTarget.cti"
191 #endif
192
193 \f
194 // Local Variables:
195 // mode: c++
196 // fill-column: 100
197 // comment-column: 40
198 // c-file-style: "senf"
199 // indent-tabs-mode: nil
200 // ispell-local-dictionary: "american"
201 // compile-command: "scons -u test"
202 // End: