blob: 0d8761b398e31d37950679b18ca7368bddeecc96 [file] [log] [blame]
Emeric Vigier2f625822012-08-06 11:09:52 -04001// Copyright (C) 2005-2010 Angelo Naselli, Penta Engineering s.r.l.
2//
3// This program is free software; you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation; either version 2 of the License, or
6// (at your option) any later version.
7//
8// but WITHOUT ANY WARRANTY; without even the implied warranty of
9// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10// GNU General Public License for more details.
11//
12// You should have received a copy of the GNU General Public License
13// along with this program; if not, write to the Free Software
14// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15//
16// As a special exception, you may use this file as part of a free software
17// library without restriction. Specifically, if other files instantiate
18// templates or use macros or inline functions from this file, or you compile
19// this file and link it with other files to produce an executable, this
20// file does not by itself cause the resulting executable to be covered by
21// the GNU General Public License. This exception does not however
22// invalidate any other reasons why the executable file might be covered by
23// the GNU General Public License.
24//
25// This exception applies only to the code released under the name GNU
26// Common C++. If you copy code from other releases into a copy of GNU
27// Common C++, as the General Public License permits, the exception does
28// not apply to the code that you add in this way. To avoid misleading
29// anyone as to the status of such modified files, you must delete
30// this exception notice from them.
31//
32// If you write modifications of your own for GNU Common C++, it is your choice
33// whether to permit this exception to apply to your modifications.
34// If you do not wish that, delete this exception notice.
35//
36
37/**
38 * @file applog.h
39 * @short Application logging facilities abstraction.
40 **/
41
42
43#ifndef ___APPLOG_H___
44#define ___APPLOG_H___
45
46#ifndef CCXX_SLOG_H_
47#include <cc++/slog.h>
48#endif
49
50#include <cc++/exception.h>
51
52#include <string>
53#include <sstream>
54#include <iostream>
55#include <map>
56
57#ifdef CCXX_NAMESPACES
58using namespace std;
59
60namespace ost
61{
62#endif
63/**
64 * Produces a dump of a buffer in a hexdump way with its
65 * code Ascii translation and relative buffer address.
66 *
67 * For instance:
68 * 0000000 - 77 98 21 49 0e 00 05 00 40 1c 01 1c 2f 00 00 00 w.!I....@.../...
69 *
70 */
71class __EXPORT HEXdump
72{
73 protected:
74 /**
75 * output string
76 */
77 std::string _str;
78
79 public:
80 // max_len: max number of bytes to be printed. 0 prints all.
81 /**
82 * HEXdump constructor.
83 *
84 * @param buffer buffer to be "hexdumped"
85 * @param buff_len buffer length
86 * @param max_len max number of bytes to be "hexdumped". Usefull to
87 * truncate output. mas_len=0 does prints all.
88 */
89 HEXdump(const unsigned char *buffer, int buff_len, int max_len = 200);
90
91 /**
92 * HEXdump destructor.
93 */
94 virtual ~HEXdump() { _str = string();}
95
96 /**
97 * const char* cast provided for conveneince.
98 */
99
100 const char * c_str() const
101 {
102 return _str.c_str();
103 }
104
105 /**
106 * string cast provided for conveneince.
107 */
108 std::string str()
109 {
110 return _str;
111 }
112
113 /**
114 * operator <<
115 * @param hd hexdump.
116 * @return application logger stream
117 */
118 friend std::ostream& operator<< (std::ostream& out, const HEXdump &hd)
119 {
120 out << hd.c_str();
121 return out;
122 }
123
124};
125
126#ifdef CCXX_EXCEPTIONS
127/**
128 * Applog exception, used for memory problems at the moment
129 *
130 */
131class __EXPORT AppLogException : public ost::Exception
132{
133 public:
134 /**
135 * Constructor.
136 * @param what_arg exception string
137 */
138 AppLogException(const std::string &what_arg) : ost::Exception(what_arg) {};
139
140};
141#endif
142
143class AppLogPrivate;
144
145/**
146 * Application logger is a class that implements a logger that can be used
147 * by applications to save log file somewhere on the system.
148 *
149 * It uses ost::slog to write to syslog and std::clog to write to standard
150 * output.
151 *
152 * It provides either a stream oriented logger or a old printf style one.
153 *
154 * It can be used to log directly on a file or in a spooler like way. Latter
155 * uses a ost::ThreadQueue to implement a thread safe access to logger.
156 *
157 * It provides a global stream variable called ost::alog.
158 *
159 * It provides an AppLog::Ident class that represents a module name for
160 * instance that can be used to tag logs. Logging levels are the same
161 * defined into ost::Slog:
162 * Slog::levelEmergency
163 * Slog::levelAlert
164 * Slog::levelCritical
165 * Slog::levelError
166 * Slog::levelWarning
167 * Slog::levelNotice
168 * Slog::levelInfo
169 * Slog::levelDebugfrom.
170 *
171 * Example of usage: alog << mod_name << debug << "Hello world!" << std::endl;
172 */
173class __EXPORT AppLog : protected streambuf, public ostream
174{
175 protected:
176 // d pointer
177 AppLogPrivate *d;
178 void writeLog(bool endOfLine = true);
179 static map<string, Slog::Level> *assoc;
180
181 public:
182 /**
183 * Ident class that represents module name.
184 */
185 class __EXPORT Ident
186 {
187 private:
188 std::string _ident;
189 public:
190
191 /**
192 * Constructor.
193 */
194 Ident() {};
195
196 /**
197 * Desctructor.
198 */
199 ~Ident() {};
200
201 /**
202 * Copy constructor.
203 */
204 Ident(Ident& id) {_ident = id._ident;}
205
206 /**
207 * const char* constructor, provided for convenience.
208 */
209 Ident(const char *str) : _ident(str) {};
210
211 /**
212 * std::string cast.
213 */
214 std::string& str() {return _ident;}
215
216 /**
217 * Assignment operator (string).
218 */
219 Ident& operator= (std::string &st) {_ident = st; return *this;}
220
221 /**
222 * Assignment operator (const char[]), provided for convenience.
223 */
224 Ident& operator= (const char str[]) {_ident = str; return *this;}
225
226 /**
227 * const char* cast provided for conveneince.
228 */
229 const char* c_str() {return _ident.c_str();}
230 };
231
232#ifndef WIN32
233 /**
234 * Constructor for a customized logger.
235 * @param logFileName log file name.
236 * @param logDirectly true to write directly to file, false to use
237 * a spooler like logger.
238 * @param usePipe true to use pipe instead of file, false otherwise
239 */
240 AppLog(const char* logFileName = NULL, bool logDirectly = false , bool usePipe = false);
241#else
242 /**
243 * Constructor for a customized logger.
244 * @param logFileName log file name.
245 * @param logDirectly true to write directly to file, false to use
246 * a spooler like logger.
247 */
248 AppLog(const char* logFileName = NULL, bool logDirectly = false);
249#endif
250 /**
251 * Destructor
252 */
253 virtual ~AppLog();
254
255 /**
256 * Subscribes the current thread to logger, it reserves thread safe
257 * buffer for it.
258 */
259 void subscribe();
260
261 /**
262 * Unsubscribes the current thread from logger.
263 */
264 void unsubscribe();
265
266#ifndef WIN32
267 /**
268 * Allows to set up ost::alog parameters.
269 * @param FileName log file name.
270 * @param logDirectly true to write directly to file, false to use
271 * a spooler like logger.
272 * @param usePipe true to use pipe instead of file, false otherwise
273 */
274 void logFileName(const char* FileName, bool logDirectly = false, bool usePipe = false);
275#else
276 /**
277 * Allows to set up ost::alog parameters.
278 * @param FileName log file name.
279 * @param logDirectly true to write directly to file, false to use
280 * a spooler like logger.
281 */
282 void logFileName(const char* FileName, bool logDirectly = false);
283#endif
284 /**
285 * if logDirectly is set it closes the file.
286 */
287 void close(void);
288
289 /**
290 * Sets the log level.
291 * @param enable log level.
292 */
293 void level(Slog::Level enable);
294
295 /**
296 * Enables clog output.
297 * @param en true to enable clog output.
298 */
299 void clogEnable(bool en = true);
300
301 /**
302 * Enables slog output for error level messages.
303 * @param en true to enable slog output.
304 */
305 void slogEnable(bool en = true);
306
307 /**
308 * Sets the level for that ident.
309 * @param ident ident (module name for instance).
310 * @param level level
311 */
312 void identLevel(const char *ident, Slog::Level level);
313
314 /**
315 * Opens the file if not already and sets ident
316 * @param ident module name for instance.
317 */
318 void open(const char *ident);
319
320 /**
321 * stream overflow() overload.
322 * @param c character to be managed
323 * @return c
324 */
325 virtual int overflow(int c);
326
327 /**
328 * stream sync() overload
329 */
330 virtual int sync();
331
332#ifdef HAVE_SNPRINTF
333
334 /**
335 * emerg level printf style method, provided for convenience.
336 * @param format printf format
337 */
338 void emerg(const char *format, ...);
339
340 /**
341 * alert level printf style method, provided for convenience.
342 * @param format printf format
343 */
344 void alert(const char *format, ...);
345
346 /**
347 * critical level printf style method, provided for convenience.
348 * @param format printf format
349 */
350 void critical(const char *format, ...);
351
352 /**
353 * error level printf style method, provided for convenience.
354 * @param format printf format
355 */
356 void error(const char *format, ...);
357
358 /**
359 * warn level printf style method, provided for convenience.
360 * @param format printf format
361 */
362 void warn(const char *format, ...);
363
364 /**
365 * notice level printf style method, provided for convenience.
366 * @param format printf format
367 */
368 void notice(const char *format, ...);
369
370 /**
371 * info level printf style method, provided for convenience.
372 * @param format printf format
373 */
374 void info(const char *format, ...);
375
376 /**
377 * debug level printf style method, provided for convenience.
378 * @param format printf format
379 */
380 void debug(const char *format, ...);
381#endif
382
383 /**
384 * operator to change ident and log level
385 * @param ident ident (module name for instance)
386 * @param level new log level
387 * @return application logger stream
388 */
389 AppLog &operator()(const char *ident, Slog::Level level = Slog::levelError);
390
391 /**
392 * operator to change ident
393 * @param ident ident (module name for instance)
394 * @return application logger stream
395 */
396 inline AppLog& operator()(Ident &ident)
397 {
398 open(ident.c_str());
399 return *this;
400 }
401
402 /**
403 * operator to change logging level
404 * @param level new log level
405 * @return application logger stream
406 */
407 AppLog &operator()(Slog::Level level);
408
409 /**
410 * manipulator operator, to change print levels.
411 * @param (* pfManipulator)(AppLog &)
412 * @return application logger stream
413 */
414 AppLog& operator<< (AppLog& (*pfManipulator)(AppLog&));
415
416 /**
417 * manipulator operator, to use ostream manipulators (i.e. std::endl,...)
418 * @param (* pfManipulator)(AppLog &)
419 * @return application logger stream
420 */
421 AppLog& operator<< (ostream& (*pfManipulator)(ostream&));
422
423 friend ostream& operator << (ostream &out, AppLog & al)
424 {
425 return al;
426 }
427
428 /**
429 * operator <<
430 * @param ident module name for instance.
431 * @return application logger stream
432 */
433 inline AppLog& operator<< (Ident &ident)
434 {
435 open(ident.c_str());
436 return *this;
437 }
438
439
440 /**
441 * warn level
442 * @return application logger stream
443 */
444 inline AppLog &warn(void)
445 {return operator()(Slog::levelWarning);}
446
447 /**
448 * error level
449 * @return application logger stream
450 */
451 AppLog &error(void)
452 { return operator()(Slog::levelError);}
453
454 /**
455 * debug level
456 * @return application logger stream
457 */
458 inline AppLog &debug(void)
459 {return operator()(Slog::levelDebug);}
460
461 /**
462 * emerg level
463 * @return application logger stream
464 */
465 inline AppLog &emerg(void)
466 {return operator()(Slog::levelEmergency);}
467
468 /**
469 * alert level
470 * @return application logger stream
471 */
472 inline AppLog &alert(void)
473 {return operator()(Slog::levelAlert);}
474
475 /**
476 * critical level
477 * @return application logger stream
478 */
479 inline AppLog &critical(void)
480 {return operator()(Slog::levelCritical);}
481
482 /**
483 * notice level
484 * @return application logger stream
485 */
486 inline AppLog &notice(void)
487 {return operator()(Slog::levelNotice);}
488
489 /**
490 * info level
491 * @return application logger stream
492 */
493 inline AppLog &info(void)
494 {return operator()(Slog::levelInfo);}
495
496 /**
497 * Translates level from string to Slog::Level, useful for
498 * configuration files for instance.
499 * Valid level names are:
500 * "emerg" for Slog::levelEmergency
501 * "alert" for Slog::levelAlert
502 * "critical" for Slog::levelCritical
503 * "error" for Slog::levelError
504 * "warn" for Slog::levelWarning
505 * "notice" for Slog::levelNotice
506 * "info" for Slog::levelInfo
507 * "debug" for Slog::levelDebug
508 * @param name Slog Level name
509 * @return Slog level value
510 */
511 static Slog::Level levelTranslate(string name)
512 {
513 map<string, Slog::Level>::iterator it = assoc->find(name);
514
515 return (it != assoc->end()) ? it->second : Slog::levelEmergency;
516 }
517
518};
519
520/**
521 * Manipulator for debug level
522 * @param sl application logger stream
523 * @return application logger stream
524 */
525__EXPORT inline AppLog &debug(AppLog& sl)
526{return sl.operator()(Slog::levelDebug);}
527
528/**
529 * Manipulator for warn level
530 * @param sl application logger stream
531 * @return application logger stream
532 */
533__EXPORT inline AppLog &warn(AppLog& sl)
534{return sl.operator()(Slog::levelWarning);}
535
536/**
537 * Manipulator for error level
538 * @param sl application logger stream
539 * @return application logger stream
540 */
541__EXPORT inline AppLog &error(AppLog& sl)
542{ return sl.operator()(Slog::levelError);}
543
544/**
545 * Manipulator for emerg level
546 * @param sl application logger stream
547 * @return application logger stream
548 */
549__EXPORT inline AppLog &emerg(AppLog& sl)
550{return sl.operator()(Slog::levelEmergency);}
551
552/**
553 * Manipulator for alert level
554 * @param sl application logger stream
555 * @return application logger stream
556 */
557__EXPORT inline AppLog &alert(AppLog& sl)
558{return sl.operator()(Slog::levelAlert);}
559
560/**
561 * Manipulator for critical level
562 * @param sl application logger stream
563 * @return application logger stream
564 */
565__EXPORT inline AppLog &critical(AppLog& sl)
566{return sl.operator()(Slog::levelCritical);}
567
568/**
569 * Manipulator for notice level
570 * @param sl application logger stream
571 * @return application logger stream
572 */
573__EXPORT inline AppLog &notice(AppLog& sl)
574{return sl.operator()(Slog::levelNotice);}
575
576/**
577 * Manipulator for info level
578 * @param sl application logger stream
579 * @return application logger stream
580 */
581__EXPORT inline AppLog &info(AppLog& sl)
582{return sl.operator()(Slog::levelInfo);}
583
584/**
585 * alog global log stream definition
586 */
587__EXPORT extern AppLog alog;
588
589#ifdef CCXX_NAMESPACES
590} //namespace
591#endif
592
593#endif //___APPLOG_H___