MFMv2.0.10
Movable Feast Machine Simulator 2.0.10
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Logger.h
Go to the documentation of this file.
1 /* -*- mode:C++ -*-
2  Logger.h Configurable output logging system
3  Copyright (C) 2014 The Regents of the University of New Mexico. All rights reserved.
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License as published by the Free Software Foundation; either
8  version 2.1 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this library; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
18  USA
19 */
20 
28 #ifndef LOGGER_H
29 #define LOGGER_H
30 
31 #include "itype.h"
32 #include "ByteSink.h"
33 #include "ByteSerializable.h"
34 #include "Mutex.h"
35 #include <stdarg.h>
36 
37 namespace MFM
38 {
39 
44  class Logger
45  {
46  public:
47 
52  enum Level
53  {
54  NONE, // 'NONE' must remain 0 to avoid races from logging in static ctors
55  ERROR,
56  WARNING,
57  MESSAGE,
58  DEBUG,
59  DEBUG1,
60  DEBUG2,
61  DEBUG3,
62  ALL,
63 
64  MIN = NONE,
65  MAX = ALL
66  };
67 
75  static const char * StrLevel(Level l)
76  {
77  switch (l)
78  {
79  case NONE: return "NON";
80  case ERROR: return "ERR";
81  case WARNING: return "WRN";
82  case MESSAGE: return "MSG";
83  case DEBUG: return "DBG";
84  case DEBUG1: return "DB1";
85  case DEBUG2: return "DB2";
86  case DEBUG3: return "DB3";
87  case ALL: return "ALL";
88  default: return "UNK";
89  }
90  }
91 
101  static bool ValidLevel(s32 levelNumber)
102  {
103  return levelNumber >= MIN && levelNumber <= MAX;
104  }
105 
111  Level GetLevel() const
112  {
113  return m_logLevel;
114  }
115 
127  Level SetLevel(u32 newLevel)
128  {
129  return SetLevel((Level)newLevel);
130  }
131 
142  Level SetLevel(Level newLevel)
143  {
144  if (!ValidLevel(newLevel))
145  {
146  FAIL(ILLEGAL_ARGUMENT);
147  }
148 
149  if (newLevel == m_logLevel)
150  {
151  return m_logLevel;
152  }
153 
154  Level oldLevel = m_logLevel;
155 
156  Debug("[%s->%s]",StrLevel(m_logLevel),StrLevel(newLevel));
157  m_logLevel = newLevel;
158  Debug("[%s]",StrLevel(m_logLevel));
159 
160  return oldLevel;
161  }
162 
172  {
173  ByteSink * old = m_sink;
174  m_sink = &byteSink;
175  return old;
176  }
177 
186  Logger(ByteSink & sink, Level initialLevel) :
187  m_sink(&sink),
188  m_logLevel(initialLevel),
189  m_timeStamper(&m_defaultTimeStamper)
190  {
191  }
192 
193  ~Logger()
194  {
195  }
196 
206  bool IfLog(Level level)
207  {
208  return m_logLevel > NONE && level <= m_logLevel;
209  }
210 
221  bool Log(Level level, const char * format, ... )
222  {
223  va_list ap;
224  va_start(ap, format);
225  Vreport(level, format, ap);
226  va_end(ap);
227  return true;
228  }
229 
241  void Vreport(Level level, const char * format, va_list & ap)
242  {
243  if (IfLog(level))
244  {
245  Mutex::ScopeLock lock(m_mutex); // Hold lock for this block
246 
247  m_sink->Printf("%@%s: ",m_timeStamper, StrLevel(level));
248  m_sink->Vprintf(format, ap);
249  m_sink->Println();
250  }
251  }
252 
259  void Error(const char * format, ... )
260  {
261  va_list ap;
262  va_start(ap, format);
263  Vreport(ERROR, format, ap);
264  va_end(ap);
265  }
266 
273  void Warning(const char * format, ... )
274  {
275  va_list ap;
276  va_start(ap, format);
277  Vreport(WARNING, format, ap);
278  va_end(ap);
279  }
280 
287  void Message(const char * format, ... )
288  {
289  va_list ap;
290  va_start(ap, format);
291  Vreport(MESSAGE, format, ap);
292  va_end(ap);
293  }
294 
301  void Debug(const char * format, ... )
302  {
303  va_list ap;
304  va_start(ap, format);
305  Vreport(DEBUG, format, ap);
306  va_end(ap);
307  }
308 
317  {
318  m_timeStamper = stamper? stamper : &m_defaultTimeStamper;
319  m_defaultTimeStamper.Reset();
320  }
321 
322  private:
323  ByteSink * m_sink;
324  Level m_logLevel;
325 
330  Mutex m_mutex;
331 
332  class DefaultTimeStamper : public ByteSerializable
333  {
334  u32 m_calls;
335  public:
336  DefaultTimeStamper() : m_calls(0) { }
337  void Reset() { m_calls = 0; }
338  virtual Result PrintTo(ByteSink & byteSink, s32 argument = 0)
339  {
340  byteSink.Print(++m_calls, Format::LEX32);
341  byteSink.Print(": ");
342  return SUCCESS;
343  }
344  virtual Result ReadFrom(ByteSource & byteSource, s32 argument = 0)
345  {
346  return UNSUPPORTED;
347  }
348  } m_defaultTimeStamper;
349  ByteSerializable * m_timeStamper;
350 
351  };
352 
353  extern Logger LOG;
354 
355 } /* namespace MFM */
356 
357 #endif /*LOGGER_H*/
void Warning(const char *format,...)
Definition: Logger.h:273
Level SetLevel(u32 newLevel)
Definition: Logger.h:127
bool Log(Level level, const char *format,...)
Definition: Logger.h:221
Level
Definition: Logger.h:52
ByteSink * SetByteSink(ByteSink &byteSink)
Definition: Logger.h:171
Level SetLevel(Level newLevel)
Definition: Logger.h:142
void Error(const char *format,...)
Definition: Logger.h:259
Definition: Mutex.h:84
Definition: Format.h:49
Definition: Mutex.h:42
static const char * StrLevel(Level l)
Definition: Logger.h:75
Definition: ByteSink.h:47
bool IfLog(Level level)
Definition: Logger.h:206
Definition: Logger.h:44
void Debug(const char *format,...)
Definition: Logger.h:301
Logger(ByteSink &sink, Level initialLevel)
Definition: Logger.h:186
void Vreport(Level level, const char *format, va_list &ap)
Definition: Logger.h:241
Level GetLevel() const
Definition: Logger.h:111
void Message(const char *format,...)
Definition: Logger.h:287
void SetTimeStamper(ByteSerializable *stamper)
Definition: Logger.h:316
Definition: ByteSerializable.h:45
static bool ValidLevel(s32 levelNumber)
Definition: Logger.h:101