Utils/Logger: Remove dependency on libboost_datetime
[senf.git] / Utils / Logger / Target.hh
index c5ac368..ff8fc54 100644 (file)
@@ -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 <g0dil@berlios.de>
 //
 // This program is free software; you can redistribute it and/or modify
 
 // Custom includes
 #include <set>
-#include <boost/date_time/posix_time/posix_time.hpp>
+#include <vector>
 #include <boost/utility.hpp>
 #include <boost/type_traits/is_convertible.hpp>
 #include "../singleton.hh"
 #include "../mpl.hh"
 #include "StreamRegistry.hh"
-#include "AreaRegistry.hh"
+#include "../Exception.hh"
+#include "TimeSource.hh"
 
 //#include "Target.mpp"
 ///////////////////////////////hh.p////////////////////////////////////////
 
 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
+        Targets are the final destination of %log messages. Every message is eventually routed to one
         or several targets.
 
         \section target_routing Routing
@@ -70,7 +72,7 @@ namespace log {
         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. 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
@@ -97,10 +99,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
@@ -114,7 +116,7 @@ namespace log {
 
         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
+        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.
 
@@ -192,10 +194,11 @@ namespace log {
         template <class Stream, class Area, class Level> 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). Examples:
                                              \code
+                                             target.route<SomeLevel>();
                                              target.route<SomeStream>();
                                              target.route<SomeStream, SomeLevel>();
                                              target.route<SomeStream, SomeArea>();
@@ -205,9 +208,9 @@ namespace log {
                                              See the class description for information on the \a
                                              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
+                                             \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
@@ -219,9 +222,9 @@ namespace log {
                    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
@@ -232,10 +235,10 @@ namespace log {
                                              \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 */
@@ -254,9 +257,9 @@ 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
+                                             \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 */
 
@@ -275,10 +278,10 @@ 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.
@@ -290,65 +293,33 @@ namespace log {
 
 #       ifndef DOXYGEN
 
-        template <class Stream> void route(
-            action_t action = ACCEPT, int index = -1);
-        template <class Stream, class Level> void route(
-            action_t action = ACCEPT, int index = -1,
-            typename boost::enable_if< boost::is_convertible<Level*,
-                                                             detail::LevelBase *> >::type * = 0);
-        template <class Stream, class Area> void route(
-            action_t action = ACCEPT, int index = -1,
-            typename boost::enable_if< boost::is_convertible<Area*,
-                                                             detail::AreaBase *> >::type * = 0);
-        template <class Stream, class AreaClass> void route(
-            action_t action = ACCEPT, int index = -1,
-            typename boost::enable_if< boost::is_convertible<typename AreaClass::SENFLogArea *,
-                                                             detail::AreaBase *> >::type * = 0);
-        template <class Stream, class Area, class Level> void route(
-            action_t action = ACCEPT, int index = -1,
-            typename boost::enable_if< boost::is_convertible<Area *,
-                                                             detail::AreaBase *> >::type * = 0);
-        template <class Stream, class AreaClass, class Level> void route(
-            action_t action = ACCEPT, int index = -1,
-            typename boost::enable_if< boost::is_convertible<typename AreaClass::SENFLogArea *,
-                                                             detail::AreaBase *> >::type * = 0);
-
-        template <class Stream> void unroute(
-            action_t action = ACCEPT);
-        template <class Stream, class Level> void unroute(
-            action_t action = ACCEPT,
-            typename boost::enable_if< boost::is_convertible<Level*,
-                                                             detail::LevelBase *> >::type * = 0);
-        template <class Stream, class Area> void unroute(
-            action_t action = ACCEPT,
-            typename boost::enable_if< boost::is_convertible<Area*,
-                                                             detail::AreaBase *> >::type * = 0);
-        template <class Stream, class AreaClass> void unroute(
-            action_t action = ACCEPT,
-            typename boost::enable_if< boost::is_convertible<typename AreaClass::SENFLogArea *,
-                                                             detail::AreaBase *> >::type * = 0);
-        template <class Stream, class Area, class Level> void unroute(
-            action_t action = ACCEPT,
-            typename boost::enable_if< boost::is_convertible<Area*,
-                                                             detail::AreaBase *> >::type * = 0);
-        template <class Stream, class AreaClass, class Level> void unroute(
-            action_t action = ACCEPT,
-            typename boost::enable_if< boost::is_convertible<typename AreaClass::SENFLogArea *,
-                                                             detail::AreaBase *> >::type * = 0);
+        template <class A1>
+        void route(action_t action = ACCEPT, int index = -1);
+        template <class A1, class A2>
+        void route(action_t action = ACCEPT, int index = -1);
+        template <class A1, class A2, class A3>
+        void route(action_t action = ACCEPT, int index = -1);
+
+        template <class A1>
+        void unroute(action_t action = ACCEPT);
+        template <class A1, class A2>
+        void unroute(action_t action = ACCEPT);
+        template <class A1, class A2, class A3>
+        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
@@ -361,21 +332,21 @@ namespace log {
 
         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);
 
 #   ifdef DOXYGEN
     protected:
 #   endif
 
-        virtual void v_write(boost::posix_time::ptime timestamp, std::string const & stream, 
+        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
@@ -383,7 +354,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
@@ -396,57 +367,9 @@ namespace log {
         RIB rib_;
         
         friend class detail::AreaBase;
+        friend class detail::TargetRegistry;
     };
 
-    /** \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////////////////////////////////////////