Jump to content
  • Advertisement
Sign in to follow this  
colinisinhere

Making a logger accessable to all classes?

This topic is 5055 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I wrote a logger class, and it works fine... but, how can i make this logger accessable to all of the classes in my project? are there any good tutorials on coding loggers? thanks!

Share this post


Link to post
Share on other sites
Advertisement
There's two ways to do this.

One is to do what Telastyn says, and use the
"extern" keyword for each of your files


logger g_logger in your main file, then any other file that uses it, use
extern logger g_logger

to declare it.
--
The other, more OO way is to use a flywheel / singleton.

Each class will assume it owns it's own verson of your logger, but that logger points to a single instance of logger. There's a singleton tutorial on this website.

Share this post


Link to post
Share on other sites
Instead of having a single global Logger object, you could make the Logger class a singleton:


class Logger
{
public:

// The single Logger object
static Logger logger;

// ...

private:

// Make constructors private to prevent object construction
Logger();
Logger(const Logger&);

// ...
};



Note that this is only a very simple way to implement a singleton, and is definitely not the best way to do things. If you haven't already, you should read up on singletons.

Share this post


Link to post
Share on other sites
One of the ways I sometimes like to handle singletons is through a "handle" which you use it through:

template <typename SingletonT> class Singleton
{
static SingletonT singleton;
public:
static SingletonT & operator*( void ) { reutrn singleton; }
static SingletonT * operator->( void ) { return &singleton; }
};
template <typename SingletonT> SingletonT Singleton::singleton;

class MySingletonClass
{
//...
};
typedef Singleton< MySingletonClass > MySingleton;

void function_that_uses_singleton ( void )
{
MySingleton mysingleton;
mysingleton->CallFunction();
(*mysingleton).CallFunction();
}

Share this post


Link to post
Share on other sites
wow, thats tricky.... Ive been trying to get it working, but I got a small problem when compiling on the overload operators lines:

c:\Documents and Settings\Colin\My Documents\Colin's Projects\Narcotik\CSingleton.h(15): error C2802: static member 'operator *' has no formal parameters
c:\Documents and Settings\Colin\My Documents\Colin's Projects\Narcotik\CSingleton.h(15): error C2333: 'CSingleton<SingletonT>::operator`*'' : error in function declaration; skipping function body
c:\Documents and Settings\Colin\My Documents\Colin's Projects\Narcotik\CSingleton.h(16): error C2801: 'operator ->' must be a non-static member
c:\Documents and Settings\Colin\My Documents\Colin's Projects\Narcotik\CSingleton.h(16): error C2333: 'CSingleton<SingletonT>::operator`->'' : error in function declaration; skipping function body


Any idea?

Share this post


Link to post
Share on other sites
operator -> and operator * cannot be statics, however the error I recall is something informing you of that. Possibly the templates are messing with the compiler's errors or something, but I am sure that operator -> and operator * can't be statics.

edit: Well DUUUUUUUUUUUUUUUUUUUURRRRR it has it right there, I must be blind. sorry for the stupidity.

Share this post


Link to post
Share on other sites
my logger is not OO, and i dont think it needs to be!
This is mutch cleaner!

iLog.h

#define ILOGFILENAME "iLog.txt"

iLogInit(bool do_we_log);
iLog(char *c);
iLogNum(float f);

iLog.cpp

bool log;

iLogInit(bool do_we_log){
log = do_we_log;
//creates/clears the log file
};
iLog(char *c){
if(!log)return;
//opens the file, and logs the string (0-terminated)
};
iLogNum(float f){
if(!log)return;
//opens the file, and logs the number(converted to string)
};

This is so easy and clean, only include iLog.h anywhere you want to log something, no globals, no templates, no singeltons, just a simple logger... Its slow, but you dont want to log something that runs 1000000 times a sec, no problem....
You can easely create a macro, witch uses the _LINE_ and _FILE_ strings automaticly, and so on...

Share this post


Link to post
Share on other sites
Using a singleton the way you suggest instead of a global is just syntactic difference IMO, it's not more OO or anything. As long as you're not actually passing a logger instance (in this case: the only instance) to each user of the logger, you're just doing global variables with different syntax (which is not necessarily bad).

@uncutno:
It's not a good idea to open the file, write and close in each logger call. This'll reduce performance, especially when outputting complex data.

Share this post


Link to post
Share on other sites
Q: Coder
It's not a good idea to open the file, write and close in each logger call. This'll reduce performance, especially when outputting complex data.

This is the cons of this method.

The pros:
Its bullit safe, if your app craches, the file is closed, and the log file wont be touched, you got simple noOO functioncalls instead of a singelton... Why do we need a singelton in this problem? The logger dont need to have any stored variables?

If you miss the Init func, the new log will be added to the old log, no problem.

If i understand this right, there is no reason for a log file to be 1 MB large, you are suposed to read it.... If you load 1000000 enteties from a file, you are only interested in the ones that messed things up. add a logical filter around the log filter!

I use my logfile for testing, and in my app, you have to press a key combination at the start for it to start to log, i dont want end users to se the logfile, but they can if needed!

If you use the logger all the time, you get alot of reading ahead, my logger can easely produce hundreds of pages in seconds..

If you got this supercomplex data you want to log, add the func:
iLogSuperComplexData(SuperComplexDataClass *a);
Now you got all the bennefits!

My argument is: dont optimize or overcomplex things because of speed or design when you dont need to... a logger is a perfect example of "dont need to"...

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!