Skip to content
Snippets Groups Projects
Commit 8218663a authored by g0dil's avatar g0dil
Browse files

Utils/Logger: Add more consistent and flexible configuration options to...

Utils/Logger: Add more consistent and flexible configuration options to SyslogUDPTarget and IOStreamTarget
parent 02f8e4cd
No related branches found
No related tags found
No related merge requests found
......@@ -24,10 +24,12 @@
\brief IOStreamTarget non-inline non-template implementation */
#include "IOStreamTarget.hh"
//#include "IOStreamTarget.ih"
#include "IOStreamTarget.ih"
// Custom includes
#include <errno.h>
#include <locale>
#include <sstream>
#include <boost/algorithm/string/trim.hpp>
#include <boost/tokenizer.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
......@@ -40,8 +42,8 @@
// senf::log::IOStreamTarget
prefix_ senf::log::IOStreamTarget::IOStreamTarget(std::ostream & os)
: stream_ (os), noformat_ (false), showTime_ (true), showStream_ (false), showLevel_ (true),
showArea_ (true)
: stream_ (os), tag_ (detail::getDefaultTag()), noformat_ (false), showTime_ (true),
showStream_ (false), showLevel_ (true), showArea_ (true)
{
std::locale const & loc (datestream_.getloc());
datestream_.imbue( std::locale(
......@@ -69,9 +71,11 @@ prefix_ void senf::log::IOStreamTarget::v_write(time_type timestamp,
std::string const & area, unsigned level,
std::string const & message)
{
std::string m (boost::trim_right_copy(message));
std::string m (message);
boost::trim_right(m);
detail::quoteNonPrintable(m);
if (!showTime_ && !showStream_ && !showLevel_ && !showArea_)
if (tag_.empty() && !showTime_ && !showStream_ && !showLevel_ && !showArea_)
stream_ << m << std::endl;
else {
typedef boost::char_separator<char> Separator;
......@@ -88,6 +92,8 @@ prefix_ void senf::log::IOStreamTarget::v_write(time_type timestamp,
datestream_ << senf::ClockService::abstime(timestamp);
datestream_ << ' ';
}
if (!tag_.empty())
datestream_ << tag_ << ": ";
if (showStream_)
datestream_ << '[' << stream << "] ";
if (showLevel_)
......@@ -102,6 +108,22 @@ prefix_ void senf::log::IOStreamTarget::v_write(time_type timestamp,
}
}
///////////////////////////////////////////////////////////////////////////
prefix_ void senf::log::detail::quoteNonPrintable(std::string & s)
{
for (std::string::iterator i (s.begin()); i != s.end(); ++i)
if (*i < ' ' && *i != '\n')
*i = ' ';
}
prefix_ std::string senf::log::detail::getDefaultTag()
{
std::stringstream ss;
ss << ::program_invocation_short_name << '[' << ::getpid() << ']';
return ss.str();
}
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
//#include "IOStreamTarget.mpp"
......
......@@ -23,7 +23,7 @@
/** \file
\brief IOStreamTarget inline non-template implementation */
//#include "IOStreamTarget.ih"
#include "IOStreamTarget.ih"
// Custom includes
......@@ -50,6 +50,11 @@ prefix_ void senf::log::IOStreamTarget::showArea(bool flag)
showArea_ = flag;
}
prefix_ void senf::log::IOStreamTarget::tag(std::string const & tag)
{
tag_ = tag;
}
///////////////////////////////cci.e///////////////////////////////////////
#undef prefix_
......
......@@ -79,6 +79,8 @@ namespace log {
By default, the date-time will be written in extended
ISO format.
\param[in] format Date/Time format string */
void tag(std::string const & tag);
protected:
void v_write(time_type timestamp, std::string const & stream,
......@@ -88,6 +90,7 @@ namespace log {
private:
std::ostream & stream_;
std::string tag_;
std::stringstream datestream_;
bool noformat_;
bool showTime_;
......
// $Id$
//
// Copyright (C) 2008
// Fraunhofer Institute for Open Communication Systems (FOKUS)
// Competence Center NETwork research (NET), St. Augustin, GERMANY
// Stefan Bund <g0dil@berlios.de>
//
// 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 IOStreamTarget internal header */
#ifndef IH_SENF_Utils_Logger_IOStreamTarget_
#define IH_SENF_Utils_Logger_IOStreamTarget_ 1
// Custom includes
///////////////////////////////ih.p////////////////////////////////////////
namespace senf {
namespace log {
namespace detail {
void quoteNonPrintable(std::string & s);
std::string getDefaultTag();
}}}
///////////////////////////////ih.e////////////////////////////////////////
#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:
......@@ -28,9 +28,10 @@
// Custom includes
#include <sstream>
#include "../../Socket/Protocols/INet/ConnectedUDPSocketHandle.hh"
#include <boost/algorithm/string/trim.hpp>
#include <boost/tokenizer.hpp>
#include "../../Socket/Protocols/INet/ConnectedUDPSocketHandle.hh"
#include "IOStreamTarget.hh"
//#include "SyslogUDPTarget.mpp"
#define prefix_
......@@ -38,26 +39,30 @@
prefix_ senf::log::SyslogUDPTarget::SyslogUDPTarget(senf::INet4Address const & target,
int facility)
: facility_ (facility),
handle_ ( senf::ConnectedUDPv4ClientSocketHandle(senf::INet4SocketAddress(target, 514u)) )
: facility_ (facility), tag_ (detail::getDefaultTag()),
handle_ ( senf::ConnectedUDPv4ClientSocketHandle(senf::INet4SocketAddress(target, 514u)) ),
showStream_ (false), showLevel_ (false), showArea_ (true)
{}
prefix_ senf::log::SyslogUDPTarget::SyslogUDPTarget(senf::INet4SocketAddress const & target,
int facility)
: facility_ (facility),
handle_ ( senf::ConnectedUDPv4ClientSocketHandle(target) )
: facility_ (facility), tag_ (detail::getDefaultTag()),
handle_ ( senf::ConnectedUDPv4ClientSocketHandle(target) ),
showStream_ (false), showLevel_ (false), showArea_ (true)
{}
prefix_ senf::log::SyslogUDPTarget::SyslogUDPTarget(senf::INet6Address const & target,
int facility)
: facility_ (facility),
handle_ ( senf::ConnectedUDPv6ClientSocketHandle(senf::INet6SocketAddress(target, 514u)) )
: facility_ (facility), tag_ (detail::getDefaultTag()),
handle_ ( senf::ConnectedUDPv6ClientSocketHandle(senf::INet6SocketAddress(target, 514u)) ),
showStream_ (false), showLevel_ (false), showArea_ (true)
{}
prefix_ senf::log::SyslogUDPTarget::SyslogUDPTarget(senf::INet6SocketAddress const & target,
int facility)
: facility_ (facility),
handle_ ( senf::ConnectedUDPv6ClientSocketHandle(target) )
: facility_ (facility), tag_ (detail::getDefaultTag()),
handle_ ( senf::ConnectedUDPv6ClientSocketHandle(target) ),
showStream_ (false), showLevel_ (false), showArea_ (true)
{}
prefix_ void senf::log::SyslogUDPTarget::v_write(time_type timestamp, std::string const & stream,
......@@ -65,10 +70,19 @@ prefix_ void senf::log::SyslogUDPTarget::v_write(time_type timestamp, std::strin
std::string const & message)
{
std::stringstream prefix;
prefix << '<' << (facility_ | senf::log::SyslogTarget::LEVELMAP[level]) << "> ";
if (area != "senf::log::DefaultArea")
if (!tag_.empty())
prefix << tag_ << ": ";
if (showStream_)
prefix << '[' << stream << "] ";
if (showLevel_)
prefix << '[' << LEVELNAMES[level] << "] ";
if (showArea_ && area != "senf::log::DefaultArea")
prefix << '[' << area << "] ";
std::string m (boost::trim_right_copy(message));
std::string m (message);
boost::trim_right(m);
detail::quoteNonPrintable(m);
typedef boost::char_separator<char> Separator;
typedef boost::tokenizer<Separator> Tokenizer;
......@@ -77,12 +91,13 @@ prefix_ void senf::log::SyslogUDPTarget::v_write(time_type timestamp, std::strin
Tokenizer::iterator i (tokenizer.begin());
Tokenizer::iterator const i_end (tokenizer.end());
std::stringstream line;
std::string line;
unsigned sz (896-prefix.str().size());
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("");
for (unsigned j (0); j < i->size(); j += sz) {
line = prefix.str();
line += std::string(*i, j, sz);
handle_.write(line);
}
}
......
// $Id$
//
// Copyright (C) 2008
// Fraunhofer Institute for Open Communication Systems (FOKUS)
// Competence Center NETwork research (NET), St. Augustin, GERMANY
// Stefan Bund <g0dil@berlios.de>
//
// 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 inline non-template implementation */
//#include "SyslogUDPTarget.ih"
// Custom includes
#define prefix_ inline
///////////////////////////////cci.p///////////////////////////////////////
prefix_ void senf::log::SyslogUDPTarget::showStream(bool flag)
{
showStream_ = flag;
}
prefix_ void senf::log::SyslogUDPTarget::showLevel(bool flag)
{
showLevel_ = flag;
}
prefix_ void senf::log::SyslogUDPTarget::showArea(bool flag)
{
showArea_ = flag;
}
prefix_ void senf::log::SyslogUDPTarget::tag(std::string const & tag)
{
tag_ = tag;
}
///////////////////////////////cci.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:
......@@ -80,6 +80,11 @@ namespace log {
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.
\implementation The RFC only \e recommends the exact message format. This allows us to
include the \c PRI part but skip the \c HEADER part (which includes the timestamp and
hostname) for better performance. We add a space after the \c PRI to force the syslog
daemon to skip the \c HEADER part.
*/
class SyslogUDPTarget
: public Target
......@@ -100,23 +105,33 @@ namespace log {
///@}
///////////////////////////////////////////////////////////////////////////
void showStream(bool flag = true);
void showLevel(bool flag = true);
void showArea(bool flag = true);
void tag(std::string const & tag);
private:
void v_write(time_type timestamp, std::string const & stream,
std::string const & area, unsigned level,
std::string const & message);
int facility_;
std::string tag_;
typedef senf::ClientSocketHandle< senf::MakeSocketPolicy<
senf::DatagramFramingPolicy,
senf::ConnectedCommunicationPolicy,
senf::WriteablePolicy>::policy > Handle;
Handle handle_;
bool showStream_;
bool showLevel_;
bool showArea_;
};
}}
///////////////////////////////hh.e////////////////////////////////////////
//#include "SyslogUDPTarget.cci"
#include "SyslogUDPTarget.cci"
//#include "SyslogUDPTarget.ct"
//#include "SyslogUDPTarget.cti"
#endif
......
......@@ -44,6 +44,7 @@ BOOST_AUTO_UNIT_TEST(syslogUDPTarget)
senf::UDPv4ClientSocketHandle server (
senf::INet4SocketAddress(senf::INet4Address::Loopback, 23444u));
udplog.tag("");
udplog.route();
SENF_LOG(("Test message"));
......@@ -55,8 +56,8 @@ BOOST_AUTO_UNIT_TEST(syslogUDPTarget)
SENF_LOG(("Very long message: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
BOOST_CHECK_EQUAL( server.read(), "<13> Very long message: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" );
BOOST_CHECK_EQUAL( server.read(), "<13> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" );
BOOST_CHECK_EQUAL( server.read(), "<13> Very long message: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" );
BOOST_CHECK_EQUAL( server.read(), "<13> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" );
}
///////////////////////////////cc.e////////////////////////////////////////
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment