\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>
// 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(
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;
datestream_ << senf::ClockService::abstime(timestamp);
datestream_ << ' ';
}
+ if (!tag_.empty())
+ datestream_ << tag_ << ": ";
if (showStream_)
datestream_ << '[' << stream << "] ";
if (showLevel_)
}
}
+///////////////////////////////////////////////////////////////////////////
+
+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"
/** \file
\brief IOStreamTarget inline non-template implementation */
-//#include "IOStreamTarget.ih"
+#include "IOStreamTarget.ih"
// Custom includes
showArea_ = flag;
}
+prefix_ void senf::log::IOStreamTarget::tag(std::string const & tag)
+{
+ tag_ = tag;
+}
+
///////////////////////////////cci.e///////////////////////////////////////
#undef prefix_
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,
private:
std::ostream & stream_;
+ std::string tag_;
std::stringstream datestream_;
bool noformat_;
bool showTime_;
--- /dev/null
+// $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
+
+\f
+// 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:
// 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_
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,
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;
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);
}
}
--- /dev/null
+// $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_
+
+\f
+// 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:
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
///@}
///////////////////////////////////////////////////////////////////////////
+ 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
senf::UDPv4ClientSocketHandle server (
senf::INet4SocketAddress(senf::INet4Address::Loopback, 23444u));
+ udplog.tag("");
udplog.route();
SENF_LOG(("Test message"));
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////////////////////////////////////////