10 #include "wvstringlist.h"
17 #define snprintf _snprintf
20 WvLogRcvBaseList *WvLog::receivers;
21 int WvLog::num_receivers = 0, WvLog::num_logs = 0;
24 const char *WvLogRcv::loglevels[WvLog::NUM_LOGLEVELS] = {
43 WvLog::WvLog(WvStringParm _app, LogLevel _loglevel, WvLogFilter* _filter)
44 : app(_app), loglevel(_loglevel), filter(_filter)
52 WvLog::WvLog(
const WvLog &l)
53 : app(l.app), loglevel(l.loglevel), filter(l.filter)
64 if (!num_logs && default_receiver)
67 delete default_receiver;
68 default_receiver = NULL;
84 if (si.wants.writable)
94 if (si.wants.writable)
105 static const int recursion_max = 8;
106 static int recursion_count = 0;
107 static WvString recursion_msg(
"Too many extra log messages written while "
108 "writing to the log. Suppressing additional messages.\n");
114 if (!default_receiver)
122 if (recursion_count < recursion_max)
123 default_receiver->log(app, loglevel, (
const char *)_buf, len);
124 else if (recursion_count == recursion_max)
125 default_receiver->log(app, WvLog::Warning, recursion_msg.
cstr(),
126 recursion_msg.len());
131 else if (default_receiver)
135 delete default_receiver;
136 default_receiver = NULL;
140 WvLogRcvBaseList::Iter i(*receivers);
141 for (i.rewind(); i.next(); )
145 if (recursion_count < recursion_max)
146 rc.log(app, loglevel, (
const char *)_buf, len);
147 else if (recursion_count == recursion_max)
148 rc.log(app, WvLog::Warning, recursion_msg.
cstr(),
149 recursion_msg.len());
162 WvLogRcvBase::WvLogRcvBase()
165 WvLogRcvBase::force_new_line =
false;
166 if (!WvLog::receivers)
167 WvLog::receivers =
new WvLogRcvBaseList;
168 WvLog::receivers->append(
this,
false);
169 WvLog::num_receivers++;
173 WvLogRcvBase::~WvLogRcvBase()
175 assert(WvLog::receivers);
176 WvLog::receivers->unlink(
this);
177 if (WvLog::receivers->isempty())
179 delete WvLog::receivers;
180 WvLog::receivers = NULL;
182 WvLog::num_receivers--;
186 const char *WvLogRcvBase::appname(WvStringParm log)
const
195 void WvLogRcvBase::static_init()
197 static bool init =
false;
208 void WvLogRcvBase::cleanup_on_fork(pid_t p)
212 if (WvLog::receivers)
213 WvLog::receivers->zap();
214 delete WvLog::default_receiver;
215 WvLog::default_receiver = NULL;
216 WvLog::num_receivers = 0;
225 WvLogRcv::WvLogRcv(WvLog::LogLevel _max_level) : custom_levels(5)
228 last_level = WvLog::NUM_LOGLEVELS;
230 max_level = _max_level;
235 WvLogRcv::~WvLogRcv()
243 last_source, loglevels[last_level]);
244 prelen = prefix.len();
250 mid_line(prefix, prelen);
262 static bool my_isprint(
char _c)
264 unsigned char c = _c;
265 if (isprint(c) || c >= 128)
272 void WvLogRcv::log(WvStringParm source,
int _loglevel,
273 const char *_buf,
size_t len)
275 WvLog::LogLevel loglevel = (WvLog::LogLevel)_loglevel;
277 WvLog::LogLevel threshold = max_level;
281 Src_LvlDict::Iter i(custom_levels);
287 if (strstr(srcname, i->src))
294 if (loglevel > threshold)
300 time_t now = wvtime().tv_sec;
301 if (source != last_source
302 || loglevel != last_level
303 || WvLogRcvBase::force_new_line)
306 last_source = source;
307 last_level = loglevel;
311 else if (last_time == 0 || now != last_time)
322 const char *buf = (
const char *)_buf, *bufend = buf + len, *cptr;
328 if (buf[0] ==
'\n' || buf[0] ==
'\r')
343 else if (!my_isprint(buf[0]))
345 snprintf(hex, 5,
"[%02x]", buf[0]);
352 for (cptr = buf; cptr < bufend; cptr++)
354 if (*cptr ==
'\n' || !my_isprint(*cptr))
360 mid_line(buf, bufend - buf);
363 else if (*cptr ==
'\n')
365 mid_line((
const char *)buf, cptr - buf);
370 mid_line(buf, cptr - buf);
379 bool WvLogRcv::set_custom_levels(
WvString descr)
385 WvStringList::Iter i(lst);
386 lst.
split(descr,
",= ");
391 for (i.rewind(); i.next(); )
395 if (atoi(*i) > 0 && atoi(*i) <= WvLog::NUM_LOGLEVELS)
397 custom_levels.add(
new Src_Lvl(src, atoi(*i)),
true);
420 WvLogConsole::WvLogConsole(
int _fd, WvLog::LogLevel _max_level) :
426 WvLogConsole::~WvLogConsole()