From: g0dil Date: Thu, 1 Nov 2007 11:35:47 +0000 (+0000) Subject: Utils/Logger: Implement TimeSource facility X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=82ad2ed94c12c3e53097fef92978de8c28239fab;p=senf.git Utils/Logger: Implement TimeSource facility Utils/Logger: Add Alias documentation Scheduler: Add scheduler based logger time source git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@490 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Scheduler/Scheduler.cc b/Scheduler/Scheduler.cc index 09971a8..adbb6a6 100644 --- a/Scheduler/Scheduler.cc +++ b/Scheduler/Scheduler.cc @@ -243,6 +243,15 @@ prefix_ void senf::Scheduler::process() } } +/////////////////////////////////////////////////////////////////////////// +// senf::SchedulerLogTimeSource + +prefix_ boost::posix_time::ptime senf::SchedulerLogTimeSource::operator()() + const +{ + return ClockService::abstime(Scheduler::instance().eventTime()); +} + ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ diff --git a/Scheduler/Scheduler.hh b/Scheduler/Scheduler.hh index 3ec8147..babc199 100644 --- a/Scheduler/Scheduler.hh +++ b/Scheduler/Scheduler.hh @@ -35,6 +35,7 @@ #include #include #include "ClockService.hh" +#include "../Utils/Logger/Target.hh" //#include "scheduler.mpp" ///////////////////////////////hh.p//////////////////////////////////////// @@ -239,6 +240,17 @@ namespace senf { */ int retrieve_filehandle(int fd); + /** \brief Scheduler specific time source for Utils/Logger framework + + This time source may be used to provide timing information for log messages within the + Utils/Logger framework. This time source will use Scheduler::eventTime() to provide timing + information. + */ + struct SchedulerLogTimeSource : public senf::log::TimeSource + { + boost::posix_time::ptime operator()() const; + }; + } ///////////////////////////////hh.e//////////////////////////////////////// diff --git a/Utils/Logger/Config.hh b/Utils/Logger/Config.hh index 8e55030..634d723 100644 --- a/Utils/Logger/Config.hh +++ b/Utils/Logger/Config.hh @@ -65,6 +65,8 @@ \c foo::SomeClass area, where it is set to \c VERBOSE. Furthermore, the limit on the \c foo::Transactions stream is set to \c NOTICE. + \see \ref SENF_LOG_CONF + \section config_runtime Runtime configuration The runtime configuration is performed by routing messages to one or more logging targets: @@ -85,9 +87,21 @@ The routing statements are processed by the targets in order, the first matching rule will decide a log messages fate for that target. - \see - \ref SENF_LOG_CONF compile time configuration \n - \ref senf::log::Target runtime configuration + \see \ref senf::log::Target + + \section config_timesource Log message timing + + One auxiliary aspect of logging is message timing. Each message is stamped with a time-stamp + giving the exact time the message was created. How the current date/time value is created may be + changed by setting a \e TimeSource. A TimeSource is an instance derived from + senf::log::TimeSource which will return the current universal time (UTC) when called. + + By default, the logging library will call gettimeofday() for each log message. To change the + time source, just pass the new class or instance to senf::log::timeSource: + \code + // Use senf::Scheduler::instance().eventTime() to time log messages + senf::log::timeSource(); + \endcode */ namespace senf { diff --git a/Utils/Logger/Log.hh b/Utils/Logger/Log.hh index 028d14e..33d9ad3 100644 --- a/Utils/Logger/Log.hh +++ b/Utils/Logger/Log.hh @@ -62,15 +62,34 @@ This current default value is set using \ref SENF_LOG_DEFAULT_STREAM, \ref SENF_LOG_DEFAULT_AREA and \ref SENF_LOG_DEFAULT_LEVEL respectively. These macros set the default stream, area and/or - level of the current scope. The logging library defines the global defaults for these values to - be \c senf::log::Debug (\e stream), senf::log::DefaultArea (\e area), and senf::log::NONE (\e - level). + level of the current scope. They may be used with a class declaration to set defaults + for all class members or within a function or member body to set the default for that member + only. They may be used only \e once within each scope. + + The logging library defines the global defaults for stream, area and level to be \c + senf::log::Debug, senf::log::DefaultArea, and senf::log::NONE respectively. The log level senf::log::NONE is special. If the log level is set to this value, the log level will be set from the stream provided default value. All these parameters must be compile time constants (they are all types, so it's difficult form them to be something else). + + \section logging_aliases Aliases + + To further simplify logging commands, aliases may be defined within any scope. An alias is an + arbitrary collection of log parameters: + \code + SENF_LOG_DEF_ALIAS( VerboseDebug, (senf::log::Debug)(senf::log::VERBOSE) ); + \endcode + Within log statements, aliases may be used like normal parameters. They will be substituted for + the parameter sequence they represent: + \code + SENF_LOG( (VerboseDebug)("Debug message") ) + // is equivalent to + SENF_LOG( (senf::log::Debug)(senf::log::VERBOSE)("Debug message") ) + \endcode + Aliases may be used together with other parameters, even with further aliases in any order. */ ///\ingroup logging diff --git a/Utils/Logger/Target.cc b/Utils/Logger/Target.cc index 3c32f95..01864ec 100644 --- a/Utils/Logger/Target.cc +++ b/Utils/Logger/Target.cc @@ -199,14 +199,18 @@ prefix_ void senf::log::Target::write(boost::posix_time::ptime timestamp, } /////////////////////////////////////////////////////////////////////////// -// senf::log::TargetRegistry +// senf::log::TimeSource -prefix_ void senf::log::detail::TargetRegistry::write(StreamBase const & stream, - AreaBase const & area, unsigned level, - std::string msg) +prefix_ senf::log::TimeSource::~TimeSource() +{} + +/////////////////////////////////////////////////////////////////////////// +// senf::log::SystemTimeSource + +prefix_ boost::posix_time::ptime senf::log::SystemTimeSource::operator()() + const { - boost::posix_time::ptime timestamp (boost::posix_time::microsec_clock::universal_time()); - area.write(timestamp, stream, level, msg); + return boost::posix_time::microsec_clock::universal_time(); } ///////////////////////////////cc.e//////////////////////////////////////// diff --git a/Utils/Logger/Target.cci b/Utils/Logger/Target.cci index e7b2409..da1ee4e 100644 --- a/Utils/Logger/Target.cci +++ b/Utils/Logger/Target.cci @@ -94,6 +94,25 @@ prefix_ senf::log::Target::action_t senf::log::Target::RoutingEntry::action() /////////////////////////////////////////////////////////////////////////// // senf::log::detail::TargetRegistry +prefix_ void senf::log::detail::TargetRegistry::write(StreamBase const & stream, + AreaBase const & area, unsigned level, + std::string msg) +{ + area.write((*timeSource_)(), stream, level, msg); +} + +prefix_ void senf::log::detail::TargetRegistry::timeSource(std::auto_ptr source) +{ + timeSource_.reset(source.release()); +} + +//////////////////////////////////////// +// private members + +prefix_ senf::log::detail::TargetRegistry::TargetRegistry() + : timeSource_(new SystemTimeSource()) +{} + prefix_ void senf::log::detail::TargetRegistry::registerTarget(Target * target) { targets_.insert(target); @@ -104,6 +123,14 @@ prefix_ void senf::log::detail::TargetRegistry::unregisterTarget(Target * target targets_.erase(target); } +/////////////////////////////////////////////////////////////////////////// +// namespace senf::log members + +prefix_ void senf::log::timeSource(std::auto_ptr source) +{ + detail::TargetRegistry::instance().timeSource(source); +} + /////////////////////////////cci.e/////////////////////////////////////// #undef prefix_ diff --git a/Utils/Logger/Target.cti b/Utils/Logger/Target.cti index ccc364d..0f7e287 100644 --- a/Utils/Logger/Target.cti +++ b/Utils/Logger/Target.cti @@ -143,6 +143,12 @@ prefix_ void senf::log::detail::write(std::string msg) TargetRegistry::instance().write(Stream::instance(), Area::instance(), Level::value, msg); } +template +prefix_ void senf::log::timeSource() +{ + timeSource(std::auto_ptr(new Source())); +} + ///////////////////////////////cti.e/////////////////////////////////////// #undef prefix_ diff --git a/Utils/Logger/Target.hh b/Utils/Logger/Target.hh index 02226ca..c5ac368 100644 --- a/Utils/Logger/Target.hh +++ b/Utils/Logger/Target.hh @@ -119,9 +119,6 @@ namespace log { 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 { @@ -401,6 +398,55 @@ namespace log { friend class detail::AreaBase; }; + /** \brief Log message time source abstract base class + + Instances derived from TimeSource provide the Logging library with the current date/time + value. The \c operator() member must be implemented to return the current universal time + (UTC). + + A new TimeSource may be installed using \ref senf::log::timeSource(). + + \ingroup config + */ + struct TimeSource + { + virtual ~TimeSource(); + virtual boost::posix_time::ptime operator()() const = 0; + }; + + /** \brief Default log message time source + + This time source is installed by default and uses gettimeofday() (via the Boost.DateTime + library) to get the current universal time. + + \ingroup config + */ + struct SystemTimeSource : public TimeSource + { + virtual boost::posix_time::ptime operator()() const; + }; + + /** \brief Change log message time source + + Set the log message time source to \a source. The logging library will take ownership of \e + source and will take care to free it, if necessary. + + Since the time source class will in almost all cases be default constructible, see the + template overload for a simpler interface. + + \ingroup config + */ + void timeSource(std::auto_ptr source); + + /** \brief Change log message time source + + Set the log message time source to (an instance of) \a Source. \a Source must be default + constructible, otherwise use the non-template senf::log::timeSource() overload. + + \ingroup config + */ + template void timeSource(); + }} ///////////////////////////////hh.e//////////////////////////////////////// diff --git a/Utils/Logger/Target.ih b/Utils/Logger/Target.ih index 115c71e..0506fc5 100644 --- a/Utils/Logger/Target.ih +++ b/Utils/Logger/Target.ih @@ -27,6 +27,8 @@ #define IH_Target_ 1 // Custom includes +#include +#include ///////////////////////////////ih.p//////////////////////////////////////// @@ -44,14 +46,20 @@ namespace detail { void write(StreamBase const & stream, AreaBase const & area, unsigned level, std::string msg); + void timeSource(std::auto_ptr source); + private: + TargetRegistry(); + void registerTarget(Target * target); void unregisterTarget(Target * target); typedef std::set Targets; Targets targets_; + boost::scoped_ptr timeSource_; friend class senf::log::Target; + friend class senf::singleton; }; /** \brief Internal: Write log message */