cache.cpp

00001
00002 /***************************************************************************
00003  *  cache.cpp - Fawkes cache logger
00004  *
00005  *  Created: Wed Feb 11 23:02:08 2009
00006  *  Copyright  2006-2009  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version. A runtime exception applies to
00014  *  this software (see LICENSE.GPL_WRE file mentioned below for details).
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU Library General Public License for more details.
00020  *
00021  *  Read the full text in the LICENSE.GPL_WRE file in the doc directory.
00022  */
00023
00024 #include <core/threading/mutex.h>
00025 #include <utils/logging/cache.h>
00026
00027 #include <cstdlib>
00028 #include <sys/time.h>
00029 #include <ctime>
00030 #include <cstdio>
00031
00032 #define TIMESTR_LENGTH 200
00033 #define MESSAGE_LENGTH 4096
00034 
00035 namespace fawkes {
00036 #if 0 /* just to make Emacs auto-indent happy */
00037 }
00038 #endif
00039 
00040 /** @class CacheLogger <utils/logging/cache.h>
00041  * Logging Cache.
00042  * The CacheLogger will cache the log messages. By default these are
00043  * 20 messages.
00044  * @author Tim Niemueller
00045  */
00046 
00047 /** Constructor.
00048  * @param num_entries number of entries in the cache, if the cache is full and a
00049  * new log message arrives the oldest message is erased.
00050  * @param log_level minimum level to log
00051  */
00052 CacheLogger::CacheLogger(unsigned int num_entries, LogLevel log_level)
00053   : Logger(log_level)
00054 {
00055   __max_num_entries = num_entries;
00056   __num_entries = 0;
00057
00058   now_s = (struct ::tm *)malloc(sizeof(struct ::tm));
00059   mutex = new Mutex();
00060 }
00061 
00062 /** Destructor. */
00063 CacheLogger::~CacheLogger()
00064 {
00065   free(now_s);
00066   delete mutex;
00067 }
00068
00069 std::list<CacheLogger::CacheEntry> &
00070 CacheLogger::get_messages()
00071 {
00072   return __messages;
00073 }
00074
00075 void
00076 CacheLogger::clear()
00077 {
00078   mutex->lock();
00079   __num_entries = 0;
00080   __messages.clear();
00081   mutex->unlock();
00082 }
00083
00084 void
00085 CacheLogger::push_message(LogLevel ll, const char *component, const char *format, va_list va)
00086 {
00087   if (log_level <= ll ) {
00088     struct timeval now;
00089     gettimeofday(&now, NULL);
00090     mutex->lock();
00091     localtime_r(&now.tv_sec, now_s);
00092     char timestr[TIMESTR_LENGTH];
00093     snprintf(timestr, TIMESTR_LENGTH, "%02d:%02d:%02d.%06ld", now_s->tm_hour,
00094              now_s->tm_min, now_s->tm_sec, now.tv_usec);
00095     char msg[MESSAGE_LENGTH];
00096     vsnprintf(msg, MESSAGE_LENGTH, format, va);
00097
00098     CacheEntry e;
00099     e.log_level = ll;
00100     e.component = component;
00101     e.time      = now;
00102     e.timestr   = timestr;
00103     e.message   = msg;
00104     __messages.push_front(e);
00105
00106     if (__num_entries == __max_num_entries) {
00107       __messages.pop_back();
00108     } else {
00109       ++__num_entries;
00110     }
00111     mutex->unlock();
00112   }
00113 }
00114
00115 void
00116 CacheLogger::push_message(LogLevel ll, const char *component, Exception &e)
00117 {
00118   if (log_level <= ll ) {
00119     struct timeval now;
00120     gettimeofday(&now, NULL);
00121     mutex->lock();
00122     localtime_r(&now.tv_sec, now_s);
00123     char timestr[TIMESTR_LENGTH];
00124     snprintf(timestr, TIMESTR_LENGTH, "%02d:%02d:%02d.%06ld",
00125              now_s->tm_hour, now_s->tm_min, now_s->tm_sec, now.tv_usec);
00126
00127     for (Exception::iterator i = e.begin(); i != e.end(); ++i) {
00128       CacheEntry e;
00129       e.log_level = ll;
00130       e.component = component;
00131       e.time      = now;
00132       e.timestr   = timestr;
00133       e.message   = std::string("[EXCEPTION] ") + *i;
00134       __messages.push_front(e);
00135     }
00136
00137     if (__num_entries == __max_num_entries) {
00138       __messages.pop_back();
00139     } else {
00140       ++__num_entries;
00141     }
00142     mutex->unlock();
00143   }
00144 }
00145
00146 void
00147 CacheLogger::vlog_debug(const char *component, const char *format, va_list va)
00148 {
00149   push_message(LL_DEBUG, component, format, va);
00150 }
00151
00152 void
00153 CacheLogger::vlog_info(const char *component, const char *format, va_list va)
00154 {
00155   push_message(LL_INFO, component, format, va);
00156 }
00157
00158 void
00159 CacheLogger::vlog_warn(const char *component, const char *format, va_list va)
00160 {
00161   push_message(LL_WARN, component, format, va);
00162 }
00163
00164 void
00165 CacheLogger::vlog_error(const char *component, const char *format, va_list va)
00166 {
00167   push_message(LL_ERROR, component, format, va);
00168 }
00169
00170 void
00171 CacheLogger::log_debug(const char *component, const char *format, ...)
00172 {
00173   va_list arg;
00174   va_start(arg, format);
00175   push_message(LL_DEBUG, component, format, arg);
00176   va_end(arg);
00177 }
00178
00179 void
00180 CacheLogger::log_info(const char *component, const char *format, ...)
00181 {
00182   va_list arg;
00183   va_start(arg, format);
00184   push_message(LL_INFO, component, format, arg);
00185   va_end(arg);
00186 }
00187
00188 void
00189 CacheLogger::log_warn(const char *component, const char *format, ...)
00190 {
00191   va_list arg;
00192   va_start(arg, format);
00193   push_message(LL_WARN, component, format, arg);
00194   va_end(arg);
00195 }
00196
00197 void
00198 CacheLogger::log_error(const char *component, const char *format, ...)
00199 {
00200   va_list arg;
00201   va_start(arg, format);
00202   push_message(LL_ERROR, component, format, arg);
00203   va_end(arg);
00204 }
00205
00206 void
00207 CacheLogger::log_debug(const char *component, Exception &e)
00208 {
00209   push_message(LL_DEBUG, component, e);
00210 }
00211
00212 void
00213 CacheLogger::log_info(const char *component, Exception &e)
00214 {
00215   push_message(LL_INFO, component, e);
00216 }
00217
00218 void
00219 CacheLogger::log_warn(const char *component, Exception &e)
00220 {
00221   push_message(LL_WARN, component, e);
00222 }
00223
00224 void
00225 CacheLogger::log_error(const char *component, Exception &e)
00226 {
00227   push_message(LL_ERROR, component, e);
00228 }
00229
00230 void
00231 CacheLogger::tlog_push_message(LogLevel ll, struct timeval *t, const char *component,
00232                           const char *format, va_list va)
00233 {
00234   if (log_level <= ll ) {
00235     mutex->lock();
00236     localtime_r(&t->tv_sec, now_s);
00237     char timestr[TIMESTR_LENGTH];
00238     snprintf(timestr, TIMESTR_LENGTH, "%02d:%02d:%02d.%06ld", now_s->tm_hour,
00239              now_s->tm_min, now_s->tm_sec, t->tv_usec);
00240     char msg[MESSAGE_LENGTH];
00241     vsnprintf(msg, MESSAGE_LENGTH, format, va);
00242
00243     CacheEntry e;
00244     e.log_level = ll;
00245     e.component = component;
00246     e.time      = *t;
00247     e.timestr   = timestr;
00248     e.message   = msg;
00249     __messages.push_front(e);
00250
00251     if (__num_entries == __max_num_entries) {
00252       __messages.pop_back();
00253     } else {
00254       ++__num_entries;
00255     }
00256     mutex->unlock();
00257   }
00258 }
00259
00260 void
00261 CacheLogger::tlog_push_message(LogLevel ll, struct timeval *t, const char *component, Exception &e)
00262 {
00263   if (log_level <= ll ) {
00264     mutex->lock();
00265     localtime_r(&t->tv_sec, now_s);
00266     char timestr[TIMESTR_LENGTH];
00267     snprintf(timestr, TIMESTR_LENGTH,
00268              "%02d:%02d:%02d.%06ld", now_s->tm_hour,
00269              now_s->tm_min, now_s->tm_sec, t->tv_usec);
00270     for (Exception::iterator i = e.begin(); i != e.end(); ++i) {
00271       CacheEntry e;
00272       e.log_level = ll;
00273       e.component = component;
00274       e.time      = *t;
00275       e.timestr   = timestr;
00276       e.message   = std::string("[EXCEPTION] ") + *i;
00277       __messages.push_front(e);
00278     }
00279
00280     if (__num_entries == __max_num_entries) {
00281       __messages.pop_back();
00282     } else {
00283       ++__num_entries;
00284     }
00285     mutex->unlock();
00286   }
00287 }
00288
00289 void
00290 CacheLogger::tlog_debug(struct timeval *t, const char *component, const char *format, ...)
00291 {
00292   va_list arg;
00293   va_start(arg, format);
00294   tlog_push_message(LL_DEBUG, t, component, format, arg);
00295   va_end(arg);
00296 }
00297
00298 void
00299 CacheLogger::tlog_info(struct timeval *t, const char *component, const char *format, ...)
00300 {
00301   va_list arg;
00302   va_start(arg, format);
00303   tlog_push_message(LL_INFO, t, component, format, arg);
00304   va_end(arg);
00305 }
00306
00307 void
00308 CacheLogger::tlog_warn(struct timeval *t, const char *component, const char *format, ...)
00309 {
00310   va_list arg;
00311   va_start(arg, format);
00312   tlog_push_message(LL_WARN, t, component, format, arg);
00313   va_end(arg);
00314 }
00315
00316 void
00317 CacheLogger::tlog_error(struct timeval *t, const char *component, const char *format, ...)
00318 {
00319   va_list arg;
00320   va_start(arg, format);
00321   tlog_push_message(LL_ERROR, t, component, format, arg);
00322   va_end(arg);
00323 }
00324
00325 void
00326 CacheLogger::tlog_debug(struct timeval *t, const char *component, Exception &e)
00327 {
00328   tlog_push_message(LL_DEBUG, t, component, e);
00329 }
00330
00331 void
00332 CacheLogger::tlog_info(struct timeval *t, const char *component, Exception &e)
00333 {
00334   tlog_push_message(LL_INFO, t, component, e);
00335 }
00336
00337 void
00338 CacheLogger::tlog_warn(struct timeval *t, const char *component, Exception &e)
00339 {
00340   tlog_push_message(LL_WARN, t, component, e);
00341 }
00342
00343 void
00344 CacheLogger::tlog_error(struct timeval *t, const char *component, Exception &e)
00345 {
00346   tlog_push_message(LL_ERROR, t, component, e);
00347 }
00348
00349 void
00350 CacheLogger::vtlog_debug(struct timeval *t, const char *component, const char *format, va_list va)
00351 {
00352   tlog_push_message(LL_DEBUG, t, component, format, va);
00353 }
00354
00355 void
00356 CacheLogger::vtlog_info(struct timeval *t, const char *component, const char *format, va_list va)
00357 {
00358   tlog_push_message(LL_INFO, t, component, format, va);
00359 }
00360
00361 void
00362 CacheLogger::vtlog_warn(struct timeval *t, const char *component, const char *format, va_list va)
00363 {
00364   tlog_push_message(LL_WARN, t, component, format, va);
00365 }
00366
00367 void
00368 CacheLogger::vtlog_error(struct timeval *t, const char *component, const char *format, va_list va)
00369 {
00370   tlog_push_message(LL_ERROR, t, component, format, va);
00371 }
00372
00373 } // end namespace fawkes