Utils/Logger: Implement targets
[senf.git] / Utils / Logger / Target.hh
index 43ae954..9a47194 100644 (file)
 #define HH_Target_ 1
 
 // Custom includes
+#include <set>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/utility.hpp>
 #include "../singleton.hh"
-#include "Stream.hh"
-#include "Area.hh"
+#include "../mpl.hh"
+#include "StreamRegistry.hh"
+#include "AreaRegistry.hh"
 
 //#include "Target.mpp"
 ///////////////////////////////hh.p////////////////////////////////////////
 namespace senf {
 namespace log {
 
-    /** \brief
+    class TargetRegistry;
+
+    /** \brief Logging target base class
+
+        All enabled log messages are eventually routed to one or more logging targets. It is the
+        responsibility of the logging target to write the log messages somewhere: onto the console,
+        to a file, to mail them to the administrator or whatever. To this end, the logging target is
+        passed the log message and a complete set of logging parameters (\e stream, \e area and \e
+        level).
       */
-    class Target
-        : public senf::singleton<Target>
+    class Target : private boost::noncopyable
     {
     public:
         ///////////////////////////////////////////////////////////////////////////
@@ -50,19 +61,24 @@ namespace log {
         ///\name Structors and default members
         ///@{
 
+        Target();
         virtual ~Target();
 
-        // default default constructor
-        // default copy constructor
-        // default copy assignment
-        // default destructor
+        ///@}
 
-        // no conversion constructors
+        template <class Stream>
+        void route();
 
-        ///@}
+        template <class Stream, class Arg0>
+        void route();
+
+        template <class Stream, class Area, class Level>
+        void route();
 
     protected:
 
+        std::string timestamp();
+
     private:
 
         void route(detail::StreamBase const * stream, detail::AreaBase const * area, 
@@ -70,15 +86,30 @@ namespace log {
         void unroute(detail::StreamBase const * stream, detail::AreaBase const * area, 
                      unsigned level);
 
+        template <class Area>
+        void route(detail::StreamBase const * stream, detail::AreaBase const *);
+
+        template <class Level>
+        void route(detail::StreamBase const * stream, detail::LevelBase const *);
+
         void updateAreaCache(detail::AreaBase const & area, detail::StreamBase const * stream,
                              unsigned level);
 
-        void write(detail::StreamBase const & stream, detail::AreaBase const & area, 
-                   unsigned level, std::string const & message);
-        
-        virtual void v_write(std::string const & stream, std::string const & area, unsigned level,
+        void write(boost::posix_time::ptime 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, std::string const & stream, 
+                             std::string const & area, unsigned level, 
                              std::string const & message) = 0;
 
+#   ifdef DOXYGEN
+    private:
+#   endif
+
         struct RoutingEntry 
         {
             RoutingEntry(detail::StreamBase const * stream_, detail::AreaBase const * area_, 
@@ -98,14 +129,43 @@ namespace log {
         typedef std::vector<RoutingEntry> RIB;
 
         RIB rib_;
+        
+        friend class TargetRegistry;
+    };
+
+    /** \brief Target registry
+
+        The TargetRegistry keeps a record of all existing targets. 
+      */
+    class TargetRegistry
+        : public senf::singleton<TargetRegistry>
+    {
+    public:
+        using senf::singleton<TargetRegistry>::instance;
+
+        void write(detail::StreamBase const & stream, detail::AreaBase const & area,
+                   unsigned level, std::string msg);
+
+    private:
+        void registerTarget(Target * target);
+        void unregisterTarget(Target * target);
+
+        typedef std::set<Target *> Targets;
+        Targets targets_;
+        
+        friend class Target;
     };
 
+
+    template <class Stream, class Area, class Level>
+    void write(std::string msg);
+
 }}
 
 ///////////////////////////////hh.e////////////////////////////////////////
 #include "Target.cci"
 //#include "Target.ct"
-//#include "Target.cti"
+#include "Target.cti"
 #endif
 
 \f