Main Page | Compound List | File List | Compound Members | File Members

Logger Class Reference

#include <Logger.h>

List of all members.

Public Types

enum  LogLevel { NOT_SET, DEBUG, ERROR, GARBAGE_TRACE }

Public Member Functions

 Logger (const char *logfileName, bool dbg)
 Logger (const Logger &rhs)
Logger getLogger (const char *klassName)
void log (const LogLevel level, const char *methodName, const char *message)

Static Public Member Functions

void setDebug ()
bool errorFound ()

Private Member Functions

 Logger (const char *klassName)
const char * getLocalTime (time_t aclock)
const char * getTimeStamp ()
bool openLogFile ()

Private Attributes

const char * className

Static Private Attributes

const char * logFileName = 0
FILE * pFile = 0
bool debug = false
bool mErrorFound = false


Detailed Description

When something goes wrong with the spam filter, it is very difficult to debug, since the software only runs when e-mail comes in and it then runs as its own process. The Logger supports debug tracing and error logging.

I have been using the Apache Jakarta Log4j for a large Java application at work and I considered using one of the C++ versions of Log4j. Log4j is great generating log files for large applications with many classes, but it seems overly complicated for a relatively simple program like the spam filter.

The Logger will always append error messages to a log file. If debug logging is turned on, the Logger will append debug messages to the log file. Debugging is turned on via a flag in the SpamFilterParams file.

Spammers tend to send spam in large blocks, so it is possible that two mail filter processes will be active at the same time. In this case they may both write to the log file at the same time. However, I have not actually observed this, in practice.

Notes on use

This class has a set of static state variables. These are shared by all instances of the class. Some of them (like the file name, and the debug variable) are initialized at static initialization time with the pLogger variable is initialized with a dynamically allocated Logger class.

Each class that uses the logger allocates its own instance that shares the static variables. The example below shows how this is done:

MailFilter::MailFilter(SpamParameters &params) { ... log = pLogger->getLogger("MailFilter");

Here log is a variable of type Logger. Calls to log messages pass a log level (either DEBUG or ERROR), the function name and a log message. Examples are shown below:

log.log(Logger::DEBUG, "MailFilter", "enter"); log.log(Logger::ERROR, "MailFilter", msg );

Definition at line 97 of file Logger.h.


Constructor & Destructor Documentation

Logger::Logger const char *  klassName  )  [inline, private]
 

Use this version of the constructor for the Logger that is created for a class' use.

Definition at line 143 of file Logger.h.

00143 : className( klassName ) {}

Logger::Logger const char *  logfileName,
bool  dbg
[inline]
 

Call this version of the constructor in the static initialization section.

The debug flag (dbg) can be set in the Logger constructor to turn on debugging during from the static constructor level. This was useful during early debugging, but is (hopefully) obsolete now that the software is more mature.

Definition at line 155 of file Logger.h.

References debug, and logFileName.

00157 {
00158   logFileName = logfileName;
00159   debug = dbg;
00160 }

Logger::Logger const Logger rhs  )  [inline]
 

Copy constructor, which copies the only non-static variable.

Definition at line 166 of file Logger.h.

References className.

00167 {
00168   className = rhs.className;
00169 } // Logger constructor


Member Function Documentation

bool Logger::errorFound  )  [static]
 

Returns:
true if an ERROR level message has been printed false othewise.

Definition at line 65 of file Logger.C.

References mErrorFound.

Referenced by MailFilter::MailFilter().

00066 {
00067   return mErrorFound;
00068 }

const char * Logger::getLocalTime time_t  aclock  )  [private]
 

Returns:
a string containing the local time and date.

Definition at line 74 of file Logger.C.

Referenced by getTimeStamp().

00075 {
00076   static char buf[128];
00077   struct tm *newtime;
00078   newtime = localtime( &aclock );  /* Convert time to struct */
00079 
00080   sprintf(buf, "%02d:%02d:%02d %02d/%02d/%04d",
00081           newtime->tm_hour, 
00082           newtime->tm_min, 
00083           newtime->tm_sec, 
00084           newtime->tm_mon, 
00085           newtime->tm_mday, 
00086           newtime->tm_year + 1900 );
00087   return buf;
00088 } // getLocalTime

Logger Logger::getLogger const char *  klassName  )  [inline]
 

Initialize a new Logger object. This uses the copy constructor.

Definition at line 175 of file Logger.h.

Referenced by MailBody::MailBody(), MailFilter::MailFilter(), main(), HeaderInfo::openTraceFile(), and SpamParameters::SpamParameters().

