- I need to be able to create multiple instances of the logger so I can create log files for each area of my engine.
- I need to be able to differentiate between normal debug messages and error messages when I'm reviewing the log.
- I need to be able to disable logging across the system at compile time.
class LoggerNothing too earth shattering here. To use the logger, create an instance then call OpenLog with the filename of the log file you want created. One note you need to make here is that if you are creating files in another directory make sure that directory exists. C++ won't create the directory for you if it doesn't.
{
//Fields
FILE* file; //File the log is saved to
//Methods
void CloseFile(); //Closes the logging file
public:
//Constructor/Destructors
Logger(){file = NULL;}
~Logger();
//Methods
bool OpenLog(char* filename); //Opens the log with the given filename
void Write(char* msg, ...); //Writes a normal message to the log
void WriteError(char* msg, ...); //Writes the message to the log and flags it as error
};
I'm rather proud of the write methods. As you can see they use variable arguments which is something I've never done before. This will allow me to use formatting in the messages I send to the log, instead of either having to create the formatted message before I send it to the logger or adding a write method for every combo of parameters I need. Here are the guts of Write:
void Logger::Write(char *msg, ...)WriteError is almost exactly the same except it adds "Error!!!!!!" to the message so you can differentiate error messages in the log from normal messages. The key to the whole operation is vfprintf. This method allows me to just pass the va_list right in without caring what's actually in it. Also you can see that I'm checking for the definintion of LOGGING_ON. Commenting out that defininition which lives in Logger.h will turn off logging system wide at compile time.
{
#ifdef LOGGING_ON
//Get the variable arguments
va_list listPointer;
va_start( listPointer, msg );
//Get the current time
boost::posix_time::ptime t(boost::posix_time::second_clock::local_time());
std::string time = boost::posix_time::to_simple_string(t);
//Write time
fprintf(file,"[%s] ",time.c_str());
//Write the msg
vfprintf(file,msg,listPointer);
//End the line
fprintf(file,"\n");
//flush the file
fflush(file);
#endif
}
The one area where this logger fails is that it is not thread safe. If I ever did plan on adding multiple threads that wrote to the same log file, this wouldn't work very well because there exists the possibility that the two threads would be writing to the log at the same time causing some jumbled log messages. Right now I don't plan on adding multi-threading to my engine, but if I do, I'll need to revisit this.
Now that I have logging in place, my next step is to come up with a consitent and elegent way of handling exceptions. This probably isn't going to be a new class that I write, but instead a standard for how I write all code. I've got a little research to do, but as always, I'll let you know how it goes.
References
Here are some thinks to sites that helped me develop the logger:- http://www.gamedev.net/reference/snippets/features/stlLogSnippet/ : This article gave me the idea for adding the time stamp
- http://bobobobo.wordpress.com/2008/01/28/how-to-use-variable-argument-lists-va_list/: This blog post explained how to use variable argument lists
No comments:
Post a Comment