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