Need suggestions for a log class

Started by
8 comments, last by garyfletcher 18 years, 9 months ago
Im trying to implent some kind of logging system for my game so I can see where things go wrong. Problem is, something is very fuzzy about the way the program comminucates with the file. :P Not whole strings are written, sometimes the log file isnt cleaned when I start the program again... and so on. There a few classes who writes to the log so maybe thats where the problem is. Should I make the log thing into a class of its own? I failed to find any good log tutorial on google so I ask here. :) Can anyone give me suggestions of a good logging system? Not to advanced though. :P
Advertisement
evolutional and jollyjeffers just made quite an interesting article on the topic named Using XML Technologies For Enhancing Log Files and actually make a dynamic logging system that shows you only the log entries you want to see.
Rob Loach [Website] [Projects] [Contact]
I always liked HTML logging. That way you can put links to helpfiles, write tables, lists, etc.

I wrote a small article about that:
http://www.novanet.be/index.php?page=viewtutorial&tutor=SmartLogs

[edit]I would also put it in a class off course, this way you can pass a log as a parameter to another class.

The log could have streaming-like operators like "<<" or just regular members like:
WriteLn(...)
WriteValidatedLn(bool, ...)
WriteTable(vector)
NewLn()
...
[www.LifeIsDigital.net - My open source projects and articles.
Hi there, i would definatly make a own log class.

I don't know what exactly you wana log and what os/development environment you use. I work with windows/win32/vc++2003 atm and this is one thing i use to see errors while developing:
inline void printdbg(const char *str, ...){	char		text[256];								// Holds Our String	va_list		ap;										// Pointer To List Of Arguments	if (str == NULL)									// If There's No Text		return;											// Do Nothing	va_start(ap, str);									// Parses The String For Variables	vsprintf(text, str, ap);							// And Converts Symbols To Actual Numbers	va_end(ap);		OutputDebugString(text);}
The funtion prints stuff to the debug output window. Don't know if it is good though.
I'm not really sure what language you're writing in, but here's one that I use (well, most of it, it's missing most of the Write/WriteLine definitions, but those are easy to extrapolate from the one given) written in C#.

using System;using System.Collections.Generic;using System.IO;using System.Text;namespace Utilities{    public static class Logger    {        private static Dictionary<string, LogFile> logs = new Dictionary<string, LogFile>();        public static void AddLog(string filename, string logname)        {            logs.Add(logname, new LogFile(filename));        }        public static void CloseLog(string logname)        {            logs[logname].Close();            logs.Remove(logname);        }        public void Write(string format, object arg0, string logname)        {            logs[logname].Write(format, arg0);        }        private class LogFile : StreamWriter, IDisposable        {            public LogFile(string filename)                : base(File.Open(filename, FileMode.OpenOrCreate, FileAccess.Write))            {                this.AutoFlush = true;            }            #region IDisposable Members            public void Dispose()            {                Dispose(true);            }            protected override void Dispose(bool disposing)            {                base.Dispose(disposing);            }            #endregion        }        public static void CloseAll()        {            foreach (KeyValuePair<string, LogFile> f in logs)                f.Value.Close();            logs.Clear();        }    }}
You can also compliment existing logging mechanisms by doing the following:

#ifdef _DEBUG#define DEBUG_OUT(x) printf x#else#define DEBUG_OUT(x)#endif


Change printf to suite your particular logging system. Usage:

DEBUG_OUT(("%s happened %d times\n", strPtr, count));


This will reduce the need for #ifdef/#endif statements around logging code will/can completely remove logging for release builds. Just make sure that you use double parens at each side of DEBUG_OUT.
struct logging_interface{      virtual void   newtext(const char *)=0;      virtual ~logging_interface(){}};

I've done something like this.

Then have things you'd like to log deal with this class. The newtext can then be extended or changed to your heart's content [to the screen? to a file? to various files? prefixed with the current time?]
Another bit of logging would be to have a logging level set so that you can restrict or enable messages based on the current level you are set at within the application.

The level run level can be a runtime parameter passed into your main() function.

level 0 - no logging (no messages are written)
level 1 - only CRITICAL message are written
level 2 - WARNING and CRITICAL messages
level 3 - DEBUG, WARNING and CRITICAL messages

You can of course have as many levels as you want and do them in whatever order you like (3 - CRITICAL -> 1 - DEBUG, WARNING & CRITCAL)

Just a thought..:)
Gary.Goodbye, and thanks for all the fish.
Quote:Original post by garyfletcher
level 0 - no logging (no messages are written)
level 1 - only CRITICAL message are written
level 2 - WARNING and CRITICAL messages
level 3 - DEBUG, WARNING and CRITICAL messages


Bit fields also come in handy if you want to isolate logging of a specific set of objects or subsystems. You can also take it up a notch and broadcast UDP packets containing all log output. Very handy for remote logging and/or creating a monitor app that allows you to select which logging to display rather than always changing flags in the source or headers.
Quote:
Quote:
Original post by garyfletcher
level 0 - no logging (no messages are written)
level 1 - only CRITICAL message are written
level 2 - WARNING and CRITICAL messages
level 3 - DEBUG, WARNING and CRITICAL messages



Bit fields also come in handy if you want to isolate logging of a specific set of objects or subsystems. You can also take it up a notch and broadcast UDP packets containing all log output. Very handy for remote logging and/or creating a monitor app that allows you to select which logging to display rather than always changing flags in the source or headers.


I didn't mean that you should change code and re-compile but pass the debug message level in at run time to main(), in fact I believe that's what I said..:).

The remote logging sounds like a good idea though if your game is deployed over the web:)
Gary.Goodbye, and thanks for all the fish.

This topic is closed to new replies.

Advertisement