Bugfix: More template-logging fixes
[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         \fixme optionally Integrate with Scheduler / ClockService to reduce number of gettimeofday()
55             calls.
56       */
57     class Target : private boost::noncopyable
58     {
59     public:
60         ///////////////////////////////////////////////////////////////////////////
61         // Types
62
63         ///////////////////////////////////////////////////////////////////////////
64         ///\name Structors and default members
65         ///@{
66
67         Target();
68         virtual ~Target();
69
70         ///@}
71
72         template <class Stream>
73         void route();
74
75         template <class Stream, class Arg0>
76         void route();
77
78         template <class Stream, class Area, class Level>
79         void route();
80
81     protected:
82
83         std::string timestamp();
84
85     private:
86
87         void route(detail::StreamBase const * stream, detail::AreaBase const * area, 
88                    unsigned level);
89         void unroute(detail::StreamBase const * stream, detail::AreaBase const * area, 
90                      unsigned level);
91
92         template <class Area>
93         void route(detail::StreamBase const * stream, detail::AreaBase const *);
94
95         template <class Level>
96         void route(detail::StreamBase const * stream, detail::LevelBase const *);
97
98         void updateAreaCache(detail::AreaBase const & area, detail::StreamBase const * stream,
99                              unsigned level);
100
101         void write(boost::posix_time::ptime timestamp, detail::StreamBase const & stream,
102                    detail::AreaBase const & area, unsigned level, std::string const & message);
103
104 #   ifdef DOXYGEN
105     protected:
106 #   endif
107
108         virtual void v_write(boost::posix_time::ptime, std::string const & stream, 
109                              std::string const & area, unsigned level, 
110                              std::string const & message) = 0;
111
112 #   ifdef DOXYGEN
113     private:
114 #   endif
115
116         struct RoutingEntry 
117         {
118             RoutingEntry(detail::StreamBase const * stream_, detail::AreaBase const * area_, 
119                          unsigned level_)
120                 : stream(stream_), area(area_), level(level_) {}
121             RoutingEntry() 
122                 : stream(0), area(0), level(0) {}
123
124             bool operator==(RoutingEntry const & other) 
125                 { return stream == other.stream && area == other.area && level == other.level; }
126
127             detail::StreamBase const * stream;
128             detail::AreaBase const * area;
129             unsigned level;
130         };
131
132         typedef std::vector<RoutingEntry> RIB;
133
134         RIB rib_;
135         
136         friend class TargetRegistry;
137     };
138
139     /** \brief Target registry
140
141         The TargetRegistry keeps a record of all existing targets. 
142       */
143     class TargetRegistry
144         : public senf::singleton<TargetRegistry>
145     {
146     public:
147         using senf::singleton<TargetRegistry>::instance;
148
149         void write(detail::StreamBase const & stream, detail::AreaBase const & area,
150                    unsigned level, std::string msg);
151
152     private:
153         void registerTarget(Target * target);
154         void unregisterTarget(Target * target);
155
156         typedef std::set<Target *> Targets;
157         Targets targets_;
158         
159         friend class Target;
160     };
161
162
163     template <class Stream, class Area, class Level>
164     void write(std::string msg);
165
166 }}
167
168 ///////////////////////////////hh.e////////////////////////////////////////
169 #include "Target.cci"
170 //#include "Target.ct"
171 #include "Target.cti"
172 #endif
173
174 \f
175 // Local Variables:
176 // mode: c++
177 // fill-column: 100
178 // comment-column: 40
179 // c-file-style: "senf"
180 // indent-tabs-mode: nil
181 // ispell-local-dictionary: "american"
182 // compile-command: "scons -u test"
183 // End: