Utils/Logger: Implement targets
[senf.git] / Utils / Logger / Target.hh
1 // $Id$
2 //
3 // Copyright (C) 2007 
4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief Target public header */
25
26 #ifndef HH_Target_
27 #define HH_Target_ 1
28
29 // Custom includes
30 #include <set>
31 #include <boost/date_time/posix_time/posix_time.hpp>
32 #include <boost/utility.hpp>
33 #include "../singleton.hh"
34 #include "../mpl.hh"
35 #include "StreamRegistry.hh"
36 #include "AreaRegistry.hh"
37
38 //#include "Target.mpp"
39 ///////////////////////////////hh.p////////////////////////////////////////
40
41 namespace senf {
42 namespace log {
43
44     class TargetRegistry;
45
46     /** \brief Logging target base class
47
48         All enabled log messages are eventually routed to one or more logging targets. It is the
49         responsibility of the logging target to write the log messages somewhere: onto the console,
50         to a file, to mail them to the administrator or whatever. To this end, the logging target is
51         passed the log message and a complete set of logging parameters (\e stream, \e area and \e
52         level).
53       */
54     class Target : private boost::noncopyable
55     {
56     public:
57         ///////////////////////////////////////////////////////////////////////////
58         // Types
59
60         ///////////////////////////////////////////////////////////////////////////
61         ///\name Structors and default members
62         ///@{
63
64         Target();
65         virtual ~Target();
66
67         ///@}
68
69         template <class Stream>
70         void route();
71
72         template <class Stream, class Arg0>
73         void route();
74
75         template <class Stream, class Area, class Level>
76         void route();
77
78     protected:
79
80         std::string timestamp();
81
82     private:
83
84         void route(detail::StreamBase const * stream, detail::AreaBase const * area, 
85                    unsigned level);
86         void unroute(detail::StreamBase const * stream, detail::AreaBase const * area, 
87                      unsigned level);
88
89         template <class Area>
90         void route(detail::StreamBase const * stream, detail::AreaBase const *);
91
92         template <class Level>
93         void route(detail::StreamBase const * stream, detail::LevelBase const *);
94
95         void updateAreaCache(detail::AreaBase const & area, detail::StreamBase const * stream,
96                              unsigned level);
97
98         void write(boost::posix_time::ptime timestamp, detail::StreamBase const & stream,
99                    detail::AreaBase const & area, unsigned level, std::string const & message);
100
101 #   ifdef DOXYGEN
102     protected:
103 #   endif
104
105         virtual void v_write(boost::posix_time::ptime, std::string const & stream, 
106                              std::string const & area, unsigned level, 
107                              std::string const & message) = 0;
108
109 #   ifdef DOXYGEN
110     private:
111 #   endif
112
113         struct RoutingEntry 
114         {
115             RoutingEntry(detail::StreamBase const * stream_, detail::AreaBase const * area_, 
116                          unsigned level_)
117                 : stream(stream_), area(area_), level(level_) {}
118             RoutingEntry() 
119                 : stream(0), area(0), level(0) {}
120
121             bool operator==(RoutingEntry const & other) 
122                 { return stream == other.stream && area == other.area && level == other.level; }
123
124             detail::StreamBase const * stream;
125             detail::AreaBase const * area;
126             unsigned level;
127         };
128
129         typedef std::vector<RoutingEntry> RIB;
130
131         RIB rib_;
132         
133         friend class TargetRegistry;
134     };
135
136     /** \brief Target registry
137
138         The TargetRegistry keeps a record of all existing targets. 
139       */
140     class TargetRegistry
141         : public senf::singleton<TargetRegistry>
142     {
143     public:
144         using senf::singleton<TargetRegistry>::instance;
145
146         void write(detail::StreamBase const & stream, detail::AreaBase const & area,
147                    unsigned level, std::string msg);
148
149     private:
150         void registerTarget(Target * target);
151         void unregisterTarget(Target * target);
152
153         typedef std::set<Target *> Targets;
154         Targets targets_;
155         
156         friend class Target;
157     };
158
159
160     template <class Stream, class Area, class Level>
161     void write(std::string msg);
162
163 }}
164
165 ///////////////////////////////hh.e////////////////////////////////////////
166 #include "Target.cci"
167 //#include "Target.ct"
168 #include "Target.cti"
169 #endif
170
171 \f
172 // Local Variables:
173 // mode: c++
174 // fill-column: 100
175 // comment-column: 40
176 // c-file-style: "senf"
177 // indent-tabs-mode: nil
178 // ispell-local-dictionary: "american"
179 // compile-command: "scons -u test"
180 // End: