From: g0dil Date: Wed, 10 Dec 2008 19:34:10 +0000 (+0000) Subject: Utils/Logger: Implement direct syslog-via-UDP target X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=adcd3672d48f44103f2b4abc6417acf5d0107978;p=senf.git Utils/Logger: Implement direct syslog-via-UDP target git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1013 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Packets/DefaultBundle/RTPPacket.hh b/Packets/DefaultBundle/RTPPacket.hh index 5a2785d..62a1f48 100644 --- a/Packets/DefaultBundle/RTPPacket.hh +++ b/Packets/DefaultBundle/RTPPacket.hh @@ -29,13 +29,14 @@ #include "../../Packets/Packets.hh" #include "../../Socket/Protocols/INet/INet6Address.hh" #include "../../Socket/Protocols/INet.hh" +#include "../../Utils/Logger/SenfLog.hh" namespace senf { struct RTPPacketParser : public senf::PacketParserBase { - SENF_LOG_CLASS_AREA(); - # include SENF_PARSER() + SENF_LOG_CLASS_AREA(); +# include SENF_PARSER() SENF_PARSER_BITFIELD ( version, 2, unsigned ); //Version (RFC 3550) SENF_PARSER_BITFIELD ( padding, 1, bool ); //1 if padding behind payload SENF_PARSER_BITFIELD ( extension, 1, bool ); @@ -55,7 +56,7 @@ namespace senf { : public senf::PacketTypeBase, public senf::PacketTypeMixin { - SENF_LOG_CLASS_AREA(); + SENF_LOG_CLASS_AREA(); typedef senf::PacketTypeMixin mixin; typedef senf::ConcretePacket packet; typedef RTPPacketParser parser; diff --git a/Socket/Protocols/BSDSocketAddress.cc b/Socket/Protocols/BSDSocketAddress.cc index b3a3635..1f3e9b3 100644 --- a/Socket/Protocols/BSDSocketAddress.cc +++ b/Socket/Protocols/BSDSocketAddress.cc @@ -23,7 +23,7 @@ /** \file \brief BSDSocketAddress non-inline non-template implementation */ -//#include "BSDSocketAddress.hh" +#include "BSDSocketAddress.hh" //#include "BSDSocketAddress.ih" // Custom includes diff --git a/Socket/Protocols/UN/UNSocketProtocol.cc b/Socket/Protocols/UN/UNSocketProtocol.cc index c9db377..85266bd 100644 --- a/Socket/Protocols/UN/UNSocketProtocol.cc +++ b/Socket/Protocols/UN/UNSocketProtocol.cc @@ -31,7 +31,7 @@ #include #include #include // for SIOCINQ / SIOCOUTQ -#include +#include "../../../Utils/Logger/SenfLog.hh" #include "../../../Utils/Exception.hh" //#include "UNSocketProtocol.mpp" diff --git a/Socket/SocketProtocol.cci b/Socket/SocketProtocol.cci index 47f7a68..372ef3e 100644 --- a/Socket/SocketProtocol.cci +++ b/Socket/SocketProtocol.cci @@ -28,7 +28,6 @@ // Custom includes #include "../Utils/senfassert.hh" -#include "../Utils/Logger/SenfLog.hh" #define prefix_ inline ///////////////////////////////cci.p/////////////////////////////////////// diff --git a/Utils/Logger/IOStreamTarget.cc b/Utils/Logger/IOStreamTarget.cc index ca26958..2588059 100644 --- a/Utils/Logger/IOStreamTarget.cc +++ b/Utils/Logger/IOStreamTarget.cc @@ -39,9 +39,6 @@ /////////////////////////////////////////////////////////////////////////// // senf::log::IOStreamTarget -char const * const senf::log::IOStreamTarget::LEVELNAMES_[8] = { - "NONE", "VERBOSE", "NOTICE", "MESSAGE", "IMPORTANT", "CRITICAL", "FATAL", "DISABLED" }; - prefix_ senf::log::IOStreamTarget::IOStreamTarget(std::ostream & os) : stream_ (os), noformat_ (false), showTime_ (true), showStream_ (false), showLevel_ (true), showArea_ (true) @@ -94,7 +91,7 @@ prefix_ void senf::log::IOStreamTarget::v_write(time_type timestamp, if (showStream_) datestream_ << '[' << stream << "] "; if (showLevel_) - datestream_ << '[' << LEVELNAMES_[level] << "] "; + datestream_ << '[' << LEVELNAMES[level] << "] "; if (showArea_ && area != "senf::log::DefaultArea") datestream_ << '[' << area << "] "; diff --git a/Utils/Logger/IOStreamTarget.hh b/Utils/Logger/IOStreamTarget.hh index 11935be..aee7e3f 100644 --- a/Utils/Logger/IOStreamTarget.hh +++ b/Utils/Logger/IOStreamTarget.hh @@ -95,7 +95,6 @@ namespace log { bool showLevel_; bool showArea_; - static char const * const LEVELNAMES_[8]; }; }} diff --git a/Utils/Logger/Levels.hh b/Utils/Logger/Levels.hh index e53af86..e390f44 100644 --- a/Utils/Logger/Levels.hh +++ b/Utils/Logger/Levels.hh @@ -108,6 +108,9 @@ namespace log { struct NONE : public detail::LevelBase { static unsigned const value = 0; }; ///\} + + static char const * const LEVELNAMES[8] = { + "NONE", "VERBOSE", "NOTICE", "MESSAGE", "IMPORTANT", "CRITICAL", "FATAL", "DISABLED" }; }} diff --git a/Utils/Logger/SConscript b/Utils/Logger/SConscript index 6b3c30f..672c29b 100644 --- a/Utils/Logger/SConscript +++ b/Utils/Logger/SConscript @@ -11,9 +11,7 @@ SENFSCons.AllIncludesHH(env, [ f for f in glob.glob("*.hh") if ( f not in ('all_includes.hh','Logger.hh','SenfLog.hh') and not f.endswith('.test.hh') ) ]) sources = SENFSCons.GlobSources() -objects = SENFSCons.Objects( env, sources = sources, LIBS = [ 'Utils' ] ) - -SENFSCons.InstallIncludeFiles(env, [ 'SenfLog.hh' ]) +objects = SENFSCons.Objects( env, sources = sources, LIBS = [ 'Utils', 'Socket' ] ) SENFSCons.Doxygen(env) diff --git a/Utils/Logger/SyslogTarget.cc b/Utils/Logger/SyslogTarget.cc index 61212ad..6b175c6 100644 --- a/Utils/Logger/SyslogTarget.cc +++ b/Utils/Logger/SyslogTarget.cc @@ -32,7 +32,7 @@ #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// -int const senf::log::SyslogTarget::LEVELMAP_[8] = { +int const senf::log::SyslogTarget::LEVELMAP[8] = { 0, LOG_DEBUG, LOG_INFO, LOG_NOTICE, LOG_WARNING, LOG_CRIT, LOG_EMERG, 0 }; prefix_ void senf::log::SyslogTarget::v_write(time_type timestamp, std::string const & stream, @@ -40,9 +40,9 @@ prefix_ void senf::log::SyslogTarget::v_write(time_type timestamp, std::string c std::string const & message) { if (area != "senf::log::DefaultArea") - syslog(facility_ | LEVELMAP_[level], "[%s] %s", area.c_str(), message.c_str()); + syslog(facility_ | LEVELMAP[level], "[%s] %s", area.c_str(), message.c_str()); else - syslog(facility_ | LEVELMAP_[level], "%s", message.c_str()); + syslog(facility_ | LEVELMAP[level], "%s", message.c_str()); } ///////////////////////////////cc.e//////////////////////////////////////// diff --git a/Utils/Logger/SyslogTarget.hh b/Utils/Logger/SyslogTarget.hh index 786b58c..d11e448 100644 --- a/Utils/Logger/SyslogTarget.hh +++ b/Utils/Logger/SyslogTarget.hh @@ -89,7 +89,9 @@ namespace log { std::string const & message); int facility_; - static int const LEVELMAP_[8]; + + public: + static int const LEVELMAP[8]; }; }} diff --git a/Utils/Logger/SyslogUDPTarget.cc b/Utils/Logger/SyslogUDPTarget.cc new file mode 100644 index 0000000..331485b --- /dev/null +++ b/Utils/Logger/SyslogUDPTarget.cc @@ -0,0 +1,102 @@ +// $Id$ +// +// Copyright (C) 2008 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/** \file + \brief SyslogUDPTarget non-inline non-template implementation */ + +#include "SyslogUDPTarget.hh" +//#include "SyslogUDPTarget.ih" + +// Custom includes +#include +#include "../../Socket/Protocols/INet/ConnectedUDPSocketHandle.hh" +#include +#include + +//#include "SyslogUDPTarget.mpp" +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// + +prefix_ senf::log::SyslogUDPTarget::SyslogUDPTarget(senf::INet4Address const & target, + int facility) + : facility_ (facility), + handle_ ( senf::ConnectedUDPv4ClientSocketHandle(senf::INet4SocketAddress(target, 514u)) ) +{} + +prefix_ senf::log::SyslogUDPTarget::SyslogUDPTarget(senf::INet4SocketAddress const & target, + int facility) + : facility_ (facility), + handle_ ( senf::ConnectedUDPv4ClientSocketHandle(target) ) +{} + +prefix_ senf::log::SyslogUDPTarget::SyslogUDPTarget(senf::INet6Address const & target, + int facility) + : facility_ (facility), + handle_ ( senf::ConnectedUDPv6ClientSocketHandle(senf::INet6SocketAddress(target, 514u)) ) +{} + +prefix_ senf::log::SyslogUDPTarget::SyslogUDPTarget(senf::INet6SocketAddress const & target, + int facility) + : facility_ (facility), + handle_ ( senf::ConnectedUDPv6ClientSocketHandle(target) ) +{} + +prefix_ void senf::log::SyslogUDPTarget::v_write(time_type timestamp, std::string const & stream, + std::string const & area, unsigned level, + std::string const & message) +{ + std::stringstream prefix; + prefix << '<' << (facility_ | senf::log::SyslogTarget::LEVELMAP[level]) << "> "; + if (area != "senf::log::DefaultArea") + prefix << '[' << area << "] "; + std::string m (boost::trim_right_copy(message)); + + typedef boost::char_separator Separator; + typedef boost::tokenizer Tokenizer; + Separator separator ("\n"); + Tokenizer tokenizer (m, separator); + Tokenizer::iterator i (tokenizer.begin()); + Tokenizer::iterator const i_end (tokenizer.end()); + + std::stringstream line; + for (; i != i_end; ++i) + for (unsigned j (0); j < i->size(); j += 896) { + line << prefix.str() << std::string(*i, j, 896); + handle_.write(line.str()); + line.str(""); + } +} + +///////////////////////////////cc.e//////////////////////////////////////// +#undef prefix_ +//#include "SyslogUDPTarget.mpp" + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// comment-column: 40 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// End: diff --git a/Utils/Logger/SyslogUDPTarget.hh b/Utils/Logger/SyslogUDPTarget.hh new file mode 100644 index 0000000..a025c3e --- /dev/null +++ b/Utils/Logger/SyslogUDPTarget.hh @@ -0,0 +1,133 @@ +// $Id$ +// +// Copyright (C) 2008 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/** \file + \brief SyslogUDPTarget public header */ + +#ifndef HH_SENF_Utils_Logger_SyslogUDPTarget_ +#define HH_SENF_Utils_Logger_SyslogUDPTarget_ 1 + +// Custom includes +#include "SyslogTarget.hh" +#include "../../Socket/Protocols/INet/INetAddressing.hh" +#include "../../Socket/ClientSocketHandle.hh" +#include "../../Socket/FramingPolicy.hh" +#include "../../Socket/ReadWritePolicy.hh" +#include "../../Socket/CommunicationPolicy.hh" + +//#include "SyslogUDPTarget.mpp" +///////////////////////////////hh.p//////////////////////////////////////// + +namespace senf { +namespace log { + + /** \brief Log target writing UDP syslog packets + + The SyslogUDPTarget will send all log messages directly via UDP to a target host. This host + should have a syslog daemon or relay running. The protocol is defined in RFC-3164. + + This log target has some important benefits: + + \li It will never block. It may however lose log messages. + \li It does \e not add timestamp information locally. + + These are \e advantages since this makes SyslogUDPTarget a very reliable high-performance + logging target. + + Valid facility values are from man 3 syslog: + + \par "" + LOG_AUTHPRIV, LOG_CRON, LOG_DAEMON, LOG_FTP, + LOG_KERN, LOG_LOCAL0, LOG_LOCAL1, LOG_LOCAL2, + LOG_LOCAL3, LOG_LOCAL4, LOG_LOCAL5, LOG_LOCAL6, + LOG_LOCAL7, LOG_LPR, LOG_MAIL, LOG_NEWS, + LOG_SYSLOG, LOG_USER, LOG_UUCP + + the default facility is LOG_USER + + The SENF log levels are mapped to syslog levels in the following way: + + + + + + + + +
senf::log::VERBOSE \c LOG_DEBUG
senf::log::NOTICE \c LOG_INFO
senf::log::MESSAGE \c LOG_NOTICE
senf::log::IMPORTANT \c LOG_WARNING
senf::log::CRITICAL \c LOG_CRIT
senf::log::FATAL \c LOG_EMERG
+ + \note Since the UDP syslog packets are limited to 1024 characters and there must be some + space left so a relay may optionally add a timestamp and hostname section, the log + messages are split after 896 characters. Additionally the log messages are split at each + newline char since non-printable characters are not allowed. + */ + class SyslogUDPTarget + : public Target + { + public: + /////////////////////////////////////////////////////////////////////////// + // Types + + /////////////////////////////////////////////////////////////////////////// + ///\name Structors and default members + ///@{ + + explicit SyslogUDPTarget(senf::INet4Address const & target, int facility = LOG_USER); + explicit SyslogUDPTarget(senf::INet4SocketAddress const & target, int facility = LOG_USER); + explicit SyslogUDPTarget(senf::INet6Address const & target, int facility = LOG_USER); + explicit SyslogUDPTarget(senf::INet6SocketAddress const & target, int facility = LOG_USER); + + ///@} + /////////////////////////////////////////////////////////////////////////// + + private: + void v_write(time_type timestamp, std::string const & stream, + std::string const & area, unsigned level, + std::string const & message); + + int facility_; + typedef senf::ClientSocketHandle< senf::MakeSocketPolicy< + senf::DatagramFramingPolicy, + senf::ConnectedCommunicationPolicy, + senf::WriteablePolicy>::policy > Handle; + Handle handle_; + }; + +}} + +///////////////////////////////hh.e//////////////////////////////////////// +//#include "SyslogUDPTarget.cci" +//#include "SyslogUDPTarget.ct" +//#include "SyslogUDPTarget.cti" +#endif + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// comment-column: 40 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// End: diff --git a/Utils/Logger/SyslogUDPTarget.test.cc b/Utils/Logger/SyslogUDPTarget.test.cc new file mode 100644 index 0000000..0968f08 --- /dev/null +++ b/Utils/Logger/SyslogUDPTarget.test.cc @@ -0,0 +1,74 @@ +// $Id$ +// +// Copyright (C) 2008 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/** \file + \brief SyslogUDPTarget.test unit tests */ + +//#include "SyslogUDPTarget.test.hh" +//#include "SyslogUDPTarget.test.ih" + +// Custom includes +#include "SyslogUDPTarget.hh" +#include "../../Socket/Protocols/INet/UDPSocketHandle.hh" +#include "Logger.hh" + +#include "../../Utils/auto_unit_test.hh" +#include + +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// + +BOOST_AUTO_UNIT_TEST(syslogUDPTarget) +{ + senf::log::SyslogUDPTarget udplog ( + senf::INet4SocketAddress(senf::INet4Address::Loopback, 23444u)); + senf::UDPv4ClientSocketHandle server ( + senf::INet4SocketAddress(senf::INet4Address::Loopback, 23444u)); + + udplog.route(); + + SENF_LOG(("Test message")); + BOOST_CHECK_EQUAL( server.read(), "<13> Test message" ); + + SENF_LOG(("Test message\nLine 2")); + BOOST_CHECK_EQUAL( server.read(), "<13> Test message" ); + BOOST_CHECK_EQUAL( server.read(), "<13> Line 2" ); + + SENF_LOG(("Very long message: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")); + + BOOST_CHECK_EQUAL( server.read(), "<13> Very long message: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ); + BOOST_CHECK_EQUAL( server.read(), "<13> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ); +} + +///////////////////////////////cc.e//////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// comment-column: 40 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// End: