log.h 12 KB

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