ucommon  7.0.0
About: GNU uCommon C++ is a portable and optimized class framework for writing C++ applications that need to use threads and support concurrent synchronization, and that use sockets, XML parsing, object serialization, thread-optimized string and data structure classes, etc..
  Fossies Dox: ucommon-7.0.0.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

Loading...
Searching...
No Matches
slog.cpp
Go to the documentation of this file.
1// Copyright (C) 1999-2005 Open Source Telecom Corporation.
2// Copyright (C) 2006-2014 David Sugar, Tycho Softworks.
3// Copyright (C) 2015 Cherokees of Idaho.
4//
5// This program is free software; you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation; either version 2 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19// As a special exception, you may use this file as part of a free software
20// library without restriction. Specifically, if other files instantiate
21// templates or use macros or inline functions from this file, or you compile
22// this file and link it with other files to produce an executable, this
23// file does not by itself cause the resulting executable to be covered by
24// the GNU General Public License. This exception does not however
25// invalidate any other reasons why the executable file might be covered by
26// the GNU General Public License.
27//
28// This exception applies only to the code released under the name GNU
29// Common C++. If you copy code from other releases into a copy of GNU
30// Common C++, as the General Public License permits, the exception does
31// not apply to the code that you add in this way. To avoid misleading
32// anyone as to the status of such modified files, you must delete
33// this exception notice from them.
34//
35// If you write modifications of your own for GNU Common C++, it is your choice
36// whether to permit this exception to apply to your modifications.
37// If you do not wish that, delete this exception notice.
38//
39
40#include <ucommon-config.h>
41#include <commoncpp/config.h>
42#include <commoncpp/export.h>
43#include <commoncpp/slog.h>
44#ifdef __BORLANDC__
45#include <stdio.h>
46#include <stdarg.h>
47#else
48#include <cstdio>
49#include <cstdarg>
50#endif
51
52#ifdef HAVE_SYSLOG_H
53#include <syslog.h>
54#endif
55
56namespace ost {
57using std::streambuf;
58using std::ofstream;
59using std::ostream;
60using std::clog;
61using std::endl;
62using std::ios;
63
65
67streambuf() ,ostream((streambuf *)this)
68{
69 _enable = true;
71 _clogEnable = true;
72 syslog = NULL;
73}
74
76{
77#ifdef HAVE_SYSLOG_H
78 closelog();
79#else
80 if(syslog)
81 fclose(syslog);
82#endif
83}
84
85void Slog::close(void)
86{
87pthread_mutex_lock(&lock);
88#ifdef HAVE_SYSLOG_H
89 closelog();
90#else
91 if(syslog)
92 fclose(syslog);
93 syslog = NULL;
94#endif
95 pthread_mutex_unlock(&lock);
96}
97
98void Slog::open(const char *ident, Class grp)
99{
100 const char *cp;
101
102 pthread_mutex_lock(&lock);
103#ifdef HAVE_SYSLOG_H
104 cp = strrchr(ident, '/');
105 if(cp)
106 ident = ++cp;
107
108 int fac;
109
110 switch(grp) {
111 case classUser:
112 fac = LOG_USER;
113 break;
114
115 case classDaemon:
116 fac = LOG_DAEMON;
117 break;
118
119 case classAudit:
120#ifdef LOG_AUTHPRIV
121 fac = LOG_AUTHPRIV;
122 break;
123#endif
124 case classSecurity:
125 fac = LOG_AUTH;
126 break;
127
128 case classLocal0:
129 fac = LOG_LOCAL0;
130 break;
131
132 case classLocal1:
133 fac = LOG_LOCAL1;
134 break;
135
136 case classLocal2:
137 fac = LOG_LOCAL2;
138 break;
139
140 case classLocal3:
141 fac = LOG_LOCAL3;
142 break;
143
144 case classLocal4:
145 fac = LOG_LOCAL4;
146 break;
147
148 case classLocal5:
149 fac = LOG_LOCAL5;
150 break;
151
152 case classLocal6:
153 fac = LOG_LOCAL6;
154 break;
155
156 case classLocal7:
157 fac = LOG_LOCAL7;
158 break;
159
160 default:
161 fac = LOG_USER;
162 break;
163 }
164 openlog(ident, 0, fac);
165#else
166 if(syslog)
167 fclose(syslog);
168
169 size_t size = strlen(ident) + 1;
170 char *buf = new char[size];
171 String::set(buf, size, ident);
172 cp = (const char *)buf;
173 buf = strrchr(buf, '.');
174 if(buf) {
175 if(!stricmp(buf, ".exe")) {
176 String::set(buf, size, ".log");
177 }
178 }
179 syslog = fopen(cp, "a");
180#endif
181 pthread_mutex_unlock(&lock);
182}
183
184void Slog::error(const char *format, ...)
185{
186 Thread *thread = Thread::get();
187 va_list args;
188 va_start(args, format);
189 overflow(EOF);
190
191 if(!thread) {
192 va_end(args);
193 return;
194 }
195
196 error();
197
198 vsnprintf(thread->msgbuf, sizeof(thread->msgbuf), format, args);
199 thread->msgpos = strlen(thread->msgbuf);
200 overflow(EOF);
201 va_end(args);
202}
203
204void Slog::warn(const char *format, ...)
205{
206 Thread *thread = Thread::get();
207 va_list args;
208
209 if(!thread)
210 return;
211
212 va_start(args, format);
213 overflow(EOF);
214 warn();
215 vsnprintf(thread->msgbuf, sizeof(thread->msgbuf), format, args);
216 thread->msgpos = strlen(thread->msgbuf);
217 overflow(EOF);
218 va_end(args);
219}
220
221void Slog::debug(const char *format, ...)
222{
223 Thread *thread = Thread::get();
224 va_list args;
225
226 if(!thread)
227 return;
228
229 va_start(args, format);
230 overflow(EOF);
231 debug();
232 vsnprintf(thread->msgbuf, sizeof(thread->msgbuf), format, args);
233 thread->msgpos = strlen(thread->msgbuf);
234 overflow(EOF);
235 va_end(args);
236}
237
238void Slog::emerg(const char *format, ...)
239{
240 Thread *thread = Thread::get();
241 va_list args;
242
243 if(!thread)
244 return;
245
246 va_start(args, format);
247 overflow(EOF);
248 emerg();
249 vsnprintf(thread->msgbuf, sizeof(thread->msgbuf), format, args);
250 thread->msgpos = strlen(thread->msgbuf);
251 overflow(EOF);
252 va_end(args);
253}
254
255void Slog::alert(const char *format, ...)
256{
257 Thread *thread = Thread::get();
258 va_list args;
259
260 if(!thread)
261 return;
262
263 va_start(args, format);
264 overflow(EOF);
265 alert();
266 vsnprintf(thread->msgbuf, sizeof(thread->msgbuf), format, args);
267 thread->msgpos = strlen(thread->msgbuf);
268 overflow(EOF);
269 va_end(args);
270}
271
272void Slog::critical(const char *format, ...)
273{
274 Thread *thread = Thread::get();
275 va_list args;
276
277 if(!thread)
278 return;
279
280 va_start(args, format);
281 overflow(EOF);
282 critical();
283 vsnprintf(thread->msgbuf, sizeof(thread->msgbuf), format, args);
284 thread->msgpos = strlen(thread->msgbuf);
285 overflow(EOF);
286 va_end(args);
287}
288
289void Slog::notice(const char *format, ...)
290{
291 Thread *thread = Thread::get();
292 va_list args;
293
294 if(!thread)
295 return;
296
297 va_start(args, format);
298 overflow(EOF);
299 notice();
300 vsnprintf(thread->msgbuf, sizeof(thread->msgbuf), format, args);
301 thread->msgpos = strlen(thread->msgbuf);
302 overflow(EOF);
303 va_end(args);
304}
305
306void Slog::info(const char *format, ...)
307{
308 Thread *thread = Thread::get();
309 va_list args;
310
311 if(!thread)
312 return;
313
314 va_start(args, format);
315 overflow(EOF);
316 info();
317 vsnprintf(thread->msgbuf, sizeof(thread->msgbuf), format, args);
318 thread->msgpos = strlen(thread->msgbuf);
319 overflow(EOF);
320 va_end(args);
321}
322
324{
325 Thread *thread = Thread::get();
326 if(!thread)
327 return c;
328
329 if(c == '\n' || !c || c == EOF) {
330 if(!thread->msgpos)
331 return c;
332
333 thread->msgbuf[thread->msgpos] = 0;
334 pthread_mutex_lock(&lock);
335 if (_enable)
336#ifdef HAVE_SYSLOG_H
337 ::syslog(priority, "%s", thread->msgbuf);
338#else
339 {
340 time_t now;
341 struct tm *dt;
342 time(&now);
343 dt = localtime(&now);
344 char buf[256];
345 const char *p = "unknown";
346 switch(priority) {
347 case levelEmergency:
348 p = "emerg";
349 break;
350 case levelInfo:
351 p = "info";
352 break;
353 case levelError:
354 p = "error";
355 break;
356 case levelAlert:
357 p = "alert";
358 break;
359 case levelDebug:
360 p = "debug";
361 break;
362 case levelNotice:
363 p = "notice";
364 break;
365 case levelWarning:
366 p = "warn";
367 break;
368 case levelCritical:
369 p = "crit";
370 break;
371 }
372
373 snprintf(buf, sizeof(buf), "%04d-%02d-%02d %02d:%02d:%02d [%s] %s\n",
374 dt->tm_year + 1900, dt->tm_mon + 1, dt->tm_mday,
375 dt->tm_hour, dt->tm_min, dt->tm_sec,
376 p, thread->msgbuf);
377 if(syslog)
378 fputs(buf, syslog);
379// syslog << "[" << priority << "] " << thread->msgbuf << endl;
380 }
381#endif
382 pthread_mutex_unlock(&lock);
383 thread->msgpos = 0;
384
385 if ( _enable && _clogEnable
386#ifndef _MSWINDOWS_
387 && (getppid() > 1)
388#endif
389 )
390 clog << thread->msgbuf << endl;
391 _enable = true;
392 return c;
393 }
394
395 if (thread->msgpos < (int)(sizeof(thread->msgbuf) - 1))
396 thread->msgbuf[thread->msgpos++] = c;
397
398 return c;
399}
400
401Slog &Slog::operator()(const char *ident, Class grp, Level lev)
402{
403 Thread *thread = Thread::get();
404
405 if(!thread)
406 return *this;
407
408 thread->msgpos = 0;
409 _enable = true;
410 open(ident, grp);
411 return this->operator()(lev, grp);
412}
413
415{
416 Thread *thread = Thread::get();
417
418 if(!thread)
419 return *this;
420
421 thread->msgpos = 0;
422 if(_level >= lev)
423 _enable = true;
424 else
425 _enable = false;
426
427#ifdef HAVE_SYSLOG_H
428 switch(lev) {
429 case levelEmergency:
430 priority = LOG_EMERG;
431 break;
432 case levelAlert:
433 priority = LOG_ALERT;
434 break;
435 case levelCritical:
436 priority = LOG_CRIT;
437 break;
438 case levelError:
439 priority = LOG_ERR;
440 break;
441 case levelWarning:
442 priority = LOG_WARNING;
443 break;
444 case levelNotice:
445 priority = LOG_NOTICE;
446 break;
447 case levelInfo:
448 priority = LOG_INFO;
449 break;
450 case levelDebug:
451 priority = LOG_DEBUG;
452 break;
453 }
454 switch(grp) {
455 case classAudit:
456#ifdef LOG_AUTHPRIV
457 priority |= LOG_AUTHPRIV;
458 break;
459#endif
460 case classSecurity:
461 priority |= LOG_AUTH;
462 break;
463 case classUser:
464 priority |= LOG_USER;
465 break;
466 case classDaemon:
467 priority |= LOG_DAEMON;
468 break;
469 case classDefault:
470 priority |= LOG_USER;
471 break;
472 case classLocal0:
473 priority |= LOG_LOCAL0;
474 break;
475 case classLocal1:
476 priority |= LOG_LOCAL1;
477 break;
478 case classLocal2:
479 priority |= LOG_LOCAL2;
480 break;
481 case classLocal3:
482 priority |= LOG_LOCAL3;
483 break;
484 case classLocal4:
485 priority |= LOG_LOCAL4;
486 break;
487 case classLocal5:
488 priority |= LOG_LOCAL5;
489 break;
490 case classLocal6:
491 priority |= LOG_LOCAL6;
492 break;
493 case classLocal7:
494 priority |= LOG_LOCAL7;
495 break;
496 }
497#else
498 priority = lev;
499#endif
500 return *this;
501}
502
504{
505 return *this;
506}
507
508} // namespace ost
509
The slog class is used to stream messages to the system's logging facility (syslogd).
Definition: slog.h:105
Slog & critical(void)
Definition: slog.h:287
Slog & emerg(void)
Definition: slog.h:279
Slog & debug(void)
Definition: slog.h:275
int priority
Definition: slog.h:137
Slog & error(void)
Definition: slog.h:271
@ levelEmergency
Definition: slog.h:124
@ levelAlert
Definition: slog.h:125
@ levelInfo
Definition: slog.h:130
@ levelWarning
Definition: slog.h:128
@ levelDebug
Definition: slog.h:131
@ levelCritical
Definition: slog.h:126
@ levelNotice
Definition: slog.h:129
@ levelError
Definition: slog.h:127
pthread_mutex_t lock
Definition: slog.h:135
bool _enable
Definition: slog.h:139
virtual ~Slog(void)
Definition: slog.cpp:75
Slog(void)
Default (and only) constructor.
Definition: slog.cpp:66
void close(void)
Definition: slog.cpp:85
Level _level
Definition: slog.h:138
Slog & operator()(void)
Does nothing except return *this.
Definition: slog.cpp:503
FILE * syslog
Definition: slog.h:136
Slog & warn(void)
Definition: slog.h:267
@ classLocal1
Definition: slog.h:114
@ classLocal6
Definition: slog.h:119
@ classDaemon
Definition: slog.h:110
@ classLocal0
Definition: slog.h:113
@ classLocal2
Definition: slog.h:115
@ classLocal3
Definition: slog.h:116
@ classUser
Definition: slog.h:111
@ classAudit
Definition: slog.h:109
@ classLocal7
Definition: slog.h:120
@ classSecurity
Definition: slog.h:108
@ classDefault
Definition: slog.h:112
@ classLocal5
Definition: slog.h:118
@ classLocal4
Definition: slog.h:117
Slog & info(void)
Definition: slog.h:295
void open(const char *ident, Class grp=classUser)
(re)opens the output stream.
Definition: slog.cpp:98
bool _clogEnable
Definition: slog.h:140
int overflow(int c) __OVERRIDE
This is the streambuf function that actually outputs the data to the device.
Definition: slog.cpp:323
Slog & notice(void)
Definition: slog.h:291
Slog & alert(void)
Definition: slog.h:283
char msgbuf[128]
Definition: thread.h:425
static Thread * get(void)
Definition: thread.h:458
size_t msgpos
Definition: thread.h:424
void set(const char *text)
Set string object to text of a null terminated string.
Definition: string.cpp:802
Export interfaces for library interfaces.
int stricmp(const char *s1, const char *s2)
Definition: cpr.cpp:95
Definition: address.cpp:63
Slog slog
Definition: slog.cpp:64
System logging facilities abstraction.
#define EOF
Definition: stream.cpp:51