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

Last change on this file since 5926 was 5641, checked in by Christoph Mayer, 15 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.