WvStreams
wvlog.h
00001 /* -*- Mode: C++ -*-
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  *
00005  * A generic data-logger class with support for multiple receivers.  If
00006  * no WvLogRcv objects have been created (see wvlogrcv.h) the default is
00007  * to log to stderr.
00008  * 
00009  * WvLog supports partial- and multiple-line log messages.  For example,
00010  *        log.print("test ");
00011  *        log.print("string\nfoo");
00012  * will print:
00013  *        appname(lvl): test string
00014  *        appname(lvl): foo
00015  */
00016 #ifndef __WVLOG_H
00017 #define __WVLOG_H
00018 
00019 #include "wvstream.h"
00020 #include <errno.h>
00021 #ifdef _WIN32
00022 typedef int pid_t;
00023 #endif
00024 
00025 class WvLog;
00026 
00027 // a WvLogRcv registers itself with WvLog and prints, captures,
00028 // or transmits log messages.
00029 class WvLogRcvBase
00030 {
00031     friend class WvLog;
00032 protected:
00033     const char *appname(WvStringParm log) const;
00034     virtual void log(WvStringParm source, int loglevel,
00035                      const char *_buf, size_t len) = 0;
00036 
00037 private:
00038     static void cleanup_on_fork(pid_t p);
00039     static void static_init();
00040 
00041 public:
00042     bool force_new_line;
00043     WvLogRcvBase();
00044     virtual ~WvLogRcvBase();
00045 };
00046 
00047 
00048 DeclareWvList(WvLogRcvBase);
00049 
00050 typedef wv::function<WvString(WvStringParm)> WvLogFilter;
00051 
00056 class WvLog : public WvStream
00057 {
00058     friend class WvLogRcvBase;
00059 public:
00060     enum LogLevel {
00061         Critical = 0,
00062         Error,
00063         Warning,
00064         Notice,
00065         Info,
00066         Debug, Debug1=Debug,
00067         Debug2,
00068         Debug3,
00069         Debug4,
00070         Debug5,
00071         
00072         NUM_LOGLEVELS
00073     };
00074     WvString app;
00075 
00076 protected:
00077     LogLevel loglevel;
00078     static WvLogRcvBaseList *receivers;
00079     static int num_receivers, num_logs;
00080     static WvLogRcvBase *default_receiver;
00081     WvLogFilter* filter;
00082 
00083 public:
00084     WvLog(WvStringParm _app, LogLevel _loglevel = Info,  
00085             WvLogFilter* filter = 0);
00086     WvLog(const WvLog &l);
00087     virtual ~WvLog();
00088     
00090     virtual bool isok() const;
00091     
00092     /* always writable */
00093     virtual void pre_select(SelectInfo &si);
00094     virtual bool post_select(SelectInfo &si);
00095 
00100     WvLog &lvl(LogLevel _loglevel)
00101         { loglevel = _loglevel; return *this; }
00102     
00104     size_t operator() (LogLevel _loglevel, WvStringParm s)
00105     { 
00106         LogLevel l = loglevel; 
00107         size_t x = lvl(_loglevel).write(filter ? (*filter)(s) : s);
00108         lvl(l);
00109         return x;
00110     }
00111     
00113     size_t operator() (LogLevel _loglevel, WVSTRING_FORMAT_DECL)
00114     { 
00115         LogLevel l = loglevel;
00116         size_t x;
00117         if (filter)
00118             x = lvl(_loglevel).print((*filter)(WvString(WVSTRING_FORMAT_CALL)));
00119         else
00120             x = lvl(_loglevel).print(WVSTRING_FORMAT_CALL);
00121         lvl(l);
00122         return x;
00123     }
00124     
00129     size_t operator() (WvStringParm s)
00130         { return WvStream::operator()(filter ? (*filter)(s) : s); }
00131     size_t operator() (WVSTRING_FORMAT_DECL)
00132         { return (filter ? 
00133             WvStream::operator()((*filter)(WvString(WVSTRING_FORMAT_CALL))) :
00134             WvStream::operator()(WVSTRING_FORMAT_CALL) );
00135         }
00136     
00142     WvLog split(LogLevel _loglevel) const
00143         { return WvLog(app, _loglevel, filter); }
00144     
00149     virtual size_t uwrite(const void *buf, size_t len);
00150     
00152     void perror(WvStringParm s)
00153         { print("%s: %s\n", s, strerror(errno)); }
00154 
00155 public:
00156     const char *wstype() const { return "WvLog"; }
00157 };
00158 
00159 
00160 #endif // __WVLOG_H