WvStreams
|
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