00176 {
00177   Logger l( klassName );
00178   return l;
00179 }

const char * Logger::getTimeStamp  )  [private]
 

Return the current local time and date. The format is:

HH:MM:SS MM/DD/YYYY

Definition at line 96 of file Logger.C.

References getLocalTime().

Referenced by log().

00097 {
00098   time_t aclock;
00099   time( &aclock );                 /* Get time in seconds */
00100   return getLocalTime( aclock );
00101 } // getTimeStamp

void Logger::log const LogLevel  level,
const char *  methodName,
const char *  message
 

Write log messages into the log file.

DEBUG level messages will only be written if the debug flag is true. ERROR level messages will always be written.

The errorFound true flag is set when an ERROR level log message is written.

Definition at line 142 of file Logger.C.

References className, debug, getTimeStamp(), mErrorFound, openLogFile(), and pFile.

Referenced by MailHeader::addrContinues(), MailFilter::append_file(), MailHeader::checkAddressSection(), MailHeader::checkDomainAddrs(), MailHeader::checkFrom(), MailHeader::checkHeader(), MailFilter::checkMail(), MailHeader::checkReceived(), MailHeader::checkSubject(), MailBody::classifyMailSection(), MailFilter::copyToTempFiles(), MailFilter::error_append_file(), MailHeader::fillInSections(), MailFilter::isFromLine(), MailBody::mailBodyMsg(), MailFilter::MailFilter(), main(), HeaderInfo::openTraceFile(), MailHeader::parseContentType(), MailBody::processBySection(), MailBody::processTextBody(), MailFilter::readLine(), MailHeader::saveBoundary(), SpamParameters::SpamParameters(), and MailFilter::writeLine().

00145 {
00146   if ((level == DEBUG && debug) || (level == ERROR)) {
00147     if (openLogFile()) {
00148       char *pLevelName;
00149       if (level == DEBUG) {
00150         pLevelName = "DEBUG";
00151       }
00152       else if (level == ERROR) {
00153         pLevelName = "ERROR";
00154         mErrorFound = true;
00155       }
00156       fprintf(pFile, "%s %s %s::%s: %s\n",
00157               getTimeStamp(),
00158               pLevelName, 
00159               className, 
00160               methodName, 
00161               message );
00162       fflush(pFile);
00163     }
00164   }
00165 } // log

bool Logger::openLogFile  )  [private]
 

Open the log file if it is not currently open. If the log file is already open or the log file is successfully opened, the function will return true, otherwise the function will return false.

Multiple instances of the spam filter may run at the same time as the spammer scum send out blocks of spam. There is a slight possibility that the execution of two mail_filter processes will overlap. In this case only one instance may be allowed to access the log file and the openLogFile call will return false. In this case log messages will be lost.

Definition at line 117 of file Logger.C.

References logFileName, and pFile.

Referenced by log().

00118 {
00119   bool rslt = true;
00120   if (pFile == 0) {
00121     rslt = false;
00122     if (logFileName != 0) {
00123       const char *mode = "a"; // open for append
00124       if ((pFile = fopen(logFileName, mode)) != 0) {
00125         rslt = true;
00126       }
00127     }
00128   }
00129   return rslt;
00130 } // openLogFile

void Logger::setDebug  )  [static]
 

Turn debugging on

Definition at line 56 of file Logger.C.

References debug.

Referenced by main().

00057 {
00058   debug = true;
00059 }


Member Data Documentation

const char* Logger::className [private]
 

An instance variable containing the class name that log messages are being generated for

Definition at line 115 of file Logger.h.

Referenced by log(), and Logger().

bool Logger::debug = false [static, private]
 

debug == true, DEBUG level messages are written to log file. debug == false, only ERROR level message will be written to the log file.

Definition at line 49 of file Logger.C.

Referenced by log(), Logger(), and setDebug().

const char * Logger::logFileName = 0 [static, private]
 

log file name

Definition at line 45 of file Logger.C.

Referenced by Logger(), and openLogFile().

bool Logger::mErrorFound = false [static, private]
 

mErrorFound == true: An ERROR level message has been written to the log file

Definition at line 50 of file Logger.C.

Referenced by errorFound(), and log().

FILE * Logger::pFile = 0 [static, private]
 

log FILE pointer

Definition at line 47 of file Logger.C.

Referenced by log(), and openLogFile().


The documentation for this class was generated from the following files:
Generated on Sat Mar 27 13:07:38 2004 for Mail Filter by doxygen 1.3.3