Target.ih
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
14 /** \file
15  \brief Target internal header */
16 
17 #ifndef IH_SENF_Utils_Logger_Target_
18 #define IH_SENF_Utils_Logger_Target_ 1
19 
20 // Custom includes
21 #include <set>
22 #include <boost/type_traits/is_same.hpp>
23 #include <boost/static_assert.hpp>
24 #include <boost/shared_ptr.hpp>
25 #include <senf/Utils/singleton.hh>
26 #include <senf/Utils/mpl.hh>
27 #include <senf/Utils/Console/LazyDirectory.hh>
28 #include <senf/Utils/Console/Parse.hh>
29 
30 //-/////////////////////////////////////////////////////////////////////////////////////////////////
31 
32 namespace senf {
33 
34  namespace console { class DirectoryNode; }
35 
36 namespace log {
37 namespace detail {
38 
39  struct LogParameters {
40  StreamBase const * stream;
41  AreaBase const * area;
42  unsigned level;
43  void clear();
44  void setDefaults();
45  static LogParameters defaultParameters();
46  };
47 
48  std::ostream & operator<<(std::ostream & os, LogParameters const & pm);
49 
50  void senf_console_parse_argument(console::ParseCommandInfo::TokensRange const & tokens,
51  LogParameters & out);
52 
53  /** \brief Internal: Target registry */
54  class TargetRegistry
55  : public senf::singleton<TargetRegistry>
56  {
57  public:
58  enum Level {
59  VERBOSE = senf::log::VERBOSE::value,
60  NOTICE = senf::log::NOTICE::value,
61  MESSAGE = senf::log::MESSAGE::value,
62  IMPORTANT = senf::log::IMPORTANT::value,
63  CRITICAL = senf::log::CRITICAL::value,
64  FATAL = senf::log::FATAL::value
65  };
66 
67  using senf::singleton<TargetRegistry>::instance;
68 
69  void write(StreamBase const & stream, AreaBase const & area, unsigned level,
70  std::string const & msg);
71 
72  void routed();
73  bool fallbackRouting();
74 
75  senf::console::ScopedDirectory<> & consoleDir();
76 
77  void dynamicTarget(std::unique_ptr<Target> target);
78 
79  private:
80  TargetRegistry();
81  ~TargetRegistry();
82 
83  void registerTarget(Target * target, std::string const & name);
84  void unregisterTarget(Target * target);
85 
86  void consoleAreas(std::ostream & os);
87  void consoleStreams(std::ostream & os);
88  void consoleWrite(LogParameters parameters, std::string const & msg);
89  void consoleRemoveTarget(Target * target);
90  boost::shared_ptr<senf::console::DirectoryNode> consoleSelf(std::ostream & os);
91 
92  typedef std::set<Target *> Targets;
93  Targets targets_;
94 
95  bool fallbackRouting_;
96 
97  console::LazyDirectory consoleDir_;
98 
99  Targets dynamicTargets_;
100 
101  friend class senf::log::Target;
102  friend class senf::singleton<TargetRegistry>;
103  };
104 
105  /** \brief Internal: Write log message */
106  template <class Stream, class Area, class Level>
107  void write(std::string const & msg);
108 
109 #ifndef DOXYGEN
110 
111  // This code takes the routing target template arguments in any order and sorts them
112  // by type (Stream, Area and Level).
113 
114  senf::mpl::rv<0u> RouteParameterCheck_(...);
115  senf::mpl::rv<1u> RouteParameterCheck_(StreamBase *);
116  senf::mpl::rv<2u> RouteParameterCheck_(AreaBase *);
117  template <class T> senf::mpl::rv<3u> RouteParameterCheck_(T*, typename T::SENFLogArea * = 0);
118  senf::mpl::rv<4u> RouteParameterCheck_(LevelBase *);
119 
120  // For g++ 4.0 (at least) we need to provide the fully scoped name for this default value.
121  // no idea why. It works without the scope in 4.1
122  template < class T, class A2, class A1,
123  unsigned type = SENF_MPL_RV( senf::log::detail::RouteParameterCheck_(static_cast<T*>(0)) ) >
124  struct RouteParameters
125  {};
126 
127  template <class A2, class A1>
128  struct RouteParameters<mpl::nil,A2,A1,0u>
129  : public RouteParameters<A2,A1,mpl::nil>
130  {};
131 
132  struct NilLevel {
133  static unsigned const value = NONE::value;
134  };
135 
136  template <>
137  struct RouteParameters<mpl::nil,mpl::nil,mpl::nil,0u>
138  {
139  typedef mpl::nil Stream;
140  typedef mpl::nil Area;
141  typedef NilLevel Level;
142  };
143 
144  template <class T, class A2, class A1>
145  struct RouteParameters<T,A2,A1,1u>
146  : public RouteParameters<A2,A1,mpl::nil>
147  {
148  typedef RouteParameters<A2,A1,mpl::nil> base;
149  BOOST_STATIC_ASSERT(( boost::is_same<typename base::Stream, mpl::nil>::value ));
150  typedef T Stream;
151  };
152 
153  template <class T, class A2, class A1>
154  struct RouteParameters<T,A2,A1,2u>
155  : public RouteParameters<A2,A1,mpl::nil>
156  {
157  typedef RouteParameters<A2,A1,mpl::nil> base;
158  BOOST_STATIC_ASSERT(( boost::is_same<typename base::Area, mpl::nil>::value ));
159  typedef T Area;
160  };
161 
162  template <class T, class A2, class A1>
163  struct RouteParameters<T,A2,A1,3u>
164  : public RouteParameters<A2,A1,mpl::nil>
165  {
166  typedef RouteParameters<A2,A1,mpl::nil> base;
167  BOOST_STATIC_ASSERT(( boost::is_same<typename base::Area, mpl::nil>::value ));
168  typedef typename T::SENFLogArea Area;
169  };
170 
171  template <class T, class A2, class A1>
172  struct RouteParameters<T,A2,A1,4u>
173  : public RouteParameters<A2,A1,mpl::nil>
174  {
175  typedef RouteParameters<A2,A1,mpl::nil> base;
176  BOOST_STATIC_ASSERT(( boost::is_same<typename base::Level, NilLevel>::value ));
177  typedef T Level;
178  };
179 
180  template <class T, class RV>
181  struct InstanceP
182  {
183  static RV * value() { return & T::instance(); }
184  };
185 
186  template <class RV>
187  struct InstanceP<mpl::nil, RV>
188  {
189  static RV * value() { return 0; }
190  };
191 
192 #endif
193 
194 }}}
195 
196 //-/////////////////////////////////////////////////////////////////////////////////////////////////
197 #endif
198 
199 
200 // Local Variables:
201 // mode: c++
202 // fill-column: 100
203 // comment-column: 40
204 // c-file-style: "senf"
205 // indent-tabs-mode: nil
206 // ispell-local-dictionary: "american"
207 // compile-command: "scons -u test"
208 // End: