Jump to content
  • Advertisement
Sign in to follow this  
schupf

Logging class (without singleton?)

This topic is 3251 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

Hello, Im writing a little engine which will have this structure: I have a Root object, which acts kinda as a factory. Here is an (pseudo code) example:
Root r = createRoot();
SceneManager sc = r->createSceneManager();
Entity e = sc->createEntity("robot.mesh");
Now I need to log at various parts in my engine (in Root methods, SceneManager methods, Entity Methods) and so on. I wonder how I could implement this logging. Currently I only see 2 possibilites: The Root object stores a pointer to a Logger and passes the Logger to all created objects. Thus EVERY class whose methods ever need to log something needs a pointer to the logger. Another problem is that all created objects wouldnt recognice is if I did change the logger. The other possibility is to make the logger a singleton. Then every class could just log with Logger::getInstance().Log(...). The problem with this approach is: Well, I just dont like singletons and try to avoid them whenever I can. Any suggestions how I could provide a logging feature for all my classes are highly appreciated!

Share this post


Link to post
Share on other sites
Advertisement
A global? Less work than either of your alternatives. Yup, same old approach the Standard C++ Library uses for std::cout, std::cerr and std::clog.

Share this post


Link to post
Share on other sites
Just create some log object at the appropriate scope and use it. This is all I do, on those rare cases where I need logging.

#include "Log.h"

void SomeFunction() {
Log log("somefile");
log << "Hello there."
}

(Yes, the obvious implementation involves opening and closing the backing file often. You can work around this, or just eat the cost since logging is 'slow' anyway, and you probably want to flush the stream constantly regardless to ensure that you always get the most updated file contents, especially if you're logging around a crash).

Share this post


Link to post
Share on other sites
I also thought about a global variable. But... aren't global variables even more evil than singletons?

Share this post


Link to post
Share on other sites
Quote:

I also thought about a global variable. But... aren't global variables even more evil than singletons?

No, they're less evil.

Logging is a mostly-trivial problem. Do the simplest thing that works for you. Don't over-engineer the thing.

Share this post


Link to post
Share on other sites
I've written a handful of loggers. They end up a single, globally defined object, every time.

This is because, in my cases at least, logging has always been a debugging aid, not an integrated part of the functionality. I might decide that any part of the code, at any level, has a sudden need to log. The next day it will be different. As a result, adding logging code doesn't fit neatly into a design process. It's not compartmentalized. And that's a situation that often drives the creation of singletons.

If what you're calling logging is really an audit trail, something that's a critical part of the application and not something you'll ultimately turn off, then it deserves a more formal place in the design.

Share this post


Link to post
Share on other sites
Hehe, yes thats true.

I can't use your approach jpetrie, because my logger is a little bit more compley. For example I can add various Appenders to my logger and thus creating a logger everytime I need to log is no option.

So I guess I just go for the global variable approach.

Share this post


Link to post
Share on other sites
When people say that "globals are evil", they really mean shared mutable state. Read only constants aren't evil. The logger, which really has a "write only" interface, is tolerable as a global IMO.

Share this post


Link to post
Share on other sites
Quote:
Original post by ScottMayo
If what you're calling logging is really an audit trail, something that's a critical part of the application and not something you'll ultimately turn off, then it deserves a more formal place in the design.


Well, I think it just a nice feature to get some consistent feedback from the engine. I will definitely use logging in debug mode AND release mode, though my logging in debug mode will be more verbose (in debug mode I also log the function, source file etc).
Nonetheless I still tend to use a global variable (because passing logger pointers to billions of objects isnt elegant either and I just hate singletons;)

Share this post


Link to post
Share on other sites
Hm, one more question that is related to my problem:
Sooner or later I will need some additional classes which are heavily access from various places. For example a class "TextureManager" which loads and pools textures.
Would you make such "complex" classes like TextureManager also accessible through a global variable, or would you make it a singleton or ...?

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!