00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "wvlogbuffer.h"
00010 #include "strutils.h"
00011 #include <time.h>
00012
00013 WvLogBuffer::Msg::Msg(WvLog::LogLevel _level, WvStringParm _source,
00014 WvString _message) : level(_level), source(_source), message(_message)
00015 {
00016 time(×tamp);
00017 }
00018
00019 WvLogBuffer::Msg* WvLogBuffer::MsgCounter::add(WvLogBuffer::Msg* msg, int max)
00020 {
00021 list.append(msg, false);
00022
00023
00024 if (list.count() > (size_t)max)
00025 {
00026 Msg* killme = list.first();
00027 list.unlink_first();
00028 return killme;
00029 }
00030 else
00031 return NULL;
00032 }
00033
00034
00035 WvLogBuffer::WvLogBuffer(int _max_lines, WvLog::LogLevel _max_level) :
00036 WvLogRcv(_max_level), counters(25)
00037 {
00038 max_lines = _max_lines;
00039 }
00040
00041
00042 WvLogBuffer::~WvLogBuffer()
00043 {
00044 end_line();
00045 }
00046
00047
00048 void WvLogBuffer::_mid_line(const char *str, size_t len)
00049 {
00050 current.put(str, len);
00051 }
00052
00053
00054 void WvLogBuffer::_end_line()
00055 {
00056 if (last_level < WvLog::NUM_LOGLEVELS)
00057 {
00058 current.put('\0');
00059 Msg *lastmsg = new Msg(last_level, last_source->app,
00060 trim_string((char *)current.get(current.used())));
00061
00062
00063 msgs.append(lastmsg, true);
00064
00065
00066 WvString type(WvString("%s:%s", last_source->app, last_level));
00067 MsgCounter* msgcounter = counters[type];
00068
00069 if (!msgcounter)
00070 {
00071 msgcounter = new MsgCounter(type);
00072 counters.add(msgcounter, true);
00073 }
00074
00075 Msg* killme = msgcounter->add(lastmsg, max_lines);
00076
00077
00078 if (killme)
00079 msgs.unlink(killme);
00080 }
00081 else
00082 current.zap();
00083 }
00084
00085
00086 void WvLogBuffer::dump(WvStream &s)
00087 {
00088 MsgList::Iter i(messages());
00089
00090 for (i.rewind(); i.next(); )
00091 {
00092 Msg &m = *i;
00093 s.print("%s %s<%s>: %s+\n",
00094 m.timestamp, m.source, loglevels[m.level], m.message);
00095 }
00096 }