2 * Worldvisions Weaver Software:
3 * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
5 * A generic data-logger class with support for multiple receivers. If
6 * no WvLogRcv objects have been created (see wvlogrcv.h) the default is
9 * WvLog supports partial- and multiple-line log messages. For example,
11 * log.print("string\nfoo");
13 * appname(lvl): test string
27 // a WvLogRcv registers itself with WvLog and prints, captures,
28 // or transmits log messages.
33 const char *appname(WvStringParm log
) const;
34 virtual void log(WvStringParm source
, int loglevel
,
35 const char *_buf
, size_t len
) = 0;
38 static void cleanup_on_fork(pid_t p
);
39 static void static_init();
44 virtual ~WvLogRcvBase();
48 DeclareWvList(WvLogRcvBase
);
50 typedef wv::function
<WvString(WvStringParm
)> WvLogFilter
;
53 * A WvLog stream accepts log messages from applications and forwards them
54 * to all registered WvLogRcv's.
56 class WvLog
: public WvStream
58 friend class WvLogRcvBase
;
78 static WvLogRcvBaseList
*receivers
;
79 static int num_receivers
, num_logs
;
80 static WvLogRcvBase
*default_receiver
;
84 WvLog(WvStringParm _app
, LogLevel _loglevel
= Info
,
85 WvLogFilter
* filter
= 0);
86 WvLog(const WvLog
&l
);
89 /** fd==-1, but this stream is always ok */
90 virtual bool isok() const;
93 virtual void pre_select(SelectInfo
&si
);
94 virtual bool post_select(SelectInfo
&si
);
97 * change the loglevel. This returns the object again, so you can
98 * make convenient statements like log.lvl(WvLog::Warning).print(...)
100 WvLog
&lvl(LogLevel _loglevel
)
101 { loglevel
= _loglevel
; return *this; }
103 /** change the loglevel and then print a message. */
104 size_t operator() (LogLevel _loglevel
, WvStringParm s
)
106 LogLevel l
= loglevel
;
107 size_t x
= lvl(_loglevel
).write(filter
? (*filter
)(s
) : s
);
112 /** change the loglevel and then print a formatted message */
113 size_t operator() (LogLevel _loglevel
, WVSTRING_FORMAT_DECL
)
115 LogLevel l
= loglevel
;
118 x
= lvl(_loglevel
).print((*filter
)(WvString(WVSTRING_FORMAT_CALL
)));
120 x
= lvl(_loglevel
).print(WVSTRING_FORMAT_CALL
);
126 * although these appear in WvStream, they need to be re-listed here
127 * since the above operator()s caused them to be hidden
129 size_t operator() (WvStringParm s
)
130 { return WvStream::operator()(filter
? (*filter
)(s
) : s
); }
131 size_t operator() (WVSTRING_FORMAT_DECL
)
133 WvStream::operator()((*filter
)(WvString(WVSTRING_FORMAT_CALL
))) :
134 WvStream::operator()(WVSTRING_FORMAT_CALL
) );
138 * split off a new WvLog object with the requested loglevel. This way
139 * you can have log at two or more levels without having to retype
140 * log.lvl(WvLog::blahblah) all the time.
142 WvLog
split(LogLevel _loglevel
) const
143 { return WvLog(app
, _loglevel
, filter
); }
146 * we override the unbuffered write function, so lines also include the
147 * application and log level.
149 virtual size_t uwrite(const void *buf
, size_t len
);
151 /** a useful substitute for the normal C perror() function */
152 void perror(WvStringParm s
)
153 { print("%s: %s\n", s
, strerror(errno
)); }
156 const char *wstype() const { return "WvLog"; }