log.cpp
上传用户:ets1996
上传日期:2014-09-30
资源大小:353k
文件大小:8k
源码类别:

SNMP编程

开发平台:

Visual C++

  1. /*_############################################################################
  2.   _## 
  3.   _##  log.cpp  
  4.   _##
  5.   _##  SNMP++v3.2.22
  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, Wed May  2 23:22:30 CEST 2007 
  27.   _##  
  28.   _##########################################################################*/
  29. #ifndef WIN32
  30. #include <unistd.h>
  31. #else
  32. #include <process.h>
  33. #endif
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <time.h>
  37. #include <signal.h>
  38. #include <string.h>
  39. #include <snmp_pp/log.h>
  40. #ifdef WIN32
  41. #ifdef __BCPLUSPLUS__
  42. #define _getpid getpid
  43. #endif
  44. #endif
  45. #if defined (CPU) && CPU == PPC603
  46. #include <taskLib.h>
  47. #endif
  48. #ifdef SNMP_PP_NAMESPACE
  49. using namespace Snmp_pp;
  50. #endif
  51. // default log filter: logs with level less or equal filter value are logged
  52. // error, warning, event, info, debug:
  53. static unsigned char default_logfilter[] = { 9, 9, 4, 6, 7, 15};
  54. #undef   LOG_INDENT
  55. /*--------------------------- class LogEntry --------------------------*/
  56.  /**
  57.   * Initialize a log entry, showing timestamp, class, and level.
  58.   * 
  59.   */  
  60. void LogEntry::init(void)
  61. {
  62. #ifdef WIN32
  63. int pid = _getpid();
  64. #elif defined (CPU) && CPU == PPC603
  65. int pid = taskIdSelf();
  66. #else
  67. int pid = getpid();
  68. #endif
  69. add_timestamp();
  70. add_string(": ");
  71. add_integer(pid);
  72. add_string(": ");
  73. char buf[20];
  74. sprintf(buf, "(%X)", get_level());
  75. add_string(buf);
  76. switch (type & 0xF0) {
  77. case DEBUG_LOG:   add_string("DEBUG  : "); break;
  78. case INFO_LOG:   add_string("INFO   : "); break;
  79. case WARNING_LOG: add_string("WARNING: "); break;
  80. case ERROR_LOG:   add_string("ERROR  : "); break;
  81. case EVENT_LOG:   add_string("EVENT  : "); break;
  82. case USER_LOG:   add_string("USER   : "); break;
  83. }
  84. #ifdef LOG_INDENT
  85. // indent log by level
  86. for (int i=0; i<(type & 0x0F); i++) 
  87. add_string(" ");
  88. #endif
  89. }
  90. /**
  91.  * Add a string value to the log entry.
  92.  *
  93.  * @param l - A numeric value.
  94.  */
  95. LogEntry& LogEntry::operator+=(const char* s)
  96. {
  97. // The convention for Agent++ log messages is that the
  98. // timestamp, etc. is followed by the class and method name,
  99. // then by the list of arguments.
  100. if (count == 0) 
  101. add_string(s);
  102. else {
  103.   if (count == 1) 
  104. add_string(": ");
  105.   else 
  106. add_string(", ");
  107.   add_string("(");
  108.   add_string(s);
  109.   add_string(")");
  110. }
  111. count++;
  112. return *this;
  113. }
  114. /**
  115.  * Add a numeric value to the log entry.
  116.  *
  117.  * @param l - A numeric value.
  118.  */
  119. LogEntry& LogEntry::operator+=(const long l)
  120. {
  121. if (count == 1) 
  122. add_string(": ");
  123. else 
  124. add_string(", ");
  125. count++;
  126. add_string("(");
  127. add_integer(l);
  128. add_string(")");
  129. return *this;
  130. }
  131. /**
  132.  * Add an integer to the log.
  133.  *
  134.  * @param s - An integer value.
  135.  * @return TRUE if the value has been added and FALSE if the log
  136.  *         entry is full.
  137.  */
  138. bool LogEntry::add_integer(long l)
  139. {
  140. char buf[40];
  141. sprintf(buf, "%ld", l);
  142. return add_string(buf);
  143. }
  144. /**
  145.  * Add the current time to the log entry.
  146.  */
  147. bool LogEntry::add_timestamp(void)
  148. {
  149. return add_string(DefaultLog::log()->now());
  150. }
  151. /*------------------------- class LogEntryImpl ------------------------*/
  152. /**
  153.  * Constructor for the standard log entry implementation.
  154.  */  
  155. LogEntryImpl::LogEntryImpl(unsigned char t) : LogEntry(t)
  156. {
  157. value = new char[MAX_LOG_SIZE];
  158.         value[0] = '';
  159. ptr = value;
  160. output_stopped = FALSE;
  161. }
  162. /**
  163.  * Destructor for the standard log entry implementation.
  164.  */  
  165. LogEntryImpl::~LogEntryImpl()
  166. {
  167. delete [] value;
  168. }
  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. bool LogEntryImpl::add_string(const char* s)
  177. {
  178. if (output_stopped)
  179. return FALSE;
  180. size_t len = strlen(s);
  181. if (len <= bytes_left()) {
  182. strcat(ptr, s);
  183. ptr += len;
  184. return TRUE;
  185. }
  186. if (bytes_left() >= 3) {
  187. strcat(ptr, "...");
  188. ptr += 3;
  189. }
  190. output_stopped = TRUE;
  191. return FALSE;
  192. }
  193. /*-------------------------- class AgentLog ---------------------------*/
  194. /**
  195.  * Default constructor.
  196.  */
  197. AgentLog::AgentLog()
  198. {
  199. for (int i=0; i<LOG_TYPES; i++)
  200. logfilter[i] = default_logfilter[i];
  201. }
  202. void AgentLog::set_filter(int logclass, unsigned char filter)
  203. int idx = (logclass/16)-1;
  204. if ((idx >=0) && (idx <= LOG_TYPES) && (filter<16)) 
  205. logfilter[idx] = filter; 
  206. }
  207. unsigned char AgentLog::get_filter(int logclass) const
  208. {
  209. int idx = (logclass/16)-1;
  210. if ((idx >= 0) && (idx < LOG_TYPES)) { 
  211. return logfilter[idx]; 
  212. }
  213. return 0;
  214. }
  215. const char* AgentLog::now(char* buf)
  216. {
  217.         if (buf == NULL) buf = static_buf;
  218. time_t t;
  219. time(&t);
  220. strftime(buf, 18, "%Y%m%d.%H:%M:%S", localtime(&t));
  221. return buf;
  222. }
  223. /*static*/ const char* AgentLog::get_current_time() 
  224. {
  225. char* buf = new char[18];
  226.         strcpy(buf, DefaultLog::log()->now());
  227. return buf;
  228. }
  229. /*------------------------ class AgentLogImpl -------------------------*/
  230. /**
  231.  * Default constructor. Log is directed to stdout.
  232.  */
  233. AgentLogImpl::AgentLogImpl(FILE* fp) : AgentLog()
  234. {
  235. set_dest(fp);
  236. }
  237. /**
  238.  * Constructor with file name of a log file. Log is directed
  239.  * to the given file.
  240.  *
  241.  * @param fname - The file name of a log file.
  242.  */ 
  243. AgentLogImpl::AgentLogImpl(const char* fname) : AgentLog()
  244. {
  245. set_dest(fname);
  246. }
  247. /**
  248.  * Destructor.
  249.  */
  250. AgentLogImpl::~AgentLogImpl()
  251. {
  252. if (close_needed) fclose(logfile);
  253. }
  254. /**
  255.  * Set destination of logs to a given file.
  256.  * 
  257.  * @param fname - A file name. "" directs logs to stdout.
  258.  */
  259. void AgentLogImpl::set_dest(const char* fname)
  260. {
  261. close_needed = FALSE;
  262. if ((!fname) || (strlen(fname) == 0)) 
  263. logfile = stdout;
  264. else {
  265. logfile = fopen(fname, "a");
  266. if (logfile == NULL)
  267. logfile = stdout;
  268. else
  269. close_needed = TRUE;
  270. }
  271. }
  272. /**
  273.  * Set destination of logs to a given file.
  274.  * 
  275.  * @param fname - A pointer to an open log file. 0 directs logs to stdout.
  276.  */
  277. void AgentLogImpl::set_dest(FILE* fp)
  278. {
  279. logfile = fp ? fp : stdout;
  280. close_needed = FALSE;
  281. }
  282. /**
  283.  * Create a new LogEntry.
  284.  *
  285.  * @param t - The type of the log entry.
  286.  * @return A new instance of LogEntry (or of a derived class).
  287.  */
  288. LogEntry* AgentLogImpl::create_log_entry(unsigned char t) const
  289. {
  290. return new LogEntryImpl(t);
  291. }
  292. /**
  293.  * Add a LogEntry to the receiver Log.
  294.  *
  295.  * @param log - A log entry.
  296.  * @return The receiver log itself.
  297.  */
  298. AgentLog& AgentLogImpl::operator+=(const LogEntry* log)
  299. {
  300. fprintf(logfile, "%sn", log->get_value());
  301. // check if critical error
  302. if ((log->get_class() == ERROR_LOG) && (log->get_level() == 0))
  303. raise(SIGTERM);
  304. return *this;
  305. }
  306. // define the default logs
  307. #ifdef _THREADS
  308. #ifndef _WIN32THREADS
  309. #if !(defined (CPU) && CPU == PPC603)
  310. pthread_mutex_t logmutex = PTHREAD_MUTEX_INITIALIZER;
  311. #endif
  312. #endif
  313. #endif
  314. AgentLog* DefaultLog::instance = 0;
  315. LogEntry* DefaultLog::entry = 0;