/*_############################################################################ _## _## log.h _## _## SNMP++v3.2.23 _## ----------------------------------------------- _## Copyright (c) 2001-2007 Jochen Katz, Frank Fock _## _## This software is based on SNMP++2.6 from Hewlett Packard: _## _## Copyright (c) 1996 _## Hewlett-Packard Company _## _## ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS. _## Permission to use, copy, modify, distribute and/or sell this software _## and/or its documentation is hereby granted without fee. User agrees _## to display the above copyright notice and this license notice in all _## copies of the software and any documentation of the software. User _## agrees to assume all liability for the use of the software; _## Hewlett-Packard and Jochen Katz make no representations about the _## suitability of this software for any purpose. It is provided _## "AS-IS" without warranty of any kind, either express or implied. User _## hereby grants a royalty-free license to any and all derivatives based _## upon this software code base. _## _## Stuttgart, Germany, Sun Nov 11 15:10:59 CET 2007 _## _##########################################################################*/ #ifndef _log_h_ #define _log_h_ #include #include #ifndef WIN32 #include #endif #include #include #ifdef SNMP_PP_NAMESPACE namespace Snmp_pp { #endif // Log entry class #define ERROR_LOG 0x10 #define WARNING_LOG 0x20 #define EVENT_LOG 0x30 #define INFO_LOG 0x40 #define DEBUG_LOG 0x50 #define USER_LOG 0x60 #define LOG_TYPES 6 #ifdef _NO_LOGGING #define LOG_BEGIN(x) #define LOG(x) #define LOG_END #else #define LOG_BEGIN(x) \ { \ if (DefaultLog::log()->log_needed(x)) \ { \ DefaultLog::log()->lock(); \ DefaultLog::create_log_entry(x); #define LOG(x) *DefaultLog::log_entry() += x #define LOG_END \ *DefaultLog::log() += DefaultLog::log_entry(); \ DefaultLog::delete_log_entry(); \ DefaultLog::log()->unlock(); \ } \ } #endif /*--------------------------- class LogEntry --------------------------*/ /** * The LogEntry class represents log entries. An instance of LogEntry can be * added to a Log. Each LogEntry can be classified into the log classes * ERROR_LOG, WARNING_LOG, EVENT_LOG, INFO_LOG, DEBUG_LOG and USER_LOG with up * to 16 severity levels. A log entry consists of a descriptor string and * optional several string or numeric values. * * The log class USER_LOG can be used for applications, it is not used * within snmp++ and agent++. * * @see Log * * @author Frank Fock * @author Marty Janzen * @version 3.5f */ class DLLOPT LogEntry { public: /** * Constructor with log class and severity level * * @param t - The type of the log entry. The type is composed * by a logical OR of the log entry class with a level * of 0 up to 15. * @note A error log of level 0 will stop program execution! */ LogEntry(unsigned char t) : type(t), count(0) {} /** * Virtual destructor. */ virtual ~LogEntry() {} /** * Initialize a new log entry, showing timestamp, class, and level. */ virtual void init(void); /** * Add a numeric value to the log entry. * * @param l - A numeric value. */ virtual LogEntry& operator+=(const long); /** * Add a string value to the log entry. * * @param l - A numeric value. */ virtual LogEntry& operator+=(const char*); /** * Get the contents of this log entry. * * @return Current contents of this log entry. */ virtual const char* get_value(void) const { return ""; } /** * Get the class of this log entry. * * @return Log entry class. */ unsigned char get_class(void) const { return type & 0xF0; } /** * Get the level of this log entry. * * @return Log entry level. */ unsigned char get_level(void) const { return type & 0x0F; } protected: /** * Add a string to the log. * * @param s - A string value. * @return TRUE if the value has been added and FALSE if the log * entry is full. */ virtual bool add_string(const char*) = 0; /** * Add an integer to the log. * * @param s - An integer value. * @return TRUE if the value has been added and FALSE if the log * entry is full. */ virtual bool add_integer(long); /** * Add the current time to the log. */ virtual bool add_timestamp(void); protected: unsigned char type; int count; }; /*------------------------- class LogEntryImpl ------------------------*/ #define MAX_LOG_SIZE 2550 // increased until debugprintf is not used! /** * The LogEntryImpl class implements a log entry using a dynamically * allocated, but fixed-size buffer. * @see Log * * @author Marty Janzen * @version 3.5f */ class DLLOPT LogEntryImpl : public LogEntry { public: /** * Constructor with log class and severity level * * @param t - The type of the log entry. The type is composed * by logical or the log entry class with a level * of 0 up to 15. * @note A error log of level 0 will stop program execution! */ LogEntryImpl(unsigned char); /** * Destructor. */ ~LogEntryImpl(); /** * Get the contents of this log entry. * * @return Current contents of this log entry. */ virtual const char* get_value(void) const { return value; } protected: /** * Count the bytes left for additional values. * * @return The number of bytes left in this log entry. */ unsigned int bytes_left() { return (unsigned int)(MAX_LOG_SIZE-(ptr-value)-1); } /** * Add a string to the log. * * @param s - A string value. * @return TRUE if the value has been added and FALSE if the log * entry is full. */ bool add_string(const char*); private: char* value; char* ptr; bool output_stopped; }; /*--------------------------- class AgentLog --------------------------*/ /** * The AgentLog class is an abstract base class representing a log for * information that is generated during the run time of an AGENT++ * SNMP agent. A derived class only needs to provide appropriate * create_log_entry() and operator+= methods. * @see LogEntry * * @author Frank Fock * @version 3.5.14 */ class DLLOPT AgentLog { public: /** * Default constructor. */ AgentLog(); /** * Virtual destructor. */ virtual ~AgentLog() {} /** * Lock the receiver. Default action is to perform no locking. */ virtual void lock() {} /** * Unlock the receiver. Default action is to perform no locking. */ virtual void unlock() {} /** * Set a filter on a specified log class. Only log entries with * a level less or equal than the specified level will be logged. * * @param logclass - A log entry class. @see LogEntry * @param filter - A value between 0 and 15. */ virtual void set_filter(int logclass, unsigned char filter); /** * Gets the log level for the given log class. * @return * a unsigned char value between 0 and 15 */ virtual unsigned char get_filter(int logclass) const; /** * Create a new LogEntry. * * @param t - The type of the log entry. * @return A new instance of LogEntry (or of a derived class). */ virtual LogEntry* create_log_entry(unsigned char) const = 0; /** * Add a LogEntry to the receiver Log. * * @param log - A log entry. * @return The receiver log itself. */ virtual AgentLog& operator+=(const LogEntry*) = 0; /** * Check whether a logging for the given type of LogEntry * has to be done or not. * * @param type * the type of the log entry. The type is composed * by logical or the log entry class with a level * of 0 up to 15. * @return * TRUE if logging is needed, FALSE otherwise. */ virtual bool log_needed(unsigned char t) { return ((t & 0x0F) <= logfilter[(t / 16) - 1]); } /** * Return the current time as a string. * * @param * a buffer (of at least 18 characters, for the default method) * into which to place a string containg the current time. * If no buffer is supplied, a static area is used. * @return * a string containing the current time. Either the supplied * buffer or the static area. */ virtual const char* now(char* = 0); /** * Return the current time as a string, using the current * default log object. (For backward compatibility.) * @note that the user is responsible for deleting the returned * string, using delete []. * * @return * a string containg the current time. */ static const char* get_current_time(); protected: unsigned char logfilter[LOG_TYPES]; char static_buf[18]; }; /*------------------------- class AgentLogImpl ------------------------*/ /** * The AgentLogImpl class is an implementation of AgentLog which writes * log messages to a file, or to stdout or stderr. * @see LogEntry * * @author Frank Fock * @version 3.5f */ class DLLOPT AgentLogImpl : public AgentLog { public: /** * Default constructor, with optional pointer to an open log file. * Log is directed to the file if given, otherwise to stdout * * @param fp - An open log file. 0 implies stdout. */ AgentLogImpl(FILE* = stdout); /** * Constructor with file name of a log file. Log is directed * to the given file. * * @param fname - The file name of a log file. */ AgentLogImpl(const char*); /** * Destructor. */ ~AgentLogImpl(); /** * Set destination of logs to a given file. * * @param fname - A file name. "" directs logs to stdout. */ void set_dest(const char*); /** * Set destination of logs to a given file. * * @param fp - A pointer to an open file. 0 directs logs to stdout. */ void set_dest(FILE*); /** * Lock the receiver. */ void lock() { #ifdef _THREADS logLock.lock(); #endif } /** * Unlock the receiver. */ void unlock() { #ifdef _THREADS logLock.unlock(); #endif } /** * Create a new LogEntry. * * @param t - The type of the log entry. * @return A new instance of LogEntry (or of a derived class). */ virtual LogEntry* create_log_entry(unsigned char) const; /** * Add a LogEntry to the receiver Log. * * @param log - A log entry. * @return The receiver log itself. */ virtual AgentLog& operator+=(const LogEntry*); protected: SnmpSynchronized logLock; FILE* logfile; bool close_needed; }; /*--------------------------- class DefaultLog --------------------------*/ /** * The DefaultLog class has a static Log member, that is used by the * AGENT++ API for logging. * * @version 3.5.4 * @author Frank Fock (singlton pattern -> Philippe Roger) */ class DLLOPT DefaultLog { public: DefaultLog() { } ~DefaultLog() { } /** * Initialize the default logger with the given logging implementation. * * @param logger * an AgentLog instance to be used as default logger. A previously * set logger will be deleted. */ static void init(AgentLog* logger) { if (instance) delete instance; instance = logger; } /** * Return the default logger. * * @return * a pointer to an AgentLog instance. */ static AgentLog* log() { if (!instance) init(new AgentLogImpl()); return instance; } /** * Create a new log entry or reuse an existing one. * * @param type * the type of the log entry as bitwise or of log class and level. */ static void create_log_entry(unsigned char t) { if (!entry) { entry = log()->create_log_entry(t); entry->init();} } /** * Return the current log entry. If there is none, an ERROR_LOG entry * with level 1 will be created. * * @return * a pointer to a LogEntry instance. */ static LogEntry* log_entry() { if (!entry) create_log_entry(ERROR_LOG | 1); return entry; } /** * Delete current log entry. */ static void delete_log_entry() { if (entry) delete entry; entry = 0; } protected: static AgentLog* instance; static LogEntry* entry; }; #ifdef SNMP_PP_NAMESPACE } #endif #endif // _log_h_