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