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