DCCL v3
logger.h
1 // Copyright 2009-2017 Toby Schneider (http://gobysoft.org/index.wt/people/toby)
2 // GobySoft, LLC (for 2013-)
3 // Massachusetts Institute of Technology (for 2007-2014)
4 // Community contributors (see AUTHORS file)
5 //
6 //
7 // This file is part of the Dynamic Compact Control Language Library
8 // ("DCCL").
9 //
10 // DCCL is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 2.1 of the License, or
13 // (at your option) any later version.
14 //
15 // DCCL is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with DCCL. If not, see <http://www.gnu.org/licenses/>.
22 #ifndef DCCLLOGGER20121009H
23 #define DCCLLOGGER20121009H
24 
25 #include <iostream>
26 #include <string>
27 #include <deque>
28 #include <iomanip>
29 #include <boost/signals2.hpp>
30 #include <cstdio>
31 
32 namespace dccl {
33  namespace logger {
35  enum Verbosity {
36  WARN = 1<<1,
37  INFO = 1<<2,
38  DEBUG1 = 1<<3,
39  DEBUG2 = 1<<4,
40  DEBUG3 = 1<<5,
41  ALL = DEBUG3 | (DEBUG3-1),
42  WARN_PLUS = WARN | (WARN - 1),
43  INFO_PLUS = INFO | (INFO - 1),
44  DEBUG1_PLUS = DEBUG1 | (DEBUG1 - 1),
45  DEBUG2_PLUS = DEBUG2 | (DEBUG2 - 1),
46  DEBUG3_PLUS = DEBUG3 | (DEBUG3 - 1)
47  };
48  enum Group
49  { GENERAL, ENCODE, DECODE, SIZE };
50 
51  }
52 
53 
54 
55  void to_ostream(const std::string& msg, dccl::logger::Verbosity vrb,
56  dccl::logger::Group grp, std::ostream* os, bool add_timestamp);
57 
58  namespace internal
59  {
60  class LogBuffer : public std::streambuf
61  {
62  public:
63  LogBuffer() : verbosity_(logger::INFO), group_(logger::GENERAL), buffer_(1) { }
64  ~LogBuffer() { }
65 
67  template <typename Slot>
68  void connect(int verbosity_mask, Slot slot) {
69  enabled_verbosities_ |= verbosity_mask;
70  if(verbosity_mask & logger::WARN) warn_signal.connect(slot);
71  if(verbosity_mask & logger::INFO) info_signal.connect(slot);
72  if(verbosity_mask & logger::DEBUG1) debug1_signal.connect(slot);
73  if(verbosity_mask & logger::DEBUG2) debug2_signal.connect(slot);
74  if(verbosity_mask & logger::DEBUG3) debug3_signal.connect(slot);
75  }
76 
77  void disconnect(int verbosity_mask) {
78  enabled_verbosities_ &= ~verbosity_mask;
79  if(verbosity_mask & logger::WARN) warn_signal.disconnect_all_slots();
80  if(verbosity_mask & logger::INFO) info_signal.disconnect_all_slots();
81  if(verbosity_mask & logger::DEBUG1) debug1_signal.disconnect_all_slots();
82  if(verbosity_mask & logger::DEBUG2) debug2_signal.disconnect_all_slots();
83  if(verbosity_mask & logger::DEBUG3) debug3_signal.disconnect_all_slots();
84  }
85 
87  void set_verbosity(logger::Verbosity verbosity)
88  { verbosity_ = verbosity; }
89 
90  void set_group(logger::Group group)
91  { group_ = group; }
92 
93 
94  bool contains(logger::Verbosity verbosity)
95  { return verbosity & enabled_verbosities_; }
96 
97 
98  private:
101  int sync();
102 
105  int overflow(int c = EOF);
106 
107 
108  void display(const std::string& s) {
109  if(verbosity_ & logger::WARN) warn_signal(s, logger::WARN, group_);
110  if(verbosity_ & logger::INFO) info_signal(s, logger::INFO, group_);
111  if(verbosity_ & logger::DEBUG1) debug1_signal(s, logger::DEBUG1, group_);
112  if(verbosity_ & logger::DEBUG2) debug2_signal(s, logger::DEBUG2, group_);
113  if(verbosity_ & logger::DEBUG3) debug3_signal(s, logger::DEBUG3, group_);
114  }
115 
116  private:
117  logger::Verbosity verbosity_;
118  logger::Group group_;
119  std::deque<std::string> buffer_;
120  int enabled_verbosities_; // mask of verbosity settings enabled
121 
122  typedef boost::signals2::signal<void (const std::string& msg, logger::Verbosity vrb, logger::Group grp)>
123  LogSignal;
124 
125  LogSignal warn_signal, info_signal, debug1_signal, debug2_signal, debug3_signal;
126 
127  };
128  }
129 
131  class Logger : public std::ostream {
132  public:
133  Logger() : std::ostream(&buf_) { }
134  virtual ~Logger() { }
135 
145  bool is(logger::Verbosity verbosity, logger::Group group = logger::GENERAL) {
146  if (!buf_.contains(verbosity)) {
147  return false;
148  } else {
149  buf_.set_verbosity(verbosity);
150  buf_.set_group(group);
151  return true;
152  }
153  }
154 
160  template<typename Slot>
161  void connect(int verbosity_mask, Slot slot) {
162  buf_.connect(verbosity_mask, slot);
163  }
164 
171  template<typename Obj>
172  void connect(
173  int verbosity_mask, Obj* obj,
174  void(Obj::*mem_func)(const std::string& msg, logger::Verbosity vrb, logger::Group grp))
175  {
176 #if BOOST_VERSION >= 106000
177  using boost::placeholders::_1;
178  using boost::placeholders::_2;
179  using boost::placeholders::_3;
180 #endif
181  connect(verbosity_mask, boost::bind(mem_func, obj, _1, _2, _3));
182  }
183 
189  void connect(int verbosity_mask, std::ostream* os,
190  bool add_timestamp = true)
191  {
192 #if BOOST_VERSION >= 106000
193  using boost::placeholders::_1;
194  using boost::placeholders::_2;
195  using boost::placeholders::_3;
196 #endif
197  buf_.connect(verbosity_mask, boost::bind(to_ostream, _1, _2, _3, os, add_timestamp));
198  }
199 
201  void disconnect(int verbosity_mask)
202  { buf_.disconnect(verbosity_mask); }
203 
204  private:
205  internal::LogBuffer buf_;
206 
207  };
208 
209  extern Logger dlog;
210 }
211 
212 #endif // DCCLLOGGER20121009H
dccl::Logger::connect
void connect(int verbosity_mask, std::ostream *os, bool add_timestamp=true)
Connect the output of one or more given verbosities to a std::ostream.
Definition: logger.h:189
dccl
Dynamic Compact Control Language namespace.
Definition: gen_units_class_plugin.h:49
dccl::Logger::is
bool is(logger::Verbosity verbosity, logger::Group group=logger::GENERAL)
Indicates the verbosity of the Logger until the next std::flush or std::endl. The boolean return is u...
Definition: logger.h:145
dccl::internal::LogBuffer::set_verbosity
void set_verbosity(logger::Verbosity verbosity)
sets the verbosity level until the next sync()
Definition: logger.h:87
dccl::Logger
The DCCL Logger class. Do not instantiate this class directly. Rather, use the dccl::dlog object.
Definition: logger.h:131
dccl::internal::LogBuffer
Definition: logger.h:60
dccl::internal::LogBuffer::connect
void connect(int verbosity_mask, Slot slot)
connect a signal to a slot (function pointer or similar)
Definition: logger.h:68
dccl::Logger::connect
void connect(int verbosity_mask, Slot slot)
Connect the output of one or more given verbosities to a slot (function pointer or similar)
Definition: logger.h:161
dccl::Logger::connect
void connect(int verbosity_mask, Obj *obj, void(Obj::*mem_func)(const std::string &msg, logger::Verbosity vrb, logger::Group grp))
Connect the output of one or more given verbosities to a member function.
Definition: logger.h:172
dccl::Logger::disconnect
void disconnect(int verbosity_mask)
Disconnect all slots for one or more given verbosities.
Definition: logger.h:201