0

I want to implement loggers in a C++ project that I am working on. I am wondering whether it would be better to implement a logger within each class individually, or to have a single logging interface and instantiate an instance of it in each class using the log4cxx libraries. I have a few loggers I would like to implement that would log events in existing classes.

In using a logging interface, I mean:

class Logger
{
private:
    log4cxx::LoggerPtr firstLogger(log4cxx::Logger::getLogger("first.log"));
    log4cxx::LoggerPtr secondLogger(log4cxx::Logger::getLogger("second.log"));
public:
    virtual void writeLogMessage(log4cxx::LoggerPtd logger, std::string msg);
};

Is what I am doing by passing that LoggerPtr the right way of doing it? Because I need to be able to select which logger to use.

Also, if creating a logging interface is better, can someone suggest a good example where one can see the nitty gritty of how to implement such an interface using log4cxx? So, for example, what needs to be private and what needs to be public etc.

Cornel Verster
  • 1,664
  • 3
  • 27
  • 55
  • Loggers is actually one place where the [singleton pattern](https://en.wikipedia.org/wiki/Singleton_pattern) is useful. Only have *one* instance of the logger, and use it when needed. – Some programmer dude Oct 19 '15 at 07:45
  • As for how to "select" which logger to use, you could wrap it in preprocessor macros, so you only write e.g. `LOG1("...")` and that macro will get the correct logger and call the write function with the logger. – Some programmer dude Oct 19 '15 at 07:46

1 Answers1

2

Yes, you shouldn't re-implement logging in your classes. It's repeating yourself and muddies the responsibilities of each class. Deciding which of the log4cxx::LoggerPtr to use sounds like something a calling class shouldn't have to care about and sounds like a decision that should be made the decision inside the Logger class

Don't create instances in your classes, however. Have an abstract class for your logger and pass it in to the constructors of your classes. Don't tie your classes to one logger implementation, rather pick it higher up or in your IOC configuration code. (I've never used IOC in C++, but this one looks good. Incidentally, will having multiple implementations of your logger solve your multiple log4cxx::LoggerPtr problem?

I would actually argue choosing how to format something that has happened into a readable std::string msg is the job of the logger, not the class. I would send some abstract Event class to the logger instead. I've been trying to remember what this pattern is called (if it is even a pattern), here's an example of it in another language

Nathan Cooper
  • 6,262
  • 4
  • 36
  • 75
  • Good answer, just a comment on C++ and IOC - manual IOC wiring is still there in C++ and an IOC _container_ (which is what you linked to) isn't _needed_ it just makes it easier (at least in C# and Java land - the C++ ones I've seen have not made me want to abandon the manual way :-)) – Johann Gerell Oct 19 '15 at 08:39
  • @JohannGerell Yeah. Tbh, none of the containers look fully ready. I only linked because this prompted me to do a bit of googling. I was a bit suprised Boost didn't have at least something. C++ is not my first language and it shows :D – Nathan Cooper Oct 19 '15 at 08:44