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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*_############################################################################
  2.   _## 
  3.   _##  log.cpp  
  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 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 };
  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. }
  83. #ifdef LOG_INDENT
  84. // indent log by level
  85. for (int i=0; i<(type & 0x0F); i++) 
  86. add_string(" ");
  87. #endif
  88. }
  89. /**
  90.  * Add a string value to the log entry.
  91.  *
  92.  * @param l - A numeric value.
  93.  */
  94. LogEntry& LogEntry::operator+=(const char* s)
  95. {
  96. // The convention for Agent++ log messages is that the
  97. // timestamp, etc. is followed by the class and method name,
  98. // then by the list of arguments.
  99. if (count == 0) 
  100. add_string(s);
  101. else {
  102.   if (count == 1) 
  103. add_string(": ");
  104.   else 
  105. add_string(", ");
  106.   add_string("(");
  107.   add_string(s);
  108.   add_string(")");
  109. }
  110. count++;
  111. return *this;
  112. }
  113. /**
  114.  * Add a numeric value to the log entry.
  115.  *
  116.  * @param l - A numeric value.
  117.  */
  118. LogEntry& LogEntry::operator+=(const long l)
  119. {
  120. if (count == 1) 
  121. add_string(": ");
  122. else 
  123. add_string(", ");
  124. count++;
  125. add_string("(");
  126. add_integer(l);
  127. add_string(")");
  128. return *this;
  129. }
  130. /**
  131.  * Add an integer to the log.
  132.  *
  133.  * @param s - An integer value.
  134.  * @return TRUE if the value has been added and FALSE if the log
  135.  *         entry is full.
  136.  */
  137. bool LogEntry::add_integer(long l)
  138. {
  139. char buf[40];
  140. sprintf(buf, "%ld", l);
  141. return add_string(buf);
  142. }
  143. /**
  144.  * Add the current time to the log entry.
  145.  */
  146. bool LogEntry::add_timestamp(void)
  147. {
  148. return add_string(DefaultLog::log()->now());
  149. }
  150. /*------------------------- class LogEntryImpl ------------------------*/
  151. /**
  152.  * Constructor for the standard log entry implementation.
  153.  */  
  154. LogEntryImpl::LogEntryImpl(unsigned char t) : LogEntry(t)
  155. {
  156. value = new char[MAX_LOG_SIZE];
  157.         value[0] = '';
  158. ptr = value;
  159. output_stopped = FALSE;
  160. }
  161. /**
  162.  * Destructor for the standard log entry implementation.
  163.  */  
  164. LogEntryImpl::~LogEntryImpl()
  165. {
  166. delete [] value;
  167. }
  168. /**
  169.  * Add a string to the log.
  170.  *
  171.  * @param s - A string value.
  172.  * @return TRUE if the value has been added and FALSE if the log
  173.  *         entry is full.
  174.  */
  175. bool LogEntryImpl::add_string(const char* s)
  176. {
  177. if (output_stopped)
  178. return FALSE;
  179. size_t len = strlen(s);
  180. if (len <= bytes_left()) {
  181. strcat(ptr, s);
  182. ptr += len;
  183. return TRUE;
  184. }
  185. if (bytes_left() >= 3) {
  186. strcat(ptr, "...");
  187. ptr += 3;
  188. }
  189. output_stopped = TRUE;
  190. return FALSE;
  191. }
  192. /*-------------------------- class AgentLog ---------------------------*/
  193. /**
  194.  * Default constructor.
  195.  */
  196. AgentLog::AgentLog()
  197. {
  198. for (int i=0; i<LOG_TYPES; i++)
  199. logfilter[i] = default_logfilter[i];
  200. }
  201. void AgentLog::set_filter(int logclass, unsigned char filter)
  202. int idx = (logclass/16)-1;
  203. if ((idx >=0) && (idx <= LOG_TYPES) && (filter<16)) 
  204. logfilter[idx] = filter; 
  205. }
  206. unsigned char AgentLog::get_filter(int logclass) const
  207. {
  208. int idx = (logclass/16)-1;
  209. if ((idx >= 0) && (idx < LOG_TYPES)) { 
  210. return logfilter[idx]; 
  211. }
  212. return 0;
  213. }
  214. const char* AgentLog::now(char* buf)
  215. {
  216.         if (buf == NULL) buf = static_buf;
  217. time_t t;
  218. time(&t);
  219. strftime(buf, 18, "%Y%m%d.%H:%M:%S", localtime(&t));
  220. return buf;
  221. }
  222. /*static*/ const char* AgentLog::get_current_time() 
  223. {
  224. char* buf = new char[18];
  225.         strcpy(buf, DefaultLog::log()->now());
  226. return buf;
  227. }
  228. /*------------------------ class AgentLogImpl -------------------------*/
  229. /**
  230.  * Default constructor. Log is directed to stdout.
  231.  */
  232. AgentLogImpl::AgentLogImpl(FILE* fp) : AgentLog()
  233. {
  234. set_dest(fp);
  235. }
  236. /**
  237.  * Constructor with file name of a log file. Log is directed
  238.  * to the given file.
  239.  *
  240.  * @param fname - The file name of a log file.
  241.  */ 
  242. AgentLogImpl::AgentLogImpl(const char* fname) : AgentLog()
  243. {
  244. set_dest(fname);
  245. }
  246. /**
  247.  * Destructor.
  248.  */
  249. AgentLogImpl::~AgentLogImpl()
  250. {
  251. if (close_needed) fclose(logfile);
  252. }
  253. /**
  254.  * Set destination of logs to a given file.
  255.  * 
  256.  * @param fname - A file name. "" directs logs to stdout.
  257.  */
  258. void AgentLogImpl::set_dest(const char* fname)
  259. {
  260. close_needed = FALSE;
  261. if ((!fname) || (strlen(fname) == 0)) 
  262. logfile = stdout;
  263. else {
  264. logfile = fopen(fname, "a");
  265. if (logfile == NULL)
  266. logfile = stdout;
  267. else
  268. close_needed = TRUE;
  269. }
  270. }
  271. /**
  272.  * Set destination of logs to a given file.
  273.  * 
  274.  * @param fname - A pointer to an open log file. 0 directs logs to stdout.
  275.  */
  276. void AgentLogImpl::set_dest(FILE* fp)
  277. {
  278. logfile = fp ? fp : stdout;
  279. close_needed = FALSE;
  280. }
  281. /**
  282.  * Create a new LogEntry.
  283.  *
  284.  * @param t - The type of the log entry.
  285.  * @return A new instance of LogEntry (or of a derived class).
  286.  */
  287. LogEntry* AgentLogImpl::create_log_entry(unsigned char t) const
  288. {
  289. return new LogEntryImpl(t);
  290. }
  291. /**
  292.  * Add a LogEntry to the receiver Log.
  293.  *
  294.  * @param log - A log entry.
  295.  * @return The receiver log itself.
  296.  */
  297. AgentLog& AgentLogImpl::operator+=(const LogEntry* log)
  298. {
  299. fprintf(logfile, "%sn", log->get_value());
  300. // check if critical error
  301. if ((log->get_class() == ERROR_LOG) && (log->get_level() == 0))
  302. raise(SIGTERM);
  303. return *this;
  304. }
  305. // define the default logs
  306. #ifdef _THREADS
  307. #ifndef _WIN32THREADS
  308. #if !(defined (CPU) && CPU == PPC603)
  309. pthread_mutex_t logmutex = PTHREAD_MUTEX_INITIALIZER;
  310. #endif
  311. #endif
  312. #endif
  313. AgentLog* DefaultLog::instance = 0;
  314. LogEntry* DefaultLog::entry = 0;