From: g0dil Date: Thu, 27 Mar 2008 01:20:43 +0000 (+0000) Subject: Console: Add log support to network client (every client is a log target) X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=d0776a27ffd63ab51b4e3419a8a6f87d11e60594;p=senf.git Console: Add log support to network client (every client is a log target) git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@768 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Console/Doxyfile b/Console/Doxyfile index 0a359ce..1fd99b4 100644 --- a/Console/Doxyfile +++ b/Console/Doxyfile @@ -7,4 +7,5 @@ ALPHABETICAL_INDEX = NO TAGFILES = \ "$(TOPDIR)/Socket/doc/Socket.tag" \ "$(TOPDIR)/Scheduler/doc/Scheduler.tag" \ - "$(TOPDIR)/Utils/doc/Utils.tag" + "$(TOPDIR)/Utils/doc/Utils.tag" \ + "$(TOPDIR)/Utils/Logger/doc/Logger.tag" diff --git a/Console/Executor.hh b/Console/Executor.hh index 93071ac..d089083 100644 --- a/Console/Executor.hh +++ b/Console/Executor.hh @@ -65,7 +65,8 @@ namespace console { typedef boost::iterator_range< ParseCommandInfo::argument_iterator> Arguments; - struct ExitException {}; ///< Thrown by built-in 'exit' command + /// Thrown by built-in 'exit' command + struct ExitException {}; /////////////////////////////////////////////////////////////////////////// //\/name Structors and default members diff --git a/Console/Node.hh b/Console/Node.hh index cf48403..c3911ff 100644 --- a/Console/Node.hh +++ b/Console/Node.hh @@ -143,6 +143,7 @@ namespace console { typedef typename boost::remove_reference::type NodeType; + /// Internal struct Creator { static NodeType & create(DirectoryNode & node, std::string const & name, Object const & ob); diff --git a/Console/ObjectDirectory.hh b/Console/ObjectDirectory.hh index 1f26bef..bb8008f 100644 --- a/Console/ObjectDirectory.hh +++ b/Console/ObjectDirectory.hh @@ -53,6 +53,7 @@ namespace console { typedef typename boost::remove_reference::type NodeType; + /// Internal struct Creator { static NodeType & create(DirectoryNode & node, Owner & owner, std::string const & name, Object const & ob); diff --git a/Console/Parse.cc b/Console/Parse.cc index bf49f31..c06a2bc 100644 --- a/Console/Parse.cc +++ b/Console/Parse.cc @@ -41,6 +41,8 @@ namespace senf { namespace console { namespace detail { +#ifndef DOXYGEN + struct ParserAccess { static void init(ParseCommandInfo & info) @@ -149,11 +151,15 @@ namespace detail { } }; +#endif + }}} /////////////////////////////////////////////////////////////////////////// // senf::console::ParseCommandInfo +#ifndef DOXYGEN + struct senf::console::ParseCommandInfo::MakeRange { typedef ParseCommandInfo::argument_value_type result_type; @@ -168,6 +174,8 @@ struct senf::console::ParseCommandInfo::MakeRange } }; +#endif + prefix_ void senf::console::ParseCommandInfo::finalize() { arguments_.resize( tempArguments_.size() ); @@ -211,6 +219,8 @@ prefix_ std::ostream & senf::console::operator<<(std::ostream & stream, /////////////////////////////////////////////////////////////////////////// // senf::console::CommandParser +#ifndef DOXYGEN + struct senf::console::CommandParser::Impl { typedef detail::CommandGrammar Grammar; @@ -222,6 +232,8 @@ struct senf::console::CommandParser::Impl Impl() : dispatcher(), context(), grammar(dispatcher, context) {} }; +#endif + prefix_ senf::console::CommandParser::CommandParser() : impl_ (new Impl()) {} diff --git a/Console/Server.cc b/Console/Server.cc index 4e37e68..eb1fac1 100644 --- a/Console/Server.cc +++ b/Console/Server.cc @@ -102,11 +102,13 @@ prefix_ void senf::console::Server::removeClient(Client & client) // senf::console::Client prefix_ senf::console::Client::Client(ClientHandle handle, std::string const & name) - : handle_ (handle), name_ (name), out_(::dup(handle.fd())) + : out_t(::dup(handle.fd())), senf::log::IOStreamTarget(out_t::member), + handle_ (handle), name_ (name), promptLen_(0) { showPrompt(); ReadHelper::dispatch( handle_, 16384u, ReadUntil("\n"), senf::membind(&Client::clientData, this) ); + route< senf::SenfLog, senf::log::NOTICE >(); } prefix_ senf::console::Client::~Client() @@ -120,6 +122,7 @@ prefix_ void senf::console::Client::stopClient() prefix_ void senf::console::Client::clientData(ReadHelper::ptr helper) { + promptLen_ = 0; if (helper->error() || handle_.eof()) { // THIS COMMITS SUICIDE. THE INSTANCE IS GONE AFTER stopClient RETURNS stopClient(); @@ -131,8 +134,9 @@ prefix_ void senf::console::Client::clientData(ReadHelper::ptr hel boost::trim(data); // Gets rid of superfluous \r or \n characters try { - if (! parser_.parse(data, boost::bind(boost::ref(executor_), _1, boost::ref(out_)))) - out_ << "syntax error" << std::endl; + if (! parser_.parse(data, boost::bind(boost::ref(executor_), _1, + boost::ref(out_t::member)))) + out_t::member << "syntax error" << std::endl; } catch (Executor::ExitException &) { // THIS COMMITS SUICIDE. THE INSTANCE IS GONE AFTER stopClient RETURNS @@ -140,10 +144,10 @@ prefix_ void senf::console::Client::clientData(ReadHelper::ptr hel return; } catch (std::exception & ex) { - out_ << ex.what() << std::endl; + out_t::member << ex.what() << std::endl; } catch (...) { - out_ << "unidentified error (unknown exception thrown)" << std::endl; + out_t::member << "unidentified error (unknown exception thrown)" << std::endl; } showPrompt(); @@ -153,7 +157,21 @@ prefix_ void senf::console::Client::clientData(ReadHelper::ptr hel prefix_ void senf::console::Client::showPrompt() { - out_ << name_ << ":" << executor_.cwd().path() << "# " << std::flush; + std::string path (executor_.cwd().path()); + out_t::member << name_ << ":" << path << "# " << std::flush; + promptLen_ = name_.size() + 1 + path.size() + 1; +} + +prefix_ void senf::console::Client::v_write(boost::posix_time::ptime timestamp, + std::string const & stream, + std::string const & area, unsigned level, + std::string const & message) +{ + if (promptLen_) + out_t::member << '\r' << std::string(' ', promptLen_) << '\r'; + IOStreamTarget::v_write(timestamp, stream, area, level, message); + if (promptLen_) + showPrompt(); } ///////////////////////////////cc.e//////////////////////////////////////// diff --git a/Console/Server.hh b/Console/Server.hh index 685eae2..26092fa 100644 --- a/Console/Server.hh +++ b/Console/Server.hh @@ -41,6 +41,7 @@ #include "Parse.hh" #include "Executor.hh" #include "../Socket/Protocols/INet/INetAddressing.hh" +#include "../Utils/Logger.hh" //#include "Server.mpp" ///////////////////////////////hh.p//////////////////////////////////////// @@ -113,10 +114,17 @@ namespace console { \fixme Make output non-blocking (use a non-blocking/discarding streambuf) and possibly set socket send buffer size \fixme Don't register a new ReadHelper every round + \fixme Ensure, that output errors (or any errors) in the console don't terminate the + application */ class Client - : public senf::intrusive_refcount + : public senf::intrusive_refcount, + private boost::base_from_member< boost::iostreams::stream >, + public senf::log::IOStreamTarget { + typedef boost::base_from_member< + boost::iostreams::stream > out_t; + SENF_LOG_CLASS_AREA(); SENF_LOG_DEFAULT_LEVEL( senf::log::NOTICE ); public: @@ -134,15 +142,17 @@ namespace console { void clientData(ReadHelper::ptr helper); void showPrompt(); + + virtual void v_write(boost::posix_time::ptime timestamp, std::string const & stream, + std::string const & area, unsigned level, + std::string const & message); ClientHandle handle_; std::string tail_; CommandParser parser_; Executor executor_; std::string name_; - - typedef boost::iostreams::stream fdostream; - fdostream out_; + unsigned promptLen_; friend class Server; }; diff --git a/Utils/Logger/IOStreamTarget.cc b/Utils/Logger/IOStreamTarget.cc index dbf4454..0d798bb 100644 --- a/Utils/Logger/IOStreamTarget.cc +++ b/Utils/Logger/IOStreamTarget.cc @@ -73,8 +73,8 @@ prefix_ void senf::log::IOStreamTarget::v_write(boost::posix_time::ptime timesta stream_ << timestamp << sep; stream_ << "[" << LEVELNAMES_[level] << "]"; if (area != "senf::log::DefaultArea") - stream_ << "[" << area << "] "; - stream_ << *i << "\n"; + stream_ << "[" << area << "]"; + stream_ << " " << *i << "\n"; sep = '-'; } stream_ << std::flush; diff --git a/Utils/Logger/IOStreamTarget.hh b/Utils/Logger/IOStreamTarget.hh index 7e4900b..2a2763a 100644 --- a/Utils/Logger/IOStreamTarget.hh +++ b/Utils/Logger/IOStreamTarget.hh @@ -73,12 +73,11 @@ namespace log { /////////////////////////////////////////////////////////////////////////// protected: - - private: void v_write(boost::posix_time::ptime timestamp, std::string const & stream, std::string const & area, unsigned level, std::string const & message); + private: std::ostream & stream_; static char const * const LEVELNAMES_[8]; }; diff --git a/Utils/Logger/Target.cc b/Utils/Logger/Target.cc index 9740cec..91d231e 100644 --- a/Utils/Logger/Target.cc +++ b/Utils/Logger/Target.cc @@ -45,8 +45,8 @@ prefix_ senf::log::Target::Target() prefix_ senf::log::Target::~Target() { while( ! rib_.empty()) { - // This is terribly slow but simplifies the area cache handling and removing a target should - // be quite seldom + // This is slow but simplifies the area cache handling and removing a target should be + // relatively seldom RIB::reverse_iterator i (rib_.rbegin()); unroute(i->stream_, i->area_, i->level_, i->action_); }