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