One way to make this efficient is to have a fixed sized (to avoid dynamic memory overhead) internal buffer ... say 2-10KB in size (remember 4 lines at 255 is 1KB) and simply keep an index .. when the index gets to the end ... open the file ... copy the whole buffer in one call ... reset the index ... close the file.
In BeOS this is totally unnessesary ... the journalled file system retains everything .. if i send a byte to an open file ... then kill my program or pull power out of the socket ... when i reboot .. that byte is in the file ... neat huh
The 2 versions for windows are as follows ... the simple one .. which has a constructor which takes a file name and a logging threashold (so unimportant messages dont get logged) ... and a log method which takes the following: LogType (exception, debug data, execution trace, message), LogSeverity(the number that determines if the log should get loged at current log level), Source Module(the module of code in which the log call resides .. duh),LogDetails(a string which contains the specific information for this particular log). It is worth mentioning that these 4 values comprise a class I call LogEvent ... which represents a simple entity to log to the file .. and this class is derived from my Exception base class ...so you can do this
; assume EXCEPTION is an enum value for the EventType; assume MAJOR_EXCEPTION is a #define for a numeric constantif(!ProcessInput()) throw LogEvent(EXCEPTION,MAJOR_ERROR,"InputServer","ProcessInput() failed");
then ... if that exception gets handled ...good ...if not ... when you get out to the main catch block ...you can not only see what the error was ..but its fairly easy to go from the log file right to the subsection of you program that might have throw it and do a grep or FindInFiles for the message string "ProcessInput() failed"
When runtime efficiency becomes an issue ... you replace the 3rd and 4th parameters with 32 bit int .. which you define in a central location ... and then use #defines ...so it looks like this:
LogEvent(EXCEPTION,FATAL_ERROR,MODULE_IO,EXP_PROCESS_INPUT_FAILED);
so you can still see all the details right in the code ... but only 4 ints are being created and passed around the program ... helps avoid really large string data areas and/or unneccesary dynamic memory allocation.
The second windows logging module I have is identical, but adds named block nesting to the log ... this stuff is useless in multithreaded code ... but it works great for people not yet using threads.
I also have additional heavyweight stuff in a debug only version .. which can have different logging levels set based on source module ... or turn on and off logging of certain types of logs (such as ... turn DebugInfo logging off....) ... but this overhead is too great to leave in release code ... so i don''t use it much. I''ve found all you really need is that single discriminating threashold ... and in debug only senerios ... the ability to tell the logger to additionally log everything from just one specified module ... that''s it ...
Whew ..that was a long post ..I''ll clean the code up this week/weekend .. if someone can just tell me how to make it availible ...I will .. it is thouroughly tested ... But I''m only going to post the easy to use simple version .. don''t want any confusing support headaches - and it''s what I use in real code anyway.