SNMP++  3.3.11
log.h
Go to the documentation of this file.
1 /*_############################################################################
2  _##
3  _## log.h
4  _##
5  _## SNMP++ v3.3
6  _## -----------------------------------------------
7  _## Copyright (c) 2001-2013 Jochen Katz, Frank Fock
8  _##
9  _## This software is based on SNMP++2.6 from Hewlett Packard:
10  _##
11  _## Copyright (c) 1996
12  _## Hewlett-Packard Company
13  _##
14  _## ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
15  _## Permission to use, copy, modify, distribute and/or sell this software
16  _## and/or its documentation is hereby granted without fee. User agrees
17  _## to display the above copyright notice and this license notice in all
18  _## copies of the software and any documentation of the software. User
19  _## agrees to assume all liability for the use of the software;
20  _## Hewlett-Packard and Jochen Katz make no representations about the
21  _## suitability of this software for any purpose. It is provided
22  _## "AS-IS" without warranty of any kind, either express or implied. User
23  _## hereby grants a royalty-free license to any and all derivatives based
24  _## upon this software code base.
25  _##
26  _##########################################################################*/
27 
28 #ifndef _SNMP_LOG_H_
29 #define _SNMP_LOG_H_
30 
31 #include <libsnmp.h>
32 #include <snmp_pp/config_snmp_pp.h>
33 #include <snmp_pp/reentrant.h>
34 
35 #ifndef WIN32
36 #include <sys/types.h>
37 #endif
38 #include <stdio.h>
39 #include <string.h>
40 
41 
42 #ifdef SNMP_PP_NAMESPACE
43 namespace Snmp_pp {
44 #endif
45 
46 // Log entry class
47 #define ERROR_LOG 0x10
48 #define WARNING_LOG 0x20
49 #define EVENT_LOG 0x30
50 #define INFO_LOG 0x40
51 #define DEBUG_LOG 0x50
52 #define USER_LOG 0x60
53 
54 #define LOG_CLASS_MASK 0xF0
55 #define LOG_LEVEL_MASK 0x0F
56 
57 #define LOG_TYPES 6
58 
59 #ifdef _NO_LOGGING
60 
61 #define LOG_BEGIN(name,level) (void)0
62 #define LOG(item) (void)0
63 #define LOG_END (void)0
64 
65 #define LOG_UNUSED(x)
66 
67 #else
68 
69 #define LOG_BEGIN(name,level) \
70 { \
71  if (DefaultLog::log()->log_needed(name,level)) \
72  { \
73  DefaultLog::lock(); \
74  DefaultLog::create_log_entry(name,level)
75 
76 #define LOG(item) *DefaultLog::log_entry() += item
77 
78 #define LOG_END \
79  *DefaultLog::log() += DefaultLog::log_entry(); \
80  DefaultLog::delete_log_entry(); \
81  DefaultLog::unlock(); \
82  } \
83 } \
84 (void)0
85 
86 #define LOG_UNUSED(x) x
87 
88 #endif
89 
90 
91 /*--------------------------- class LogEntry --------------------------*/
92 
93 /**
94  * The LogEntry class represents log entries. An instance of LogEntry can be
95  * added to a Log. Each LogEntry can be classified into the log classes
96  * ERROR_LOG, WARNING_LOG, EVENT_LOG, INFO_LOG, DEBUG_LOG and USER_LOG with up
97  * to 16 severity levels. A log entry consists of a descriptor string and
98  * optional several string or numeric values.
99  *
100  * The log class USER_LOG can be used for applications, it is not used
101  * within snmp++ and agent++.
102  *
103  * @note A error log of level 0 will stop program execution!
104  *
105  * @see Log
106  *
107  * @author Frank Fock
108  * @author Marty Janzen
109  * @version 3.6
110  */
111 
113 public:
114  /**
115  * Constructor with log class and severity level
116  *
117  * @param n - The name of the logging module
118  * @param t - The type of the log entry. The type is composed
119  * by a logical OR of the log entry class with a level
120  * of 0 up to 15.
121  * @note A error log of level 0 will stop program execution!
122  */
123  LogEntry(const char * const n, unsigned char t) : name(n), type(t), count(0) {}
124 
125  /**
126  * Virtual destructor.
127  */
128  virtual ~LogEntry() {}
129 
130  /**
131  * Initialize a new log entry, showing timestamp, class, and level.
132  */
133  virtual void init();
134 
135  /**
136  * Add a numeric value to the log entry.
137  *
138  * @param l - A numeric value.
139  */
140  virtual LogEntry& operator+=(const long l);
141 
142  /**
143  * Add a string value to the log entry.
144  *
145  * @param s - A string value.
146  */
147  virtual LogEntry& operator+=(const char* s);
148 
149  /**
150  * Get the contents of this log entry.
151  *
152  * @return Current contents of this log entry.
153  */
154  virtual const char* get_value() const { return ""; }
155 
156  /**
157  * Get the type of this log entry.
158  *
159  * @return Log entry type.
160  * @since 3.6
161  */
162  unsigned char get_type() const { return type; }
163 
164  /**
165  * Get the class of this log entry.
166  *
167  * @return Log entry class.
168  */
169  unsigned char get_class() const { return (unsigned char)(type & LOG_CLASS_MASK); }
170 
171  /**
172  * Get the level of this log entry.
173  *
174  * @return Log entry level.
175  */
176  unsigned char get_level() const { return (unsigned char)(type & LOG_LEVEL_MASK); }
177 
178  /**
179  * Get the logger name of this log entry.
180  *
181  * @return Log entry logger name
182  */
183  const char * get_name() const { return name; }
184 
185 protected:
186  /**
187  * Add a string to the log.
188  *
189  * @param s - A string value.
190  * @return TRUE if the value has been added and FALSE if the log
191  * entry is full.
192  */
193  virtual bool add_string(const char* s) = 0;
194 
195  /**
196  * Add an integer to the log.
197  *
198  * @param s - An integer value.
199  * @return TRUE if the value has been added and FALSE if the log
200  * entry is full.
201  */
202  virtual bool add_integer(long s);
203 
204  /**
205  * Add the current time to the log.
206  */
207  virtual bool add_timestamp();
208 
209 protected:
210  const char * const name;
211  unsigned char type;
212  int count;
213 };
214 
215 
216 /*------------------------- class LogEntryImpl ------------------------*/
217 
218 #define MAX_LOG_SIZE 2550 // increased until debugprintf is not used!
219 
220 /**
221  * The LogEntryImpl class implements a log entry using a dynamically
222  * allocated, but fixed-size buffer.
223  * @see Log
224  *
225  * @author Marty Janzen
226  * @version 3.6
227  */
228 
229 class DLLOPT LogEntryImpl : public LogEntry {
230 public:
231  /**
232  * Constructor with log class and severity level
233  *
234  * @param n - The name of the logging module
235  * @param t - The type of the log entry. The type is composed
236  * by logical or the log entry class with a level
237  * of 0 up to 15.
238  * @note A error log of level 0 will stop program execution!
239  */
240  LogEntryImpl(const char * const n, unsigned char t)
241  : LogEntry(n, t)
242  {
243  value = new char[MAX_LOG_SIZE];
244  value[0] = '\0';
245  ptr = value;
246  output_stopped = false;
247  }
248 
249  /**
250  * Destructor.
251  */
252  virtual ~LogEntryImpl()
253  {
254  delete [] value;
255  }
256 
257  /**
258  * Get the contents of this log entry.
259  *
260  * @return Current contents of this log entry.
261  */
262  virtual const char* get_value() const { return value; }
263 
264 protected:
265  /**
266  * Count the bytes left for additional values.
267  *
268  * @return The number of bytes left in this log entry.
269  */
270  unsigned int bytes_left()
271  { return (unsigned int)(MAX_LOG_SIZE-(ptr-value)-1); }
272 
273  /**
274  * Add a string to the log.
275  *
276  * @param s - A string value.
277  * @return TRUE if the value has been added and FALSE if the log
278  * entry is full.
279  */
280  bool add_string(const char* s);
281 
282 private:
283  char* value;
284  char* ptr;
286 };
287 
288 
289 /*--------------------------- class AgentLog --------------------------*/
290 
291 /**
292  * The AgentLog class is an abstract base class representing a log for
293  * information that is generated during the run time of an AGENT++
294  * SNMP agent. A derived class only needs to provide appropriate
295  * create_log_entry() and operator+= methods.
296  * @see LogEntry
297  *
298  * @author Frank Fock
299  * @version 3.6
300  */
301 
303 public:
304  /**
305  * Default constructor.
306  */
307  AgentLog();
308 
309  /**
310  * Virtual destructor.
311  */
312  virtual ~AgentLog() {}
313 
314 #ifdef WITH_LOG_PROFILES
315  /**
316  * Set a bunch of predefined filters for all log classes at once.
317  * Only available when built with WITH_LOG_PROFILES
318  *
319  * @param logprofile - name of a log profile, must be one of
320  * { "off", "quiet", "std", "events", "verbose", "full",
321  * "debug", "schwafel", "original" }
322  * In case a non-existant profile is chosen, "original" is used.
323  */
324  virtual void set_profile(const char * const logprofile);
325 #endif
326 
327  /**
328  * Set a filter on a specified log class. Only log entries with
329  * a level less or equal than the specified level will be logged.
330  *
331  * @param logclass - A log entry class. @see LogEntry
332  * @param filter - A value between 0 and 15.
333  */
334  virtual void set_filter(int logclass, unsigned char filter);
335 
336  /**
337  * Gets the log level for the given log class.
338  * @return
339  * a unsigned char value between 0 and 15
340  */
341  virtual unsigned char get_filter(int logclass) const;
342 
343  /**
344  * Create a new LogEntry.
345  *
346  * @param name - The name of the logging module
347  * @param t - The type of the log entry.
348  * @return A new instance of LogEntry (or of a derived class).
349  */
350  virtual LogEntry* create_log_entry(const char * const name, unsigned char t) const = 0;
351 
352  /**
353  * Add a LogEntry to the receiver Log.
354  *
355  * @param log - A log entry.
356  * @return The receiver log itself.
357  */
358  virtual AgentLog& operator+=(const LogEntry* log) = 0;
359 
360  /**
361  * Check whether a logging for the given type of LogEntry
362  * has to be done or not.
363  *
364  * @param t
365  * the type of the log entry. The type is composed
366  * by logical or the log entry class with a level
367  * of 0 up to 15.
368  * @return
369  * TRUE if logging is needed, FALSE otherwise.
370  */
371  virtual bool log_needed(const char * const, unsigned char t) const
372  { return (logfilter[(t / 16) - 1] != 0xFF) && ((t & LOG_LEVEL_MASK) <= logfilter[(t / 16) - 1]); }
373 
374  /**
375  * Return the current time as a string.
376  *
377  * @param buf
378  * a buffer (of at least 18 characters, for the default method)
379  * into which to place a string containg the current time.
380  * If no buffer is supplied, a static area is used.
381  * @return
382  * a string containing the current time. Either the supplied
383  * buffer or the static area.
384  */
385  virtual const char* now(char* buf = 0);
386 
387  /**
388  * Return the current time as a string, using the current
389  * default log object. (For backward compatibility.)
390  * @note that the user is responsible for deleting the returned
391  * string, using delete [].
392  *
393  * @return
394  * a string containg the current time.
395  */
396  static const char* get_current_time();
397 
398 protected:
399  unsigned char logfilter[LOG_TYPES];
400  char static_buf[18];
401 };
402 
403 
404 /*------------------------- class AgentLogImpl ------------------------*/
405 
406 /**
407  * The AgentLogImpl class is an implementation of AgentLog which writes
408  * log messages to a file, or to stdout or stderr.
409  * @see LogEntry
410  *
411  * @author Frank Fock
412  * @version 3.5f
413  */
414 
415 class DLLOPT AgentLogImpl : public AgentLog {
416 public:
417  /**
418  * Default constructor, with optional pointer to an open log file.
419  * Log is directed to the file if given, otherwise to stdout
420  *
421  * @param fp - An open log file. 0 implies stdout.
422  */
423  AgentLogImpl(FILE* fp = stdout);
424 
425  /**
426  * Constructor with file name of a log file. Log is directed
427  * to the given file.
428  *
429  * @param fname - The file name of a log file.
430  */
431  AgentLogImpl(const char* fname);
432 
433  /**
434  * Destructor.
435  */
436  ~AgentLogImpl();
437 
438  /**
439  * Set destination of logs to a given file.
440  *
441  * @param fname - A file name. "" directs logs to stdout.
442  */
443  void set_dest(const char* fname);
444 
445  /**
446  * Set destination of logs to a given file.
447  *
448  * @param fp - A pointer to an open file. 0 directs logs to stdout.
449  */
450  void set_dest(FILE* fp);
451 
452  /**
453  * Create a new LogEntry.
454  *
455  * @param name - The name of the logging module
456  * @param t - The type of the log entry.
457  * @return A new instance of LogEntry (or of a derived class).
458  */
459  virtual LogEntry* create_log_entry(const char * const name, unsigned char t) const;
460 
461  /**
462  * Add a LogEntry to the receiver Log.
463  *
464  * @param log - A log entry.
465  * @return The receiver log itself.
466  */
467  virtual AgentLog& operator+=(const LogEntry* log);
468 
469 protected:
470  FILE* logfile;
472 };
473 
474 
475 /*--------------------------- class DefaultLog --------------------------*/
476 
477 /**
478  * The DefaultLog class has a static Log member, that is used by the
479  * AGENT++ API for logging.
480  *
481  * @version 3.6
482  * @author Frank Fock (singleton pattern -> Philippe Roger)
483  */
484 
486 public:
489 
490  /**
491  * Initialize the default logger with the given logging implementation.
492  *
493  * @note Call cleanup function before the application exits
494  * @note The DefaultLog class takes ownership of the pointer. Do
495  * not delete it yourself.
496  * @note This method is NOT THREADSAFE. It must be called in main()
497  * before any logging takes place.
498  *
499  * @param logger
500  * an AgentLog instance to be used as default logger. A previously
501  * set logger will be deleted.
502  */
503  static void init(AgentLog* logger)
504  { lock(); if (instance) delete instance; instance = logger; unlock(); }
505 
506  /**
507  * Initialize the default logger with the given logging implementation
508  * if there is currently no logger instance set.
509  *
510  * @note Call cleanup function before the application exits
511  * @note The DefaultLog class takes ownership of the pointer. Do
512  * not delete it yourself.
513  * @note This method is THREADSAFE.
514  *
515  * @param logger
516  * an AgentLog instance to be used as default logger.
517  * @return
518  * the existing logger (if there was any) or the new logger pointer.
519  * @since 3.5.24
520  */
521  static AgentLog* init_ts(AgentLog* logger = NULL);
522 
523  /**
524  * Free the logging implementation.
525  * @note This method is THREADSAFE.
526  */
527  static void cleanup();
528 
529  /**
530  * Return the default logger.
531  *
532  * @return
533  * a pointer to an AgentLog instance.
534  */
535  static inline AgentLog* log()
536  {
537  AgentLog* r = instance;
538  if (!r)
539  r = init_ts();
540  return r;
541  }
542 
543  /**
544  * Create a new log entry or reuse an existing one.
545  *
546  * @param name - The name of the logging module
547  * @param type
548  * the type of the log entry as bitwise or of log class and level.
549  */
550  static void create_log_entry(const char *name, unsigned char type)
551  {
552  if (!entry)
553  {
554  entry = log()->create_log_entry(name, type);
555  entry->init();
556  }
557  }
558 
559  /**
560  * Return the current log entry. If there is none, an ERROR_LOG entry
561  * with level 1 will be created.
562  *
563  * @return
564  * a pointer to a LogEntry instance.
565  */
566  static LogEntry* log_entry()
567  {
568  if (!entry) {
569  create_log_entry("main", ERROR_LOG | 1);
570  }
571  return entry;
572  }
573 
574  /**
575  * Delete current log entry.
576  */
577  static void delete_log_entry()
578  {
579  if (entry)
580  delete entry;
581  entry = 0;
582  }
583 
584  /**
585  * Lock the log singleton.
586  */
587  static void lock()
588  {
589 #ifdef _THREADS
590  mutex.lock();
591 #endif
592  }
593 
594  /**
595  * Unlock the log singleton.
596  */
597  static void unlock()
598  {
599 #ifdef _THREADS
600  mutex.unlock();
601 #endif
602  }
603 
604 protected:
605 
607  static LogEntry* entry;
608 #ifdef _THREADS
610 #endif
611  static const char defaultName;
612 };
613 
614 #ifdef SNMP_PP_NAMESPACE
615 }
616 #endif
617 
618 #endif // _SNMP_LOG_H_
int count
Definition: log.h:212
virtual ~AgentLog()
Virtual destructor.
Definition: log.h:312
virtual const char * get_value() const
Get the contents of this log entry.
Definition: log.h:262
#define LOG_CLASS_MASK
Definition: log.h:54
static void unlock()
Unlock the log singleton.
Definition: log.h:597
unsigned char get_level() const
Get the level of this log entry.
Definition: log.h:176
char * value
Definition: log.h:283
static const char defaultName
Definition: log.h:611
unsigned char get_class() const
Get the class of this log entry.
Definition: log.h:169
LogEntry(const char *const n, unsigned char t)
Constructor with log class and severity level.
Definition: log.h:123
#define LOG_LEVEL_MASK
Definition: log.h:55
bool close_needed
Definition: log.h:471
#define DLLOPT
The LogEntry class represents log entries.
Definition: log.h:112
bool output_stopped
Definition: log.h:285
static LogEntry * entry
Definition: log.h:607
The LogEntryImpl class implements a log entry using a dynamically allocated, but fixed-size buffer...
Definition: log.h:229
static void create_log_entry(const char *name, unsigned char type)
Create a new log entry or reuse an existing one.
Definition: log.h:550
~DefaultLog()
Definition: log.h:488
const char *const name
Definition: log.h:210
static void lock()
Lock the log singleton.
Definition: log.h:587
static SnmpSynchronized mutex
Definition: log.h:609
FILE * logfile
Definition: log.h:470
static AgentLog * log()
Return the default logger.
Definition: log.h:535
DefaultLog()
Definition: log.h:487
virtual bool log_needed(const char *const, unsigned char t) const
Check whether a logging for the given type of LogEntry has to be done or not.
Definition: log.h:371
static void delete_log_entry()
Delete current log entry.
Definition: log.h:577
virtual ~LogEntryImpl()
Destructor.
Definition: log.h:252
LogEntryImpl(const char *const n, unsigned char t)
Constructor with log class and severity level.
Definition: log.h:240
#define MAX_LOG_SIZE
Definition: log.h:218
The AgentLogImpl class is an implementation of AgentLog which writes log messages to a file...
Definition: log.h:415
unsigned int bytes_left()
Count the bytes left for additional values.
Definition: log.h:270
unsigned char type
Definition: log.h:211
static AgentLog * instance
Definition: log.h:606
static void init(AgentLog *logger)
Initialize the default logger with the given logging implementation.
Definition: log.h:503
static LogEntry * log_entry()
Return the current log entry.
Definition: log.h:566
char * ptr
Definition: log.h:284
virtual ~LogEntry()
Virtual destructor.
Definition: log.h:128
unsigned char get_type() const
Get the type of this log entry.
Definition: log.h:162
const char * get_name() const
Get the logger name of this log entry.
Definition: log.h:183
The AgentLog class is an abstract base class representing a log for information that is generated dur...
Definition: log.h:302
#define LOG_TYPES
Definition: log.h:57
#define ERROR_LOG
Definition: log.h:47
The DefaultLog class has a static Log member, that is used by the AGENT++ API for logging...
Definition: log.h:485
virtual const char * get_value() const
Get the contents of this log entry.
Definition: log.h:154