Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members

TraceLogger.h

Go to the documentation of this file.
00001 #ifndef TRACELOGGER_H 00002 #define TRACELOGGER_H 00003 00004 #include <PropsFile.h> 00005 #include <exception> 00006 #include <string> 00007 #include <iostream> 00008 #include <fstream> 00009 #include <set> 00010 #include <vector> 00011 #include <PtMutex.h> 00012 00013 BOREALIS_NAMESPACE_BEGIN; 00014 00015 /* 00016 Provides a thread-safe logger to help in debugging programs. It takes the 00017 following from the supplied PropsFile: 00018 00019 00020 OUTPUT CHANNEL CONTROL 00021 ====================== 00022 All of the following properties are mandatory: 00023 <TraceLogger.output.file type="string" value="foo"/> 00024 <TraceLogger.output.stdout type="bool" value="bar"/> 00025 <TraceLogger.output.stderr type="bool" value="baz"/> 00026 00027 The file-related property has a special meaning: The file 'foo' will be 00028 written to iff 'foo' is not the empty string. If 'foo' can't be written to 00029 for some reason (and isn't the empty string), failed attempts to write to 00030 it will be mentioned on stdout/stderr (if each is enable for logging). 00031 00032 If the specified log file can't even be *initially* opened, then the c'tor 00033 will throw an exception. 00034 00035 If a log file is specified, this TraceLogger might keep an open handle on 00036 the file up until this object's destructor returns. 00037 00038 The following property is optional: 00039 <TraceLogger.output.lineAfterEntries type="bool" value="foo"/> 00040 00041 Whenn it's defined with a value of 'T' (true), a blank line will follow each 00042 logfile entry. The intention of this feature is to make log files easier to 00043 read by humans. 00044 00045 LOG MESSAGE FILTERING 00046 ===================== 00047 Additional optional properties can be defined, to describe which set of 00048 logging attempts should actually be sent to the logger's outputs. These 00049 must be of the form: 00050 <TraceLogger.group.foo type="bool" value="bar"/> 00051 00052 In this case, 'foo' can be any non-empty string. A calls to the 'log' method 00053 will appear on the logger's output iff the 'group' parameter to the 'log' 00054 method corresponded to one of these properties *and* the property's value 00055 is 'T'. 00056 00057 NOTE: The group-name may not be longer than 'MAX_GROUP_NAME_LEN' characters. 00058 The main reason for this restriction is for logfile formatting. 00059 00060 For example: 00061 <TraceLogger.group.StorageMgr.PageFaultEvent type="bool" value="T"> 00062 00063 myLogger.log("StorageMgr.PageFaultEvent", "Page eviction occured"); 00064 */ 00065 class TraceLogger 00066 { 00067 public: 00068 enum { MAX_GROUP_NAME_LEN = 20 }; // Value choice is arbitrary/aesthetic 00069 00070 // Reads the specified props file, but doesn't keep a reference to it. 00071 TraceLogger(const PropsFile & props) 00072 throw (exception); 00073 00074 // Just don't call this when an invocation if 'log(...)' is pending. 00075 virtual ~TraceLogger(); 00076 00077 // Logs the specified message according to the rules stated above. Concurrent 00078 // calls to this method are threadsafe and have the normal linearization 00079 // qualities. 00080 // 00081 // Each logged message is immediately flushed. 00082 // 00083 // Don't include cr/lr characters in 'message'. If you want a multi-line 00084 // log message, use the verion of log(...) that takes a vector<string> 00085 // argument. 00086 void log(const string & group, const string & message) 00087 throw (exception); 00088 00089 // Atomically logs numerous lines of text. 00090 void log(const string & group, const vector<string> & messages) 00091 throw (exception); 00092 00093 private: 00094 static const string timeHeader; 00095 static const string pidHeader; 00096 static const string tidHeader; 00097 static const string groupHeader; 00098 static const string msgHeader; 00099 00100 bool _logToStdout; 00101 bool _logToStderr; 00102 bool _lineAfterEntries; 00103 00104 ofstream * _pLogfileStream; // NULL if the user didn't want one. 00105 00106 // Lists all of the values for the log(...) method's 'group' parameter that 00107 // will cause the corresponding message to be logged. 00108 set<string> _loggedGroups; 00109 00110 // Max # of chars needed to textually represent a TID/PID 00111 size_t _maxTidWidth; 00112 size_t _maxPidWidth; 00113 00114 const char * _pszTimeFormat; 00115 size_t _formattedTimeWidth; 00116 00117 PtMutex _mtx; 00118 00119 size_t _groupColumnWidth; 00120 00121 // The string that's used to cause message lines in multi-line messages to 00122 // start at the proper column. 00123 string _multiLineMsgPadding; 00124 00125 void writeColumnHeaderLines() 00126 throw (exception); 00127 00128 // Assumes the parameters have been validated, and that the caller currently 00129 // holds _mtx. 00130 string formatMsgMajorLine(const string & group, const string & messageLine) 00131 throw (exception); 00132 00133 // Assumes the parameters have been validated, and that the caller currently 00134 // holds _mtx. 00135 string formatMsgMinorLine(const string & messageLine) 00136 throw (exception); 00137 00138 00139 // Sends this one line of text to all of the logger's outputs. Assumes that the 00140 // caller currently holds _mtx's lock. 00141 void writeLineToOutputs(const string & line) 00142 throw (exception); 00143 00144 // Returns true iff a message from the specified log group really needs to be 00145 // logged. 00146 // 00147 // Will throw an exception if 'group' has in illegal value. 00148 inline bool mustLogMessage(const string & group) 00149 throw (exception); 00150 }; 00151 00152 BOREALIS_NAMESPACE_END; 00153 00154 #endif

Generated on Fri Nov 12 15:15:22 2004 for Borealis by doxygen 1.3.8