From: g0dil Date: Fri, 6 Feb 2009 00:03:23 +0000 (+0000) Subject: Utils/Logger: Add console directory to target X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=41eff772147b6df1961d9029ba6815b553b4f81d;p=senf.git Utils/Logger: Add console directory to target git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1100 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Socket/ServerSocketHandle.cti b/Socket/ServerSocketHandle.cti index 4044b1e..132625d 100644 --- a/Socket/ServerSocketHandle.cti +++ b/Socket/ServerSocketHandle.cti @@ -114,8 +114,8 @@ template prefix_ typename senf::ServerSocketHandle::ClientHandle senf::ServerSocketHandle::acceptfrom(Address & addr) { - return ClienttHandle(this->protocol().clone(), - SPolicy::CommunicationPolicy::accept(*this,addr)); + return ClientHandle(this->body().clone( + SPolicy::CommunicationPolicy::accept(*this,addr), false)); } /////////////////////////////////////////////////////////////////////////// diff --git a/Utils/Console/Parse.test.cc b/Utils/Console/Parse.test.cc index 5a2295f..4570fb0 100644 --- a/Utils/Console/Parse.test.cc +++ b/Utils/Console/Parse.test.cc @@ -227,28 +227,28 @@ BOOST_AUTO_UNIT_TEST(commandParser) ++ args; BOOST_REQUIRE( args != info.arguments().end() ); - BOOST_REQUIRE_EQUAL( args->size(), 1 ); + BOOST_REQUIRE_EQUAL( args->size(), 1u ); BOOST_CHECK_EQUAL( args->begin()->value(), tokens[1] ); ++ args; BOOST_REQUIRE( args != info.arguments().end() ); - BOOST_REQUIRE_EQUAL( args->size(), 1 ); + BOOST_REQUIRE_EQUAL( args->size(), 1u ); BOOST_CHECK_EQUAL( args->begin()->value(), tokens[2] ); ++ args; BOOST_REQUIRE( args != info.arguments().end() ); - BOOST_REQUIRE_EQUAL( args->size(), 8 ); + BOOST_REQUIRE_EQUAL( args->size(), 8u ); for (unsigned i (0); i<8; ++i) BOOST_CHECK_EQUAL( args->begin()[i].value(), tokens[4+i] ); ++ args; BOOST_REQUIRE( args != info.arguments().end() ); - BOOST_REQUIRE_EQUAL( args->size(), 1 ); + BOOST_REQUIRE_EQUAL( args->size(), 1u ); BOOST_CHECK_EQUAL( args->begin()->value(), tokens[13] ); ++ args; BOOST_REQUIRE( args != info.arguments().end() ); - BOOST_REQUIRE_EQUAL( args->size(), 1 ); + BOOST_REQUIRE_EQUAL( args->size(), 1u ); BOOST_CHECK_EQUAL( args->begin()->value(), tokens[14] ); ++ args; diff --git a/Utils/Console/Server.cc b/Utils/Console/Server.cc index 719f527..41475c2 100644 --- a/Utils/Console/Server.cc +++ b/Utils/Console/Server.cc @@ -106,12 +106,12 @@ prefix_ void senf::console::Server::newClient(int event) ServerHandle::ClientHandle client (handle_.accept()); boost::intrusive_ptr p (new Client(*this, client)); clients_.insert( p ); - SENF_LOG(( "Registered new client " << p.get() )); + SENF_LOG(( "Registered new client " << client.peer() )); } prefix_ void senf::console::Server::removeClient(Client & client) { - SENF_LOG(( "Disposing client " << & client )); + SENF_LOG(( "Disposing client " << client.handle().peer() )); // THIS DELETES THE CLIENT INSTANCE !! clients_.erase(boost::intrusive_ptr(&client)); } @@ -224,8 +224,9 @@ senf::console::detail::NoninteractiveClientReader::newData(int event) // senf::console::Client prefix_ senf::console::Client::Client(Server & server, ClientHandle handle) - : out_t(boost::ref(*this)), senf::log::IOStreamTarget(out_t::member), server_ (server), - handle_ (handle), + : out_t(boost::ref(*this)), + senf::log::IOStreamTarget("client-" + senf::str(handle.peer()), out_t::member), + server_ (server), handle_ (handle), readevent_ ("senf::console::Client::interactive_check", boost::bind(&Client::setNoninteractive,this), handle, scheduler::FdEvent::EV_READ, false), @@ -322,33 +323,6 @@ prefix_ void senf::console::Client::v_write(senf::log::time_type timestamp, reader_->enablePrompt(); } -prefix_ std::ostream & senf::console::operator<<(std::ostream & os, Client const & client) -{ - typedef ClientSocketHandle< MakeSocketPolicy< - INet4AddressingPolicy,ConnectedCommunicationPolicy>::policy > V4Socket; - typedef ClientSocketHandle< MakeSocketPolicy< - INet6AddressingPolicy,ConnectedCommunicationPolicy>::policy > V6Socket; - - try { - if (check_socket_cast(client.handle())) - os << dynamic_socket_cast(client.handle()).peer(); - else if (check_socket_cast(client.handle())) - os << dynamic_socket_cast(client.handle()).peer(); - else - os << static_cast(&client); - } - catch (SystemException &) { - os << "0.0.0.0:0"; - } - - return os; -} - -prefix_ std::ostream & senf::console::operator<<(std::ostream & os, Client * client) -{ - return os << *client; -} - /////////////////////////////////////////////////////////////////////////// // senf::console::Client::SysBacktrace diff --git a/Utils/Console/Server.ih b/Utils/Console/Server.ih index d7b73e7..5e110fa 100644 --- a/Utils/Console/Server.ih +++ b/Utils/Console/Server.ih @@ -88,7 +88,7 @@ namespace detail { typedef senf::ServerSocketHandle< senf::MakeSocketPolicy< senf::TCPv4SocketProtocol::Policy, - senf::UnspecifiedAddressingPolicy>::policy > ServerHandle; + senf::BSDAddressingPolicy>::policy > ServerHandle; /** \brief Internal: Generic client interface diff --git a/Utils/Logger/ConsoleTarget.cci b/Utils/Logger/ConsoleTarget.cci index d1ff8e5..5fc13c1 100644 --- a/Utils/Logger/ConsoleTarget.cci +++ b/Utils/Logger/ConsoleTarget.cci @@ -40,7 +40,7 @@ prefix_ senf::log::ConsoleTarget & senf::log::ConsoleTarget::instance() } prefix_ senf::log::ConsoleTarget::ConsoleTarget() - : IOStreamTarget(std::cout) + : IOStreamTarget("console", std::cout) {} ///////////////////////////////cci.e/////////////////////////////////////// diff --git a/Utils/Logger/FileTarget.cc b/Utils/Logger/FileTarget.cc index 0467573..2baff33 100644 --- a/Utils/Logger/FileTarget.cc +++ b/Utils/Logger/FileTarget.cc @@ -33,7 +33,8 @@ ///////////////////////////////cc.p//////////////////////////////////////// prefix_ senf::log::FileTarget::FileTarget(std::string file) - : ofstream_t(file.c_str(), std::ofstream::app), IOStreamTarget(ofstream_t::member), file_(file) + : ofstream_t(file.c_str(), std::ofstream::app), IOStreamTarget(file, ofstream_t::member), + file_(file) {} prefix_ void senf::log::FileTarget::reopen() diff --git a/Utils/Logger/IOStreamTarget.cci b/Utils/Logger/IOStreamTarget.cci index 8e55b74..e4f7968 100644 --- a/Utils/Logger/IOStreamTarget.cci +++ b/Utils/Logger/IOStreamTarget.cci @@ -30,8 +30,8 @@ #define prefix_ inline ///////////////////////////////cci.p/////////////////////////////////////// -prefix_ senf::log::IOStreamTarget::IOStreamTarget(std::ostream & os) - : stream_ (os) +prefix_ senf::log::IOStreamTarget::IOStreamTarget(std::string const & name, std::ostream & os) + : Target(name), stream_ (os) {} ///////////////////////////////cci.e/////////////////////////////////////// diff --git a/Utils/Logger/IOStreamTarget.hh b/Utils/Logger/IOStreamTarget.hh index bb1c0d5..229ab63 100644 --- a/Utils/Logger/IOStreamTarget.hh +++ b/Utils/Logger/IOStreamTarget.hh @@ -57,7 +57,7 @@ namespace log { ///\name Structors and default members ///@{ - explicit IOStreamTarget(std::ostream & os); + IOStreamTarget(std::string const & name, std::ostream & os); ///@} /////////////////////////////////////////////////////////////////////////// diff --git a/Utils/Logger/StringTarget.cti b/Utils/Logger/StringTarget.cti index 1157206..a1e6a37 100644 --- a/Utils/Logger/StringTarget.cti +++ b/Utils/Logger/StringTarget.cti @@ -34,7 +34,7 @@ // senf::log::StringTarget prefix_ senf::log::StringTarget::StringTarget() - : IOStreamTarget(stream_base::member) + : IOStreamTarget("membuffer", stream_base::member) {} prefix_ std::string senf::log::StringTarget::str() diff --git a/Utils/Logger/SyslogTarget.cci b/Utils/Logger/SyslogTarget.cci index fe71ce3..f9c6271 100644 --- a/Utils/Logger/SyslogTarget.cci +++ b/Utils/Logger/SyslogTarget.cci @@ -31,7 +31,7 @@ ///////////////////////////////cci.p/////////////////////////////////////// prefix_ senf::log::SyslogTarget::SyslogTarget(int facility) - : facility_ (facility) + : Target("syslog"), facility_ (facility) {} ///////////////////////////////cci.e/////////////////////////////////////// diff --git a/Utils/Logger/SyslogUDPTarget.cc b/Utils/Logger/SyslogUDPTarget.cc index 0538fe0..03a055f 100644 --- a/Utils/Logger/SyslogUDPTarget.cc +++ b/Utils/Logger/SyslogUDPTarget.cc @@ -44,6 +44,9 @@ prefix_ void senf::log::SyslogUDPTarget::v_write(time_type timestamp, std::strin detail::quoteNonPrintable(m); std::stringstream prfstream; + // The space after the '>' is there on purpose: It ensures, that the prefix (which may be empty) + // or message will not inadvertently be interpreted as date or hostname by a receiving syslog + // daemon or proxy prfstream << '<' << (facility_ | senf::log::SyslogTarget::LEVELMAP[level]) << "> " << prefix(timestamp, stream, area, level); std::string const & prf (prfstream.str()); diff --git a/Utils/Logger/SyslogUDPTarget.cci b/Utils/Logger/SyslogUDPTarget.cci index 4078e3d..52a5055 100644 --- a/Utils/Logger/SyslogUDPTarget.cci +++ b/Utils/Logger/SyslogUDPTarget.cci @@ -27,31 +27,32 @@ // Custom includes #include "../../Socket/Protocols/INet/ConnectedUDPSocketHandle.hh" +#include "../String.hh" #define prefix_ inline ///////////////////////////////cci.p/////////////////////////////////////// prefix_ senf::log::SyslogUDPTarget::SyslogUDPTarget(senf::INet4Address const & target, int facility) - : facility_ (facility), + : Target("udp-" + senf::str(target)), facility_ (facility), handle_ ( senf::ConnectedUDPv4ClientSocketHandle(senf::INet4SocketAddress(target, 514u)) ) {} prefix_ senf::log::SyslogUDPTarget::SyslogUDPTarget(senf::INet4SocketAddress const & target, int facility) - : facility_ (facility), + : Target("udp-" + senf::str(target)), facility_ (facility), handle_ ( senf::ConnectedUDPv4ClientSocketHandle(target) ) {} prefix_ senf::log::SyslogUDPTarget::SyslogUDPTarget(senf::INet6Address const & target, int facility) - : facility_ (facility), + : Target("udp-" + senf::str(target)), facility_ (facility), handle_ ( senf::ConnectedUDPv6ClientSocketHandle(senf::INet6SocketAddress(target, 514u)) ) {} prefix_ senf::log::SyslogUDPTarget::SyslogUDPTarget(senf::INet6SocketAddress const & target, int facility) - : facility_ (facility), + : Target("udp-" + senf::str(target)), facility_ (facility), handle_ ( senf::ConnectedUDPv6ClientSocketHandle(target) ) {} diff --git a/Utils/Logger/Target.cc b/Utils/Logger/Target.cc index 068631c..22d5823 100644 --- a/Utils/Logger/Target.cc +++ b/Utils/Logger/Target.cc @@ -28,7 +28,11 @@ // Custom includes #include +#include #include "ConsoleTarget.hh" +#include "../Console/Console.hh" +#include "../Console/Sysdir.hh" +#include "../membind.hh" //#include "Target.mpp" #define prefix_ @@ -37,9 +41,106 @@ /////////////////////////////////////////////////////////////////////////// // senf::log::Target -prefix_ senf::log::Target::Target() +namespace senf { +namespace log { + + SENF_CONSOLE_REGISTER_ENUM_MEMBER( Target, action_t, (ACCEPT)(REJECT) ); + +}} + +namespace { +namespace local { + + enum Level { + VERBOSE = senf::log::VERBOSE::value, + NOTICE = senf::log::NOTICE::value, + MESSAGE = senf::log::MESSAGE::value, + IMPORTANT = senf::log::IMPORTANT::value, + CRITICAL = senf::log::CRITICAL::value, + FATAL = senf::log::FATAL::value + }; + SENF_CONSOLE_REGISTER_ENUM( Level, + (VERBOSE)(NOTICE)(MESSAGE)(IMPORTANT)(CRITICAL)(FATAL) ); + +}} + +prefix_ senf::log::Target::Target(std::string const & name) { - detail::TargetRegistry::instance().registerTarget(this); + namespace kw = senf::console::kw; + + detail::TargetRegistry::instance().registerTarget(this, name); + consoleDir_().add("list", senf::membind(&Target::consoleList, this)) + .doc("Show routing table\n" + "\n" + "Columns:\n" + " # rule index\n" + " STREAM stream to match, empty to match all streams\n" + " AREA area to match, empty to match all targets\n" + " LEVEL match messages with level above this. Log levels in increasing order\n" + " are:\n" + " verbose, notice, message, important, critical, fatal\n" + " ACTION action to take: accept or reject"); + consoleDir_().add("route", + boost::function( + senf::membind( + static_cast(&Target::route), + this))) + .arg("stream", "stream to match or empty to match any stream", + kw::default_value="") + .arg("area", "area to match or empty to match any area", + kw::default_value="") + .arg("level", "log level, one of: VERBOSE, NOTICE, MESSAGE, IMPORTANT, CRITICAL, FATAL", + kw::default_value=local::VERBOSE) + .arg("action", "routing action, one of: ACCEPT, REJECT", + kw::default_value=ACCEPT) + .arg("index", "index at which to insert new rule", + kw::default_value=-1) + .doc("Add routing entry. Log messages are matched against the routing table beginning\n" + "with the first entry. The action of the first matching entry determines the\n" + "handling of the message.\n" + "\n" + "Examples:\n" + "\n" + " route\n" + " route all messages to this target.\n" + "\n" + " route \"\" my::Class\n" + " route all messages which are in the my::Class area.\n" + "\n" + " route senf::log::Debug \"\" VERBOSE REJECT\n" + " route \"\" \"\" VERBOSE\n" + " route all messages not in the senf::log::Debug stream to the current area.\n" + "\n" + "The additional optional index argument identifies the position in the routing table\n" + "where the new routing entry will be added. Positive numbers count from the\n" + "beginning, 0 being the first routing entry. Negative values count from the end.\n"); + consoleDir_().add("unroute", + senf::membind(static_cast(&Target::unroute), this)) + .arg("index", "index of routing entry to remove") + .overloadDoc("Remove routing entry with the given index"); + consoleDir_().add("unroute", + boost::function( + senf::membind( + static_cast(&Target::unroute), + this))) + .arg("stream", "stream to match or empty to match any stream", + kw::default_value="") + .arg("area", "area to match or empty to match any area", + kw::default_value="") + .arg("level", "log level, one of: VERBOSE, NOTICE, MESSAGE, IMPORTANT, CRITICAL, FATAL", + kw::default_value=local::VERBOSE) + .arg("action", "routing action, one of: ACCEPT, REJECT", + kw::default_value=ACCEPT) + .overloadDoc("Remove the routing entry matching the specified arguments."); + consoleDir_().add("flush", senf::membind(&Target::flush, this)) + .doc("Remove all routing entries clearing the routing table. This will disable all\n" + "logging output on this target."); } prefix_ senf::log::Target::~Target() @@ -56,9 +157,12 @@ prefix_ senf::log::Target::~Target() prefix_ void senf::log::Target::route(std::string const & stream, std::string const & area, unsigned level, action_t action, int index) { - detail::StreamBase const * s (StreamRegistry::instance().lookup(stream)); - if (!s) - throw InvalidStreamException(); + detail::StreamBase const * s (0); + if (! stream.empty()) { + s = StreamRegistry::instance().lookup(stream); + if (!s) + throw InvalidStreamException(); + } detail::AreaBase const * a (0); if (! area.empty()) { a = AreaRegistry::instance().lookup(area); @@ -71,9 +175,12 @@ prefix_ void senf::log::Target::route(std::string const & stream, std::string co prefix_ void senf::log::Target::unroute(std::string const & stream, std::string const & area, unsigned level, action_t action) { - detail::StreamBase const * s (StreamRegistry::instance().lookup(stream)); - if (!s) - throw InvalidStreamException(); + detail::StreamBase const * s (0); + if (! stream.empty()) { + s = StreamRegistry::instance().lookup(stream); + if (!s) + throw InvalidStreamException(); + } detail::AreaBase const * a (0); if (! area.empty()) { a = AreaRegistry::instance().lookup(area); @@ -124,6 +231,15 @@ prefix_ void senf::log::Target::flush() } //////////////////////////////////////// +// protected members + +prefix_ senf::log::detail::TargetRegistry::TargetRegistry() + : fallbackRouting_(true) +{ + console::sysdir().add("log", consoleDir_()); +} + +//////////////////////////////////////// // private members prefix_ void senf::log::Target::route(detail::StreamBase const * stream, @@ -214,9 +330,44 @@ prefix_ void senf::log::Target::write(time_type timestamp, } } +namespace { + std::string formatLabel(std::string const & l) + { + if (l.empty()) + return "-"; + if (l.size() > 29) + return l.substr(l.size()-29); + return l; + } +} + +prefix_ void senf::log::Target::consoleList(std::ostream & os) +{ + static char const * levels[] = { + "none", "verbose", "notice", "message", "important", "critical", "fatal", "disabled" }; + + boost::format fmt ("%2d %-29s %-29s %-9s %-6s\n"); + os << fmt % "#" % "STREAM" % "AREA" % "LEVEL" % "ACTION"; + unsigned n (0); + for (iterator i (begin()); i != end(); ++i, ++n) + os << fmt + % n + % formatLabel(i->stream()) + % formatLabel(i->area()) + % levels[i->level()] + % (i->action() == ACCEPT ? "accept" : "reject"); +} + /////////////////////////////////////////////////////////////////////////// // senf::log::detail::TargetRegistry +prefix_ void senf::log::detail::TargetRegistry::registerTarget(Target * target, + std::string const & name) +{ + targets_.insert(target); + consoleDir_().add(name, target->consoleDir_()); +} + prefix_ void senf::log::detail::TargetRegistry::write(StreamBase const & stream, AreaBase const & area, unsigned level, std::string const & msg) diff --git a/Utils/Logger/Target.cci b/Utils/Logger/Target.cci index 10e58ab..09c5706 100644 --- a/Utils/Logger/Target.cci +++ b/Utils/Logger/Target.cci @@ -137,15 +137,6 @@ prefix_ bool senf::log::detail::TargetRegistry::fallbackRouting() //////////////////////////////////////// // private members -prefix_ senf::log::detail::TargetRegistry::TargetRegistry() - : fallbackRouting_(true) -{} - -prefix_ void senf::log::detail::TargetRegistry::registerTarget(Target * target) -{ - targets_.insert(target); -} - prefix_ void senf::log::detail::TargetRegistry::unregisterTarget(Target * target) { targets_.erase(target); diff --git a/Utils/Logger/Target.hh b/Utils/Logger/Target.hh index 9065ef4..69fd1d1 100644 --- a/Utils/Logger/Target.hh +++ b/Utils/Logger/Target.hh @@ -36,6 +36,7 @@ #include "StreamRegistry.hh" #include "../Exception.hh" #include "TimeSource.hh" +#include "../Console/LazyDirectory.hh" //#include "Target.mpp" ///////////////////////////////hh.p//////////////////////////////////////// @@ -185,7 +186,7 @@ namespace log { ///\name Structors and default members ///@{ - Target(); + explicit Target(std::string const & name); virtual ~Target(); ///@} @@ -351,6 +352,8 @@ namespace log { void write(time_type timestamp, detail::StreamBase const & stream, detail::AreaBase const & area, unsigned level, std::string const & message); + void consoleList(std::ostream & os); + # ifdef DOXYGEN protected: # endif @@ -382,6 +385,8 @@ namespace log { RIB rib_; + console::LazyDirectory consoleDir_; + friend class detail::AreaBase; friend class detail::TargetRegistry; }; diff --git a/Utils/Logger/Target.ih b/Utils/Logger/Target.ih index a083871..c6d4efb 100644 --- a/Utils/Logger/Target.ih +++ b/Utils/Logger/Target.ih @@ -30,6 +30,7 @@ #include #include #include +#include "../Console/LazyDirectory.hh" ///////////////////////////////ih.p//////////////////////////////////////// @@ -53,13 +54,15 @@ namespace detail { private: TargetRegistry(); - void registerTarget(Target * target); + void registerTarget(Target * target, std::string const & name); void unregisterTarget(Target * target); typedef std::set Targets; Targets targets_; bool fallbackRouting_; + + console::LazyDirectory consoleDir_; friend class senf::log::Target; friend class senf::singleton; diff --git a/Utils/String.cti b/Utils/String.cti new file mode 100644 index 0000000..8d39ba9 --- /dev/null +++ b/Utils/String.cti @@ -0,0 +1,52 @@ +// $Id$ +// +// Copyright (C) 2009 +// 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 String inline template implementation */ + +//#include "String.ih" + +// Custom includes +#include + +#define prefix_ inline +///////////////////////////////cti.p/////////////////////////////////////// + +template +prefix_ std::string senf::str(T const & t) +{ + return boost::lexical_cast(t); +} + +///////////////////////////////cti.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: diff --git a/Utils/String.hh b/Utils/String.hh index 10f523e..623068b 100644 --- a/Utils/String.hh +++ b/Utils/String.hh @@ -42,12 +42,15 @@ namespace senf { template std::string stringJoin(ForwardReadableRange const & range, std::string sep); + template + std::string str(T const & t); + } ///////////////////////////////hh.e//////////////////////////////////////// //#include "String.cci" #include "String.ct" -//#include "String.cti" +#include "String.cti" #endif