An Overlay-based
Virtual Network Substrate
SpoVNet

source: trash/old-modules/transport/protlib/logfile.h @ 5641

Last change on this file since 5641 was 5641, checked in by Christoph Mayer, 14 years ago
File size: 8.6 KB
Line 
1/// ----------------------------------------*- mode: C++; -*--
2/// @file logfile.h
3/// Implementation of a logging stream
4/// ----------------------------------------------------------
5/// $Id: logfile.h 2549 2007-04-02 22:17:37Z bless $
6/// $HeadURL: https://svn.ipv6.tm.uka.de/nsis/protlib/trunk/include/logfile.h $
7// ===========================================================
8//
9// Copyright (C) 2005-2007, all rights reserved by
10// - Institute of Telematics, Universitaet Karlsruhe (TH)
11//
12// More information and contact:
13// https://projekte.tm.uka.de/trac/NSIS
14//
15// This program is free software; you can redistribute it and/or modify
16// it under the terms of the GNU General Public License as published by
17// the Free Software Foundation; version 2 of the License
18//
19// This program is distributed in the hope that it will be useful,
20// but WITHOUT ANY WARRANTY; without even the implied warranty of
21// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22// GNU General Public License for more details.
23//
24// You should have received a copy of the GNU General Public License along
25// with this program; if not, write to the Free Software Foundation, Inc.,
26// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27//
28// ===========================================================
29#ifndef _logfile_h_
30#define _logfile_h_
31
32
33#define _NO_LOGGING
34
35#include <fstream> // file stream
36#include <iostream>
37
38#include <string.h>
39#include <pthread.h>
40#include <sys/time.h>
41#include <stdio.h> // sprintf
42#include <unistd.h> // getpid
43
44#include "protlib_types.h"
45
46namespace protlib {
47
48  using namespace std;
49/** @addtogroup log Logging
50 * @{
51 */
52
53namespace log {
54
55    static const pthread_mutex_t initlogmutex=
56#ifdef _DEBUG
57  // PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; // use this for debugging, it will return errors on potential deadlock situations
58  PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
59#else // should be recursive mutex because sometimes error log output sometimes occurs
60  // while objects contents are logged
61  PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; // PTHREAD_MUTEX_INITIALIZER;
62#endif
63
64#undef ERROR_LOG
65#undef WARNING_LOG
66#undef EVENT_LOG
67#undef INFO_LOG
68#undef DEBUG_LOG
69#undef LOG_TYPES
70
71#undef LOG_ALL
72#undef LOG_EMERG
73#undef LOG_ALERT
74#undef LOG_CRIT
75#undef LOG_NORMAL
76#undef LOG_UNIMP
77
78
79enum logclass_t
80{
81  ERROR_LOG= 0x10,
82  WARNING_LOG= 0x20,
83  EVENT_LOG= 0x30,
84  INFO_LOG=  0x40,
85  DEBUG_LOG= 0x50,
86  EVERY_LOG= 0xF0,
87  LOG_TYPES= 5
88};
89
90
91enum loglevel_t
92{
93  LOG_EMERG=  0,
94  LOG_ALERT=  1,
95  LOG_CRIT=   2,
96  LOG_NORMAL= 4,
97  LOG_UNIMP=  8,
98  LOG_ALL=   15
99};
100
101// colors
102
103enum color_t
104{
105clear,
106bold_on,
107italics_on,
108underline_on,
109inverse_on,
110strikethrough_on,
111bold_off,
112italics_off,
113underline_off,
114inverse_off,
115strikethrough_off,
116black,
117red,
118green,
119yellow,
120blue,
121magenta,
122cyan,
123white,
124fg_default,
125bg_black,
126bg_red,
127bg_green,
128bg_yellow,
129bg_blue,
130bg_magenta,
131bg_cyan,
132bg_white,
133bg_default,
134num_colors,
135off=0};
136
137extern const char* color[];
138extern const char *const ANSIcolorcode[];
139
140
141#define  ERRLog(mname, logstring) Log(ERROR_LOG, LOG_NORMAL, mname, logstring)
142#define  ERRCLog(mname, logstring) Log(ERROR_LOG, LOG_CRIT, mname, logstring)
143#define  EVLog(mname, logstring) Log(EVENT_LOG, LOG_NORMAL, mname, logstring)
144#define  WLog(mname, logstring) Log(WARNING_LOG, LOG_NORMAL, mname, logstring)
145#define  ILog(mname, logstring) Log(INFO_LOG, LOG_NORMAL, mname, logstring)
146#define  DLog(mname, logstring) Log(DEBUG_LOG, LOG_NORMAL, mname, logstring)
147
148
149#ifndef _NO_LOGGING
150
151// Log(lclass, llevel, mname, logstring)
152// lclass: logclass, llevel: severitylevel, mname: module or methodname,
153// logstring: things to log in stream notation
154#define  Log(lclass, llevel, mname, logstring) do {                     \
155  if ( protlib::log::DefaultLog.should_log(lclass, llevel) ) {          \
156    using protlib::log::DefaultLog;                                     \
157    DefaultLog.logstart(lclass, llevel, mname) << logstring;            \
158    DefaultLog.logend();                                                \
159  }                                                                     \
160} while ( false )
161
162#define  LogS(lclass, llevel, mname, logstring) do {                    \
163  if ( protlib::log::DefaultLog.should_log(lclass, llevel) ) {          \
164    protlib::log::DefaultLog.logstart(lclass, llevel, mname,            \
165        __FILE__, __FUNCTION__, __LINE__) << logstring;                 \
166    protlib::log::DefaultLog.logend();                                  \
167  }                                                                     \
168} while ( false )
169
170#else
171
172#define  Log(logclass, loglevel, mname, logstring)
173#define  LogS(logclass, loglevel, mname, logstring)
174
175#endif
176
177class logfile
178{
179 private:
180  ostream* logstream;
181  pthread_mutex_t logmutex;
182
183  unsigned char logfilter[LOG_TYPES];
184
185  bool usecolors;
186  bool quiet_start;
187
188  const char* timenow();
189
190 public:
191
192  logfile(const char* filename="", bool usecolors= true, bool quietstart=false);
193  ~logfile();
194
195  bool set_dest(const char* filename, bool quiet=false);
196  void set_filter(logclass_t logclass, uint8 severitylevel);
197  bool should_log(logclass_t logclass, loglevel_t severitylevel);
198
199
200  ostream& logstart(logclass_t logclass, loglevel_t severity_level,
201                    const string& modname,
202                    const char* file="",
203                    const char* func="",
204                    int line=0);
205  void coloron() { usecolors=true; for (int i= 0; i<num_colors; i++) {color[i]= ANSIcolorcode[i]; } }
206  void coloroff() { usecolors=false; for (int i= 0; i<num_colors; i++) {color[i]= ""; } }
207
208  void logend();
209}; // end class logfile
210
211extern
212
213inline
214logfile::logfile(const char* filename,  bool usecolors, bool quietstart)
215  : logstream(0),
216    logmutex(initlogmutex),
217    usecolors(usecolors),
218    quiet_start(quietstart)
219{
220  for (int i= 0; i< LOG_TYPES; i++)
221    logfilter[i]= LOG_ALL;
222
223  if (strlen(filename))
224    logstream= new(nothrow) ofstream(filename);
225  else
226    logstream= &cout;
227
228  if (!logstream)
229  {
230    cerr << "Could not open logfile " << filename << endl;
231  }
232  else
233  {
234    pthread_mutex_lock(&logmutex);
235
236    // if enable colors, use ANSI code,
237    // if disable colors, so replace all strings with "";
238    for (int i= 0; i<num_colors; i++)
239    {
240      color[i]= (usecolors ? ANSIcolorcode[i] : "");
241    }
242
243    if (!quiet_start && logstream)
244    {
245//       (*logstream) << color[blue] << timenow()
246//                 << '[' << getpid() << "] >>>>>>>>>>>>>>>>>>>>>>>> *** LOG START *** >>>>>>>>>>>>>>>>>>>>>>>>"
247//                 << color[off] << endl;
248    }
249    pthread_mutex_unlock(&logmutex);
250  }
251}
252
253
254inline
255logfile::~logfile()
256{
257  if (logstream)
258  {
259    pthread_mutex_lock(&logmutex);
260
261    if ( ! quiet_start )
262//      (*logstream) << color[blue] << timenow() << '[' << getpid()
263//      << "] <<<<<<<<<<<<<<<<<<<<<<<< *** LOG  STOP *** <<<<<<<<<<<<<<<<<<<<<<<<"
264//      << color[off] << endl;
265    pthread_mutex_unlock(&logmutex);
266
267    // destroy mutex
268    pthread_mutex_destroy(&logmutex);
269
270    // delete if allocated stream
271    if (logstream!= &cout)
272      delete logstream;
273
274    logstream= 0;
275  }
276}
277
278
279
280inline
281void
282logfile::set_filter(logclass_t logclass, uint8 severity_level)
283{
284  uint8 logclass_index= (logclass>>4)-1;
285  if (logclass_index < LOG_TYPES)
286    logfilter[logclass_index]=  severity_level;
287}
288
289inline
290bool
291logfile::should_log(logclass_t logclass, loglevel_t severity_level)
292{
293  return severity_level <= logfilter[(logclass>>4)-1];
294}
295
296
297/**
298 * returns current time in static char array
299 * @return pointer to static character array that contains current time
300 */
301inline
302const char* logfile::timenow()
303{
304  static time_t t;
305  static struct timeval now;
306  static char timestr[32]= "";
307  static char msecstr[6];
308
309  gettimeofday(&now,NULL);
310  t= now.tv_sec;
311  strftime(timestr, sizeof(timestr)-sizeof(msecstr), "%Y-%m-%d %H:%M:%S.", localtime(&t));
312  snprintf(msecstr,sizeof(msecstr),"%03lu",now.tv_usec/1000UL);
313  strcat(timestr,msecstr);
314  return timestr;
315}
316
317inline
318void logfile::logend()
319{
320  if (logstream)
321  {
322    (*logstream) << color[off] << endl;
323  }
324
325  pthread_mutex_unlock(&logmutex);
326}
327
328
329extern logfile& DefaultLog;
330//@}
331
332} // end namespace log
333
334} // end namespace protlib
335
336
337
338
339
340/**
341 * returns current time in static char array
342 * @return pointer to static character array that contains current time
343 */
344inline
345const char* log_timenow(char* module, char* event)
346{
347
348    //static pthread_mutex_t timestampmutex= PTHREAD_MUTEX_INITIALIZER;
349
350
351
352    //pthread_mutex_lock(&timestampmutex);
353
354
355    static time_t t;
356    //static struct timeval now;
357    static char timestr[128]= "";
358    //static char msecstr[8];
359
360    struct timespec tp;
361
362    clock_gettime(CLOCK_REALTIME, &tp);
363
364    //gettimeofday(&now,NULL);
365    t= tp.tv_sec;
366
367    //bringing down the range to under 1 hour
368    //write out microseconds
369
370    //printf("%ld\n", tp.tv_nsec);
371    //printf("%ld\n", t % 3600);
372
373    sprintf(timestr, "%05ld%06ld - ", t % 3600, tp.tv_nsec/1000L);
374    //snprintf(msecstr,sizeof(msecstr),"%06lu",tp.tv_nsec/1000000UL);
375    strcat(timestr,module);
376    strcat(timestr," - ");
377    strcat(timestr,event);
378
379    //pthread_mutex_unlock(&timestampmutex);
380
381    return timestr;
382}
383
384
385
386#endif
Note: See TracBrowser for help on using the repository browser.