log.h
上传用户:cnryan
上传日期:2008-12-15
资源大小:260k
文件大小:12k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*_############################################################################
  2.   _## 
  3.   _##  log.h  
  4.   _##
  5.   _##  SNMP++v3.2.21
  6.   _##  -----------------------------------------------
  7.   _##  Copyright (c) 2001-2006 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, Fri Jun 16 17:48:57 CEST 2006 
  27.   _##  
  28.   _##########################################################################*/
  29. #ifndef _log_h_
  30. #define _log_h_
  31. #include <snmp_pp/config_snmp_pp.h>
  32. #include <snmp_pp/reentrant.h>
  33. #ifndef WIN32
  34. #include <sys/types.h>
  35. #endif
  36. #include <stdio.h>
  37. #include <string.h>
  38. #ifdef SNMP_PP_NAMESPACE
  39. namespace Snmp_pp {
  40. #endif
  41. // Log entry class
  42. #define ERROR_LOG 0x10
  43. #define WARNING_LOG 0x20
  44. #define EVENT_LOG 0x30
  45. #define INFO_LOG 0x40
  46. #define DEBUG_LOG 0x50
  47. #define LOG_TYPES       5
  48. #ifdef _NO_LOGGING
  49.  
  50. #define LOG_BEGIN(x)
  51. #define LOG(x)
  52. #define LOG_END
  53. #else
  54. #define LOG_BEGIN(x)
  55. {
  56. if (DefaultLog::log()->log_needed(x))
  57. {
  58. DefaultLog::log()->lock();
  59. DefaultLog::create_log_entry(x);
  60. #define LOG(x) *DefaultLog::log_entry() += x
  61. #define LOG_END
  62. *DefaultLog::log() += DefaultLog::log_entry();
  63. DefaultLog::delete_log_entry();
  64. DefaultLog::log()->unlock();
  65. }
  66. }
  67. #endif
  68. /*--------------------------- class LogEntry --------------------------*/
  69. /**
  70.  * The LogEntry class represents log entries. An instance of LogEntry can
  71.  * be added to a Log. Each LogEntry can be classified into the log classes
  72.  * ERROR_LOG, WARNING_LOG, EVENT_LOG, INFO_LOG, and DEBUG_LOG with up to
  73.  * 16 severity levels. A log entry consists of a descriptor string and
  74.  * optional several string or numeric values. 
  75.  * @see Log
  76.  * 
  77.  * @author Frank Fock
  78.  * @author Marty Janzen
  79.  * @version 3.5f
  80.  */
  81. class DLLOPT LogEntry {
  82. public:
  83. /**
  84.  * Constructor with log class and severity level
  85.  * 
  86.  * @param t - The type of the log entry. The type is composed 
  87.  *            by a logical OR of the log entry class with a level
  88.  *            of 0 up to 15. 
  89.  * @note A error log of level 0 will stop program execution!
  90.  */  
  91. LogEntry(unsigned char t) : type(t), count(0) {}
  92. /**
  93.  * Virtual destructor.
  94.  */  
  95. virtual ~LogEntry() {}
  96. /**
  97.  * Initialize a new log entry, showing timestamp, class, and level.
  98.  */ 
  99. virtual void init(void);
  100. /**
  101.  * Add a numeric value to the log entry.
  102.  *
  103.  * @param l - A numeric value.
  104.  */
  105. virtual LogEntry& operator+=(const long);
  106. /**
  107.  * Add a string value to the log entry.
  108.  *
  109.  * @param l - A numeric value.
  110.  */
  111. virtual LogEntry& operator+=(const char*);
  112. /**
  113.  * Get the contents of this log entry.
  114.          *
  115.  * @return Current contents of this log entry.
  116.  */ 
  117. virtual const char* get_value(void) const { return ""; }
  118. /**
  119.  * Get the class of this log entry.
  120.          *
  121.  * @return Log entry class.
  122.  */ 
  123. unsigned char get_class(void) const { return type & 0xF0; }
  124. /**
  125.  * Get the level of this log entry.
  126.          *
  127.  * @return Log entry level.
  128.  */ 
  129. unsigned char get_level(void) const { return type & 0x0F; }
  130. protected:
  131. /**
  132.  * Add a string to the log.
  133.  *
  134.  * @param s - A string value.
  135.  * @return TRUE if the value has been added and FALSE if the log
  136.  *         entry is full.
  137.  */
  138. virtual bool add_string(const char*) = 0;
  139. /**
  140.  * Add an integer to the log.
  141.  *
  142.  * @param s - An integer value.
  143.  * @return TRUE if the value has been added and FALSE if the log
  144.  *         entry is full.
  145.  */
  146. virtual bool add_integer(long);
  147. /**
  148.  * Add the current time to the log.
  149.  */
  150. virtual bool add_timestamp(void);
  151. protected:
  152. unsigned char   type;
  153. int count;
  154. };
  155. /*------------------------- class LogEntryImpl ------------------------*/
  156. #define MAX_LOG_SIZE 2550 // increased until debugprintf is not used!
  157. /**
  158.  * The LogEntryImpl class implements a log entry using a dynamically
  159.  * allocated, but fixed-size buffer.
  160.  * @see Log
  161.  * 
  162.  * @author Marty Janzen
  163.  * @version 3.5f
  164.  */
  165. class DLLOPT LogEntryImpl : public LogEntry {
  166. public:
  167. /**
  168.  * Constructor with log class and severity level
  169.  * 
  170.  * @param t - The type of the log entry. The type is composed 
  171.  *            by logical or the log entry class with a level
  172.  *            of 0 up to 15. 
  173.  * @note A error log of level 0 will stop program execution!
  174.  */  
  175. LogEntryImpl(unsigned char);
  176. /**
  177.  * Destructor.
  178.  */  
  179. ~LogEntryImpl();
  180. /**
  181.  * Get the contents of this log entry.
  182.          *
  183.  * @return Current contents of this log entry.
  184.  */ 
  185. virtual const char* get_value(void) const { return value; }
  186. protected:
  187. /**
  188.  * Count the bytes left for additional values.
  189.  *
  190.  * @return The number of bytes left in this log entry.
  191.  */  
  192. unsigned int bytes_left() 
  193.     { return (unsigned int)(MAX_LOG_SIZE-(ptr-value)-1); }
  194. /**
  195.  * Add a string to the log.
  196.  *
  197.  * @param s - A string value.
  198.  * @return TRUE if the value has been added and FALSE if the log
  199.  *         entry is full.
  200.  */
  201. bool add_string(const char*);
  202. private:
  203.         char* value;
  204. char* ptr;
  205. bool output_stopped;
  206. };
  207. /*--------------------------- class AgentLog --------------------------*/
  208. /**
  209.  * The AgentLog class is an abstract base class representing a log for
  210.  * information that is generated during the run time of an AGENT++
  211.  * SNMP agent.  A derived class only needs to provide appropriate
  212.  * create_log_entry() and operator+= methods.
  213.  * @see LogEntry
  214.  *
  215.  * @author Frank Fock
  216.  * @version 3.5.14
  217.  */
  218.  
  219. class DLLOPT AgentLog {
  220. public:
  221. /**
  222.  * Default constructor.
  223.  */ 
  224. AgentLog();
  225. /**
  226.  * Virtual destructor.
  227.  */
  228. virtual ~AgentLog() {}
  229. /**
  230.  * Lock the receiver.  Default action is to perform no locking.
  231.  */
  232. virtual void lock() {}
  233. /**
  234.  * Unlock the receiver.  Default action is to perform no locking.
  235.  */
  236. virtual void unlock() {}
  237. /**
  238.  * Set a filter on a specified log class. Only log entries with
  239.  * a level less or equal than the specified level will be logged.
  240.  *
  241.  * @param logclass - A log entry class. @see LogEntry
  242.  * @param filter - A value between 0 and 15.
  243.  */ 
  244. virtual void set_filter(int logclass, unsigned char filter);
  245. /**
  246.  * Gets the log level for the given log class.
  247.  * @return
  248.  *    a unsigned char value between 0 and 15 
  249.  */
  250. virtual unsigned char get_filter(int logclass) const; 
  251. /**
  252.  * Create a new LogEntry.
  253.  *
  254.  * @param t - The type of the log entry.
  255.  * @return A new instance of LogEntry (or of a derived class).
  256.  */
  257. virtual LogEntry* create_log_entry(unsigned char) const = 0;
  258. /**
  259.  * Add a LogEntry to the receiver Log.
  260.  *
  261.  * @param log - A log entry.
  262.  * @return The receiver log itself.
  263.  */
  264. virtual AgentLog& operator+=(const LogEntry*) = 0;
  265. /**
  266.  * Check whether a logging for the given type of LogEntry
  267.  * has to be done or not.
  268.  *
  269.  * @param type
  270.  *    the type of the log entry. The type is composed 
  271.  *    by logical or the log entry class with a level
  272.  *    of 0 up to 15.
  273.  * @return
  274.  *    TRUE if logging is needed, FALSE otherwise.
  275.  */
  276. virtual bool log_needed(unsigned char t) 
  277.   { return ((t & 0x0F) <= logfilter[(t / 16) - 1]); }
  278. /**
  279.  * Return the current time as a string.
  280.  * 
  281.  * @param
  282.  *    a buffer (of at least 18 characters, for the default method)
  283.          *    into which to place a string containg the current time.
  284.          *    If no buffer is supplied, a static area is used.
  285.  * @return
  286.  *    a string containing the current time. Either the supplied
  287.  *    buffer or the static area.
  288.  */
  289. virtual const char* now(char* = 0);
  290. /**
  291.  * Return the current time as a string, using the current
  292.          * default log object.  (For backward compatibility.)
  293.  * @note that the user is responsible for deleting the returned
  294.  * string, using delete [].
  295.  * 
  296.  * @return
  297.  *    a string containg the current time.
  298.  */
  299. static const char* get_current_time();
  300. protected:
  301. unsigned char logfilter[LOG_TYPES];
  302. char static_buf[18];
  303. };
  304. /*------------------------- class AgentLogImpl ------------------------*/
  305. /**
  306.  * The AgentLogImpl class is an implementation of AgentLog which writes
  307.  * log messages to a file, or to stdout or stderr.
  308.  * @see LogEntry 
  309.  *
  310.  * @author Frank Fock
  311.  * @version 3.5f
  312.  */
  313.  
  314. class DLLOPT AgentLogImpl : public AgentLog {
  315. public:
  316. /**
  317.  * Default constructor, with optional pointer to an open log file.
  318.          * Log is directed to the file if given, otherwise to stdout
  319.  *
  320.  * @param fp - An open log file.  0 implies stdout.
  321.  */ 
  322. AgentLogImpl(FILE* = stdout);
  323. /**
  324.  * Constructor with file name of a log file. Log is directed
  325.  * to the given file.
  326.  *
  327.  * @param fname - The file name of a log file.
  328.  */ 
  329. AgentLogImpl(const char*);
  330. /**
  331.  * Destructor.
  332.  */
  333. ~AgentLogImpl();
  334. /**
  335.  * Set destination of logs to a given file.
  336.  * 
  337.  * @param fname - A file name. "" directs logs to stdout.
  338.  */
  339. void set_dest(const char*);
  340. /**
  341.  * Set destination of logs to a given file.
  342.  * 
  343.  * @param fp - A pointer to an open file.  0 directs logs to stdout.
  344.  */
  345. void set_dest(FILE*);
  346. /**
  347.  * Lock the receiver.
  348.  */
  349. void lock()
  350. {
  351. #ifdef _THREADS
  352. logLock.lock();
  353. #endif
  354. }
  355. /**
  356.  * Unlock the receiver.
  357.  */
  358.  void unlock()
  359. {
  360. #ifdef _THREADS
  361. logLock.unlock();
  362. #endif
  363. }
  364. /**
  365.  * Create a new LogEntry.
  366.  *
  367.  * @param t - The type of the log entry.
  368.  * @return A new instance of LogEntry (or of a derived class).
  369.  */
  370. virtual LogEntry* create_log_entry(unsigned char) const;
  371. /**
  372.  * Add a LogEntry to the receiver Log.
  373.  *
  374.  * @param log - A log entry.
  375.  * @return The receiver log itself.
  376.  */
  377. virtual AgentLog& operator+=(const LogEntry*);
  378. protected:
  379. SnmpSynchronized logLock;
  380. FILE* logfile;
  381. bool close_needed;
  382. };
  383. /*--------------------------- class DefaultLog --------------------------*/
  384. /**
  385.  * The DefaultLog class has a static Log member, that is used by the
  386.  * AGENT++ API for logging.
  387.  *
  388.  * @version 3.5.4
  389.  * @author Frank Fock (singlton pattern -> Philippe Roger)
  390.  */  
  391. class DLLOPT DefaultLog {
  392. public:
  393. DefaultLog() { }
  394. ~DefaultLog() { }
  395. /** 
  396.  * Initialize the default logger with the given logging implementation.
  397.  *
  398.  * @param logger
  399.  *    an AgentLog instance to be used as default logger. A previously
  400.  *    set logger will be deleted.
  401.  */
  402. static void init(AgentLog* logger) 
  403.   { if (instance) delete instance; instance = logger; }
  404. /**
  405.  * Return the default logger. 
  406.  *
  407.  * @return
  408.  *    a pointer to an AgentLog instance.
  409.  */
  410. static AgentLog* log() 
  411.   { if (!instance) init(new AgentLogImpl()); return instance; }
  412. /**
  413.  * Create a new log entry or reuse an existing one.
  414.  *
  415.  * @param type
  416.  *    the type of the log entry as bitwise or of log class and level. 
  417.  */
  418. static void create_log_entry(unsigned char t)
  419.   { if (!entry) { entry = log()->create_log_entry(t); entry->init();} }
  420. /**
  421.  * Return the current log entry. If there is none, an ERROR_LOG entry
  422.  * with level 1 will be created.
  423.  *
  424.  * @return
  425.  *    a pointer to a LogEntry instance.
  426.  */
  427. static LogEntry* log_entry() 
  428.   { if (!entry) create_log_entry(ERROR_LOG | 1); return entry; } 
  429. /**
  430.  * Delete current log entry.
  431.  */
  432. static void delete_log_entry() 
  433.   { if (entry) delete entry; entry = 0; }
  434. protected:
  435. static AgentLog* instance;
  436. static LogEntry* entry;
  437. };
  438. #ifdef SNMP_PP_NAMESPACE
  439. }
  440. #endif
  441. #endif // _log_h_