}
}
+///////////////////////////////////////////////////////////////////////////
+// senf::SchedulerLogTimeSource
+
+prefix_ boost::posix_time::ptime senf::SchedulerLogTimeSource::operator()()
+ const
+{
+ return ClockService::abstime(Scheduler::instance().eventTime());
+}
+
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
#include <boost/call_traits.hpp>
#include <boost/integer.hpp>
#include "ClockService.hh"
+#include "../Utils/Logger/Target.hh"
//#include "scheduler.mpp"
///////////////////////////////hh.p////////////////////////////////////////
*/
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////////////////////////////////////////
\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:
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<senf::SchedulerLogTimeSource>();
+ \endcode
*/
namespace senf {
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 <em>of the current scope</em>. 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 <em>compile time constants</em> (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
}
///////////////////////////////////////////////////////////////////////////
-// 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////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// 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<TimeSource> 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);
targets_.erase(target);
}
+///////////////////////////////////////////////////////////////////////////
+// namespace senf::log members
+
+prefix_ void senf::log::timeSource(std::auto_ptr<TimeSource> source)
+{
+ detail::TargetRegistry::instance().timeSource(source);
+}
+
/////////////////////////////cci.e///////////////////////////////////////
#undef prefix_
TargetRegistry::instance().write(Stream::instance(), Area::instance(), Level::value, msg);
}
+template <class Source>
+prefix_ void senf::log::timeSource()
+{
+ timeSource(std::auto_ptr<Source>(new Source()));
+}
+
///////////////////////////////cti.e///////////////////////////////////////
#undef prefix_
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
{
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<TimeSource> 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 <class Source> void timeSource();
+
}}
///////////////////////////////hh.e////////////////////////////////////////
#define IH_Target_ 1
// Custom includes
+#include <memory>
+#include <boost/scoped_ptr.hpp>
///////////////////////////////ih.p////////////////////////////////////////
void write(StreamBase const & stream, AreaBase const & area, unsigned level,
std::string msg);
+ void timeSource(std::auto_ptr<TimeSource> source);
+
private:
+ TargetRegistry();
+
void registerTarget(Target * target);
void unregisterTarget(Target * target);
typedef std::set<Target *> Targets;
Targets targets_;
+ boost::scoped_ptr<TimeSource> timeSource_;
friend class senf::log::Target;
+ friend class senf::singleton<TargetRegistry>;
};
/** \brief Internal: Write log message */