4

After searching for what feels far too long, I decided to ask this simple question on stackoverflow: How do I create a custom Layout for log4cplus (1.1.2)? The closest related question is How do I add a custom filter in log4cplus? where the author adds the new class directly into the log4cplus directory (or uses log4cplus namespace?). I do not have this option as the log4plus headers and libraries are installed independently (and simply setting the namespace to log4cplus does not work either.

What I tried is a minimal example inheriting from log4cplus::PatternLayout:

namespace myNameSpace {
  class LOG4CPLUS_EXPORT MyPatternLayout: public ::log4cplus::PatternLayout {
    public:
       MyPatternLayout(const log4cplus::tstring& pattern);
       MyPatternLayout(const log4cplus::helpers::Properties& properties);
      ~MyPatternLayout();
    private:
      // Disallow copying of instances of this class
      MyPatternLayout(const MyPatternLayout&);
      MyPatternLayout& operator=(const MyPatternLayout&);
};
}

I expect that LOG4CPLUS_EXPORT takes care of registering my class to the log4cplus framework so I can use it in the configuration file. However, adding

log4cplus.appender.STDOUT.layout=myNameSpace::MyPatternLayout

results in an error:

log4cplus:ERROR Cannot find LayoutFactory: "myNameSpace::MyPatternLayout"

So how do I register a custom Layout/Appender?

Community
  • 1
  • 1
DragonTux
  • 732
  • 10
  • 22

1 Answers1

2

After trying many things, it boils down to one simple entry that has to be put after log4cplus::initialize(); and before log4cplus::PropertyConfigurator::doConfigure("<path to config file");. If you want to add the new Layout in the log4cplus namespace you can simply

//example1
log4cplus::initialize();
// register our stuff
log4cplus::spi::LayoutFactoryRegistry& reg = log4cplus::spi::getLayoutFactoryRegistry();
LOG4CPLUS_REG_LAYOUT(reg, MyPatternLayout);
log4cplus::PropertyConfigurator::doConfigure(Logger::mConfigFile);

or, if you want to use your own namespace

 //example2
 log4cplus::initialize();
 // register our stuff
 log4cplus::spi::LayoutFactoryRegistry& reg = log4cplus::spi::getLayoutFactoryRegistry();
 LOG4CPLUS_REG_PRODUCT (reg, "myNamespace::", MyPatternLayout, myNamespace::, log4cplus::spi::LayoutFactory);
 log4cplus::PropertyConfigurator::doConfigure(Logger::mConfigFile);

You can then use the layout in the config as

log4cplus.appender.STDOUT.layout = log4cplus::MyPatternLayout #example 1

or

log4cplus.appender.STDOUT.layout = myNamespace::MyPatternLayout #example 2

Simple enough, right? I wish the log4cplus had a documentation closer to the .log4j one

DragonTux
  • 732
  • 10
  • 22