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