X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Utils%2FLogger%2FTarget.hh;h=69fd1d123115c7987da35c61c92ddea75c8279c1;hb=41eff772147b6df1961d9029ba6815b553b4f81d;hp=02226ca8901fee320d907e72b9b02b9aed20e503;hpb=012a592d56be453719b7fbba492b56ae804c048f;p=senf.git diff --git a/Utils/Logger/Target.hh b/Utils/Logger/Target.hh index 02226ca..69fd1d1 100644 --- a/Utils/Logger/Target.hh +++ b/Utils/Logger/Target.hh @@ -1,8 +1,8 @@ // $Id$ // -// Copyright (C) 2007 -// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) -// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Copyright (C) 2007 +// 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 @@ -23,18 +23,20 @@ /** \file \brief Target public header */ -#ifndef HH_Target_ -#define HH_Target_ 1 +#ifndef HH_SENF_Utils_Logger_Target_ +#define HH_SENF_Utils_Logger_Target_ 1 // Custom includes #include -#include +#include #include #include #include "../singleton.hh" #include "../mpl.hh" #include "StreamRegistry.hh" -#include "AreaRegistry.hh" +#include "../Exception.hh" +#include "TimeSource.hh" +#include "../Console/LazyDirectory.hh" //#include "Target.mpp" ///////////////////////////////hh.p//////////////////////////////////////// @@ -52,12 +54,13 @@ namespace senf { namespace log { - class TargetRegistry; + namespace detail { class TargetRegistry; } + namespace detail { class AreaBase; } /** \brief Logging target base class - - Targets are the final destination of log messages. Every message is eventually routed to one - or several targets. + + Targets are the final destination of %log messages. Every message is eventually routed to + one or several targets. \section target_routing Routing @@ -65,12 +68,13 @@ namespace log { matched against this table. If an entry matches, the action associated with this entry is taken (either \c ACCEPT or \c REJECT). - Every target manages it's own routing table. Conceptually, every routing message will be - routed to every target where it will then be matched against each targets routing table (the + Every target manages it's own routing table. Conceptually, every message will be routed to + every target where it will then be matched against each targets routing table (the implementation is more efficient and utilizes a routing cache). Each routing entry consists of the following parameters - \li (mandatory) \e stream. The entry will match only messages directed at that stream + \li (optional) \e stream. If specified, the entry will match only messages directed at that + stream \li (optional) \e area. If the area is specified, only messages directed at that area are matched, otherwise any area will be allowed \li (optional) \e level. If the log level is specified, messages will be accepted if their @@ -85,11 +89,13 @@ namespace log { \code target.route(senf::log::Target::REJECT); target.route(); + target.route(); \endcode The identical routing statements may be expressed using dynamic routing via: \code target.route("foo::SomeStream", "", senf::log::NOTICE::value, senf::log::Target::REJECT); target.route("foo::SomeStream"); + target.route(); \endcode The static representation has the benefit of being compile-time type checked: Invalid routing parameters will be caught while compiling the code. The dynamic representation is @@ -97,10 +103,10 @@ namespace log { The different object representations are: \li The \e streams is statically represented by it's name, which is the name of a class - defined with \ref SENF_LOG_DEF_STREAM. The dynamic representation is a string + defined with \ref SENF_LOG_DEFINE_STREAM. The dynamic representation is a string representation of this name. \li The \e area is statically represented by it's name, which again is the name of a class - defined with \ref SENF_LOG_DEF_STREAM. The dynamic representation again is a string + defined with \ref SENF_LOG_DEFINE_STREAM. The dynamic representation again is a string representation of this class's name. The dynamic representation represents an absent area with the empty string. \li The \e level is statically represented by a level class from \ref @@ -110,18 +116,15 @@ namespace log { \section target_impl Implementing new targets To implement a new target type, you need to derive from senf::log::Target and implement the - single \c v_write member. This member will be called whenever a message should be output. + single \c v_write member. This member will be called whenever a message should be output. - The target may process in any arbitrary way: reformat, writing it into an SQL DB, whatever - can be envisioned. However, there is one important limitation: The \c v_write call must not - block. So for more complex scenarios, additional measures must be taken (e.g. writing a log - backend daemon which receives the messages via UDP and processes them). Of course, in rare - cases messages might be lost but this cannot be avoided. + The target may process the message in any arbitrary way: reformat it, write it into an SQL + DB, whatever can be envisioned. However, there is one important limitation: The \c v_write + call must \e not block. So for more complex scenarios, additional measures must be taken + (e.g. writing a %log backend daemon which receives the messages via UDP and processes + them). Of course, in rare cases messages might be lost but this cannot be avoided. \see \ref targets - - \fixme optionally Integrate with Scheduler / ClockService to reduce number of gettimeofday() - calls. */ class Target : private boost::noncopyable { @@ -134,7 +137,7 @@ namespace log { Every routing entry is associated with a routing action. This action is final (for this target. Each target is processed independently). */ - enum action_t { + enum action_t { ACCEPT /** Output message */ , REJECT /** Suppress message output */ }; @@ -146,29 +149,29 @@ namespace log { \see senf::log::Target */ - struct RoutingEntry + struct RoutingEntry { std::string stream() const; ///< Stream to match std::string area() const; ///< Area to match (empty of unspecified) unsigned level() const; ///< Level to match (senf::log::NONE::value if unspecified) action_t action() const; ///< Action to take - + # ifdef DOXYGEN private: # endif RoutingEntry(); - bool operator==(RoutingEntry const & other); + bool operator==(RoutingEntry const & other) const; private: - RoutingEntry(detail::StreamBase const * stream, detail::AreaBase const * area, + RoutingEntry(detail::StreamBase const * stream, detail::AreaBase const * area, unsigned level, action_t action); detail::StreamBase const * stream_; detail::AreaBase const * area_; unsigned level_; action_t action_; - + friend class Target; }; @@ -177,12 +180,13 @@ namespace log { public: typedef RIB::const_iterator iterator; ///< Routing table iterator + typedef RIB::size_type size_type; /////////////////////////////////////////////////////////////////////////// ///\name Structors and default members ///@{ - Target(); + explicit Target(std::string const & name); virtual ~Target(); ///@} @@ -195,57 +199,61 @@ namespace log { template void route( action_t action = ACCEPT, int index = -1); ///< Add route (static) /**< Add a route for the given combination of \a Stream, \a - Area and \a Level. The \a Stream parameter is mandatory - while either \a Area or \a Level are optional (the - template signature is shown simplified here): + Area and \a Level. All parameters (\a Stream, \a Area + and \a Level) are optional (the template signature is + shown simplified here). So possible commands are: \code + target.route(); target.route(); - target.route(); + target.route(); + target.route(); target.route(); + target.route(); + target.route(); target.route(); \endcode See the class description for information on the \a - action and \a index parameters + action and \a index parameters - \param[in] Stream mandatory stream to match - \param[in] Area optional area to match - \param[in] Level optional level, matches messages with - at least the given level. + \tparam Stream stream to match + \tparam Area area to match + \tparam Level level, matches messages with + at least the given level. \param[in] action routing action to take \param[in] index position of new route in the routing table */ # endif - void route(std::string const & stream, std::string const & area = "", + void route(std::string const & stream, std::string const & area = "", unsigned level = NONE::value, action_t action = ACCEPT, int index = -1); ///< Add route (dynamic) /**< Add a route for the given combination of \a stream, \a - area and \a level. The \a stream parameter is mandatory - while either \a area or \a level may be left - unspecified by setting them to the empty string or + area and \a level. All parameters (\a Stream, \a Area + and \a Level) are optional and may be omitted by + setting them to the empty string or the senf::log::NONE::value respectively. See the class description for information on the \a - action and \a index parameters + action and \a index parameters \throws InvalidStreamException if the given \a stream is not found in the StreamRegistry \throws InvalidAreaException if the given \a area is not found in the AreaRegistry - \param[in] stream mandatory stream to match - \param[in] area optional area to match - \param[in] level optional level, matches messages with - at least the given level. + \param[in] stream stream to match + \param[in] area area to match + \param[in] level level, matches messages with at least + the given level. \param[in] action routing action to take \param[in] index position of new route in the routing table */ # ifdef DOXYGEN - template + template void unroute(action_t action = ACCEPT); ///< Remove route (static) /**< This member removes an arbitrary routing entry. The @@ -257,15 +265,15 @@ namespace log { found, it will be removed, otherwise the call will be ignored - \param[in] Stream mandatory stream to match - \param[in] Area optional area to match - \param[in] Level optional level, matches messages with - at least the given level. + \tparam Stream stream to match + \tparam Area area to match + \tparam Level level, matches messages with + at least the given level. \param[in] action routing action to take */ # endif - void unroute(std::string const & stream, std::string const & area = "", + void unroute(std::string const & stream, std::string const & area = "", unsigned level = NONE::value, action_t action = ACCEPT); ///< Remove route (dynamic) /**< This member removes an arbitrary routing entry. The \a @@ -278,107 +286,86 @@ namespace log { found, it will be removed, otherwise the call will be ignored - \param[in] stream mandatory stream to match - \param[in] area optional area to match - \param[in] level optional level, matches messages with - at least the given level. + \param[in] stream stream to match + \param[in] area area to match + \param[in] level level, matches messages with at least + the given level. \param[in] action routing action to take */ void unroute(int index=-1); ///< Remove route (indexed) /**< This call will remove the route with the given index. - + See the class documentation for more information on - indexing. + indexing. \param[in] index index of routing entry to remove */ # ifndef DOXYGEN - template void route( - action_t action = ACCEPT, int index = -1); - template void route( - action_t action = ACCEPT, int index = -1, - typename boost::enable_if< boost::is_convertible >::type * = 0); - template void route( - action_t action = ACCEPT, int index = -1, - typename boost::enable_if< boost::is_convertible >::type * = 0); - template void route( - action_t action = ACCEPT, int index = -1, - typename boost::enable_if< boost::is_convertible >::type * = 0); - template void route( - action_t action = ACCEPT, int index = -1, - typename boost::enable_if< boost::is_convertible >::type * = 0); - template void route( - action_t action = ACCEPT, int index = -1, - typename boost::enable_if< boost::is_convertible >::type * = 0); - - template void unroute( - action_t action = ACCEPT); - template void unroute( - action_t action = ACCEPT, - typename boost::enable_if< boost::is_convertible >::type * = 0); - template void unroute( - action_t action = ACCEPT, - typename boost::enable_if< boost::is_convertible >::type * = 0); - template void unroute( - action_t action = ACCEPT, - typename boost::enable_if< boost::is_convertible >::type * = 0); - template void unroute( - action_t action = ACCEPT, - typename boost::enable_if< boost::is_convertible >::type * = 0); - template void unroute( - action_t action = ACCEPT, - typename boost::enable_if< boost::is_convertible >::type * = 0); + void route(action_t action = ACCEPT, int index = -1); + template + void route(action_t action = ACCEPT, int index = -1); + template + void route(action_t action = ACCEPT, int index = -1); + template + void route(action_t action = ACCEPT, int index = -1); + + void unroute(action_t action = ACCEPT); + template + void unroute(action_t action = ACCEPT); + template + void unroute(action_t action = ACCEPT); + template + void unroute(action_t action = ACCEPT); # endif ///\} /** \brief Exception: Invalid stream */ - struct InvalidStreamException : public std::exception - { virtual char const * what() const throw() - { return "senf::log::Target::InvalidStreamException"; } }; - + struct InvalidStreamException : public senf::Exception + { InvalidStreamException() + : senf::Exception("senf::log::Target::InvalidStreamException"){} }; + /** \brief Exception: Invalid area */ - struct InvalidAreaException : public std::exception - { virtual char const * what() const throw() - { return "senf::log::Target::InvalidAreaException"; } }; + struct InvalidAreaException : public senf::Exception + { InvalidAreaException() + : senf::Exception("senf::log::Target::InvalidAreaException"){} }; iterator begin() const; ///< Iterator to beginning of routing table iterator end() const; ///< Iterator past the end of routing table - + + RoutingEntry const & operator[](size_type i) const; ///< Access routing entry + + size_type size() const; ///< Number of routing table entries + bool empty() const; ///< \c true, if routing table empty, \c false otherwise + + void flush(); ///< Clear routing table + private: - void route(detail::StreamBase const * stream, detail::AreaBase const * area, + void route(detail::StreamBase const * stream, detail::AreaBase const * area, unsigned level, action_t action, int index); - void unroute(detail::StreamBase const * stream, detail::AreaBase const * area, + void unroute(detail::StreamBase const * stream, detail::AreaBase const * area, unsigned level, action_t action); void updateRoutingCache(detail::StreamBase const * stream, detail::AreaBase const * area); - void write(boost::posix_time::ptime timestamp, detail::StreamBase const & stream, + 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 - virtual void v_write(boost::posix_time::ptime timestamp, std::string const & stream, - std::string const & area, unsigned level, + virtual void v_write(time_type timestamp, std::string const & stream, + std::string const & area, unsigned level, std::string const & message) = 0; ///< Called to write out the routing message /**< This member must be defined in the derived class to - somehow format and write the log message. + somehow format and write the %log message. - Every log message always possesses a complete set of + Every %log message always possesses a complete set of meta information (\a stream, \a area and \a level). \note This member must \e not block since it may be @@ -386,7 +373,7 @@ namespace log { simple logging over NFS or many other network protocols. - \param[in] timestamp log message timing information + \param[in] timestamp %log message timing information \param[in] stream message stream \param[in] area message area \param[in] level message level @@ -397,10 +384,18 @@ namespace log { # endif RIB rib_; - + + console::LazyDirectory consoleDir_; + friend class detail::AreaBase; + friend class detail::TargetRegistry; }; + /** \brief Write route action + \related Target + */ + std::ostream & operator<<(std::ostream & os, Target::action_t const & action); + }} ///////////////////////////////hh.e//////////////////////////////////////// @@ -409,7 +404,7 @@ namespace log { #include "Target.cti" #endif - + // Local Variables: // mode: c++ // fill-column: 100