1 /*_############################################################################
6 _## -----------------------------------------------
7 _## Copyright (c) 2001-2010 Jochen Katz, Frank Fock
9 _## This software is based on SNMP++2.6 from Hewlett Packard:
11 _## Copyright (c) 1996
12 _## Hewlett-Packard Company
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.
26 _## Stuttgart, Germany, Thu Sep 2 00:07:47 CEST 2010
28 _##########################################################################*/
35 #include <snmp_pp/config_snmp_pp.h>
36 #include <snmp_pp/reentrant.h>
39 #include <sys/types.h>
45 #ifdef SNMP_PP_NAMESPACE
50 #define ERROR_LOG 0x10
51 #define WARNING_LOG 0x20
52 #define EVENT_LOG 0x30
54 #define DEBUG_LOG 0x50
69 #define LOG_BEGIN(x) \
71 if (DefaultLog::log()->log_needed(x)) \
73 DefaultLog::log()->lock(); \
74 DefaultLog::create_log_entry(x);
76 #define LOG(x) *DefaultLog::log_entry() += x
79 *DefaultLog::log() += DefaultLog::log_entry(); \
80 DefaultLog::delete_log_entry(); \
81 DefaultLog::log()->unlock(); \
85 #define LOG_UNUSED(x) x
90 /*--------------------------- class LogEntry --------------------------*/
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.
99 * The log class USER_LOG can be used for applications, it is not used
100 * within snmp++ and agent++.
102 * @note A error log of level 0 will stop program execution!
107 * @author Marty Janzen
111 class DLLOPT LogEntry {
114 * Constructor with log class and severity level
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
119 * @note A error log of level 0 will stop program execution!
121 LogEntry(unsigned char t) : type(t), count(0) {}
124 * Virtual destructor.
126 virtual ~LogEntry() {}
129 * Initialize a new log entry, showing timestamp, class, and level.
131 virtual void init(void);
134 * Add a numeric value to the log entry.
136 * @param l - A numeric value.
138 virtual LogEntry& operator+=(const long);
141 * Add a string value to the log entry.
143 * @param l - A numeric value.
145 virtual LogEntry& operator+=(const char*);
148 * Get the contents of this log entry.
150 * @return Current contents of this log entry.
152 virtual const char* get_value(void) const { return ""; }
155 * Get the class of this log entry.
157 * @return Log entry class.
159 unsigned char get_class(void) const { return type & 0xF0; }
162 * Get the level of this log entry.
164 * @return Log entry level.
166 unsigned char get_level(void) const { return type & 0x0F; }
170 * Add a string to the log.
172 * @param s - A string value.
173 * @return TRUE if the value has been added and FALSE if the log
176 virtual bool add_string(const char*) = 0;
179 * Add an integer to the log.
181 * @param s - An integer value.
182 * @return TRUE if the value has been added and FALSE if the log
185 virtual bool add_integer(long);
188 * Add the current time to the log.
190 virtual bool add_timestamp(void);
198 /*------------------------- class LogEntryImpl ------------------------*/
200 #define MAX_LOG_SIZE 2550 // increased until debugprintf is not used!
203 * The LogEntryImpl class implements a log entry using a dynamically
204 * allocated, but fixed-size buffer.
207 * @author Marty Janzen
211 class DLLOPT LogEntryImpl : public LogEntry {
214 * Constructor with log class and severity level
216 * @param t - The type of the log entry. The type is composed
217 * by logical or the log entry class with a level
219 * @note A error log of level 0 will stop program execution!
221 LogEntryImpl(unsigned char);
229 * Get the contents of this log entry.
231 * @return Current contents of this log entry.
233 virtual const char* get_value(void) const { return value; }
237 * Count the bytes left for additional values.
239 * @return The number of bytes left in this log entry.
241 unsigned int bytes_left()
242 { return (unsigned int)(MAX_LOG_SIZE-(ptr-value)-1); }
245 * Add a string to the log.
247 * @param s - A string value.
248 * @return TRUE if the value has been added and FALSE if the log
251 bool add_string(const char*);
260 /*--------------------------- class AgentLog --------------------------*/
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.
273 class DLLOPT AgentLog {
276 * Default constructor.
281 * Virtual destructor.
283 virtual ~AgentLog() {}
286 * Lock the receiver. Default action is to perform no locking.
288 virtual void lock() {}
291 * Unlock the receiver. Default action is to perform no locking.
293 virtual void unlock() {}
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.
299 * @param logclass - A log entry class. @see LogEntry
300 * @param filter - A value between 0 and 15.
302 virtual void set_filter(int logclass, unsigned char filter);
305 * Gets the log level for the given log class.
307 * a unsigned char value between 0 and 15
309 virtual unsigned char get_filter(int logclass) const;
312 * Create a new LogEntry.
314 * @param t - The type of the log entry.
315 * @return A new instance of LogEntry (or of a derived class).
317 virtual LogEntry* create_log_entry(unsigned char) const = 0;
320 * Add a LogEntry to the receiver Log.
322 * @param log - A log entry.
323 * @return The receiver log itself.
325 virtual AgentLog& operator+=(const LogEntry*) = 0;
328 * Check whether a logging for the given type of LogEntry
329 * has to be done or not.
332 * the type of the log entry. The type is composed
333 * by logical or the log entry class with a level
336 * TRUE if logging is needed, FALSE otherwise.
338 virtual bool log_needed(unsigned char t)
339 { return ((t & 0x0F) <= logfilter[(t / 16) - 1]); }
342 * Return the current time as a string.
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.
349 * a string containing the current time. Either the supplied
350 * buffer or the static area.
352 virtual const char* now(char* = 0);
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 [].
361 * a string containg the current time.
363 static const char* get_current_time();
366 unsigned char logfilter[LOG_TYPES];
371 /*------------------------- class AgentLogImpl ------------------------*/
374 * The AgentLogImpl class is an implementation of AgentLog which writes
375 * log messages to a file, or to stdout or stderr.
382 class DLLOPT AgentLogImpl : public AgentLog {
385 * Default constructor, with optional pointer to an open log file.
386 * Log is directed to the file if given, otherwise to stdout
388 * @param fp - An open log file. 0 implies stdout.
390 AgentLogImpl(FILE* = stdout);
393 * Constructor with file name of a log file. Log is directed
396 * @param fname - The file name of a log file.
398 AgentLogImpl(const char*);
406 * Set destination of logs to a given file.
408 * @param fname - A file name. "" directs logs to stdout.
410 void set_dest(const char*);
413 * Set destination of logs to a given file.
415 * @param fp - A pointer to an open file. 0 directs logs to stdout.
417 void set_dest(FILE*);
430 * Unlock the receiver.
440 * Create a new LogEntry.
442 * @param t - The type of the log entry.
443 * @return A new instance of LogEntry (or of a derived class).
445 virtual LogEntry* create_log_entry(unsigned char) const;
448 * Add a LogEntry to the receiver Log.
450 * @param log - A log entry.
451 * @return The receiver log itself.
453 virtual AgentLog& operator+=(const LogEntry*);
456 SnmpSynchronized logLock;
462 /*--------------------------- class DefaultLog --------------------------*/
465 * The DefaultLog class has a static Log member, that is used by the
466 * AGENT++ API for logging.
469 * @author Frank Fock (singleton pattern -> Philippe Roger)
472 class DLLOPT DefaultLog {
478 * Initialize the default logger with the given logging implementation.
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.
487 * an AgentLog instance to be used as default logger. A previously
488 * set logger will be deleted.
490 static void init(AgentLog* logger)
491 { if (instance) delete instance; instance = logger; }
494 * Initialize the default logger with the given logging implementation
495 * if there is currently no logger instance set.
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.
503 * an AgentLog instance to be used as default logger.
505 * the existing logger (if there was any) or the new logger pointer.
508 static AgentLog* init_ts(AgentLog* logger);
511 * Free the logging implementation.
512 * @note This method is THREADSAFE.
514 static void cleanup();
517 * Return the default logger.
520 * a pointer to an AgentLog instance.
522 static AgentLog* log();
525 * Create a new log entry or reuse an existing one.
528 * the type of the log entry as bitwise or of log class and level.
530 static void create_log_entry(unsigned char t)
531 { if (!entry) { entry = log()->create_log_entry(t); entry->init();} }
534 * Return the current log entry. If there is none, an ERROR_LOG entry
535 * with level 1 will be created.
538 * a pointer to a LogEntry instance.
540 static LogEntry* log_entry()
541 { if (!entry) create_log_entry(ERROR_LOG | 1); return entry; }
544 * Delete current log entry.
546 static void delete_log_entry()
547 { if (entry) delete entry; entry = 0; }
551 static AgentLog* instance;
552 static LogEntry* entry;
553 static SnmpSynchronized mutex;
557 #ifdef SNMP_PP_NAMESPACE