WvStreams
wvlogbuffer.cc
1/*
2 * Worldvisions Weaver Software:
3 * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
4 *
5 * WvLogBuffer is a descendant of WvLogRcv that buffers log messages for
6 * later use. It only keeps up to max_lines log entries for every
7 * source/debug level, s.t. debug level <= max_level
8 */
9#include "wvlogbuffer.h"
10#include "strutils.h"
11#include <time.h>
12
13WvLogBuffer::Msg::Msg(WvLog::LogLevel _level, WvStringParm _source,
14 WvString _message) : level(_level), source(_source), message(_message)
15{
16 time(&timestamp);
17}
18
19WvLogBuffer::Msg* WvLogBuffer::MsgCounter::add(WvLogBuffer::Msg* msg, int max)
20{
21 list.append(msg, false);
22
23 // Check if we need to purge anything
24 if (list.count() > (size_t)max)
25 {
26 Msg* killme = list.first();
27 list.unlink_first();
28 return killme;
29 }
30 else
31 return NULL;
32}
33
34
35WvLogBuffer::WvLogBuffer(int _max_lines, WvLog::LogLevel _max_level) :
36 WvLogRcv(_max_level), counters(25)
37{
38 max_lines = _max_lines;
39}
40
41
42WvLogBuffer::~WvLogBuffer()
43{
44 end_line();
45}
46
47
48void WvLogBuffer::_mid_line(const char *str, size_t len)
49{
50 current.put(str, len);
51}
52
53void WvLogBuffer::handle_msg(Msg *lastmsg)
54{
55 // Stick the msg in the list of all messages
56 msgs.append(lastmsg, true);
57
58 // Check if we already have any messages of this source/level
59 WvString type(WvString("%s:%s", last_source, last_level));
60 MsgCounter* msgcounter = counters[type];
61 // If not create a new tracking list for it
62 if (!msgcounter)
63 {
64 msgcounter = new MsgCounter(type);
65 counters.add(msgcounter, true);
66 }
67 // Now that we are sure the type exists, add the message to it
68 Msg* killme = msgcounter->add(lastmsg, max_lines);
69
70 // Delete the extra messages if we need to
71 if (killme)
72 msgs.unlink(killme);
73}
74
76{
77 if (last_level < WvLog::NUM_LOGLEVELS)
78 {
79 current.put('\0'); // terminating NULL
80 Msg *lastmsg = new Msg(last_level, last_source,
81 trim_string((char *)current.get(current.used())));
82
83 handle_msg(lastmsg);
84 }
85 else
86 current.zap();
87}
88
89void WvLogBuffer::feed_receiver(WvLogRcv& receiver)
90{
91 WvLogBuffer::MsgList::Iter i(msgs);
92 i.rewind();
93 while (i.next())
94 {
95 WvLogBuffer::Msg &msg = *i;
96 receiver.log(msg.source, msg.level,
97 msg.message.cstr(), msg.message.len());
98 }
99}
100
101
102void WvLogBuffer::dump(WvStream &s)
103{
104 MsgList::Iter i(messages());
105
106 for (i.rewind(); i.next(); )
107 {
108 Msg &m = *i;
109 s.print("%s %s<%s>: %s+\n",
110 m.timestamp, m.source, loglevels[m.level], m.message);
111 }
112}
const T * get(size_t count)
Reads exactly the specified number of elements and returns a pointer to a storage location owned by t...
Definition: wvbufbase.h:114
void zap()
Clears the buffer.
Definition: wvbufbase.h:257
size_t used() const
Returns the number of elements in the buffer currently available for reading.
Definition: wvbufbase.h:92
A WvFastString acts exactly like a WvString, but can take (const char *) strings without needing to a...
Definition: wvstring.h:94
const char * cstr() const
return a (const char *) for this string.
Definition: wvstring.h:267
virtual void _end_line()
End this (Guaranteed NonEmpty) log line.
Definition: wvlogbuffer.cc:75
virtual void _mid_line(const char *str, size_t len)
add text to the current log line.
Definition: wvlogbuffer.cc:48
WvLogRcv adds some intelligence to WvLogRcvBase, to keep track of line-prefix-printing and other form...
Definition: wvlogrcv.h:29
Unified support for streams, that is, sequences of bytes that may or may not be ready for read/write ...
Definition: wvstream.h:25
WvString is an implementation of a simple and efficient printable-string class.
Definition: wvstring.h:330
char * trim_string(char *string)
Trims whitespace from the beginning and end of the character string, including carriage return / line...
Definition: strutils.cc:59