Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

wvlog.h

Go to the documentation of this file.
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 
00022 class WvLog;
00023 
00024 // a WvLogRcv registers itself with WvLog and prints, captures,
00025 // or transmits log messages.
00026 class WvLogRcvBase
00027 {
00028     friend class WvLog;
00029 protected:
00030     const char *appname(const WvLog *log) const;
00031     virtual void log(const WvLog *source, int loglevel,
00032                      const char *_buf, size_t len) = 0;
00033 public:
00034     WvLogRcvBase();
00035     virtual ~WvLogRcvBase();
00036 };
00037 
00038 
00039 DeclareWvList(WvLogRcvBase);
00040 
00041 
00042 /**
00043  * A WvLog stream accepts log messages from applications and forwards them
00044  * to all registered WvLogRcv's.
00045  */
00046 class WvLog : public WvStream
00047 {
00048     friend class WvLogRcvBase;
00049 public:
00050     enum LogLevel {
00051         Critical = 0,
00052         Error,
00053         Warning,
00054         Notice,
00055         Info,
00056         Debug, Debug1=Debug,
00057         Debug2,
00058         Debug3,
00059         Debug4,
00060         Debug5,
00061         
00062         NUM_LOGLEVELS
00063     };
00064     WvString app;
00065 
00066 protected:
00067     const WvLog *parent;
00068     LogLevel loglevel;
00069     static WvLogRcvBaseList receivers;
00070     static int num_receivers, num_logs;
00071     static WvLogRcvBase *default_receiver;
00072 
00073 public:
00074     WvLog(WvStringParm _app, LogLevel _loglevel = Info,
00075           const WvLog *par = NULL);
00076     WvLog(const WvLog &l);
00077     virtual ~WvLog();
00078 
00079     /** fd==-1, but this stream is always ok */
00080     virtual bool isok() const;
00081     
00082     /* always writable */
00083     virtual bool pre_select(SelectInfo &si);
00084 
00085     /**
00086      * change the loglevel.  This returns the object again, so you can
00087      * make convenient statements like log.lvl(WvLog::Warning).print(...)
00088      */
00089     WvLog &lvl(LogLevel _loglevel)
00090         { loglevel = _loglevel; return *this; }
00091     
00092     /** change the loglevel and then print a message. */
00093     size_t operator() (LogLevel _loglevel, WvStringParm s)
00094     { 
00095         LogLevel l = loglevel; 
00096         size_t x = lvl(_loglevel).write(s);
00097         lvl(l);
00098         return x;
00099     }
00100     
00101     /** change the loglevel and then print a formatted message */
00102     size_t operator() (LogLevel _loglevel, WVSTRING_FORMAT_DECL)
00103     { 
00104         LogLevel l = loglevel;
00105         size_t x = lvl(_loglevel).print(WVSTRING_FORMAT_CALL);
00106         lvl(l);
00107         return x;
00108     }
00109     
00110     /**
00111      * although these appear in WvStream, they need to be re-listed here
00112      * since the above operator()s caused them to be hidden
00113      */
00114     size_t operator() (WvStringParm s)
00115         { return WvStream::operator()(s); }
00116     size_t operator() (WVSTRING_FORMAT_DECL)
00117         { return WvStream::operator()(WVSTRING_FORMAT_CALL); }
00118     
00119     /**
00120      * split off a new WvLog object with the requested loglevel.  This way
00121      * you can have log at two or more levels without having to retype
00122      * log.lvl(WvLog::blahblah) all the time.
00123      */
00124     WvLog split(LogLevel _loglevel) const
00125         { return WvLog(app, _loglevel, this); }
00126     
00127     /**
00128      * we override the unbuffered write function, so lines also include the
00129      * application and log level.
00130      */
00131     virtual size_t uwrite(const void *buf, size_t len);
00132     
00133     /** a useful substitute for the normal C perror() function */
00134     void perror(WvStringParm s)
00135         { print("%s: %s\n", s, strerror(errno)); }
00136 };
00137 
00138 
00139 #endif // __WVLOG_H

Generated on Wed Dec 15 15:08:11 2004 for WvStreams by  doxygen 1.3.9.1