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