I reply to myself. What you need: you need to create a new custom appender and set it as appender in the first level logger, than in the code you can clone the appender. As bonus, in your custom appender you can manage delayed file creation so no more empty files if no log are present ;) Here the code:
class MyLogger {
private:
MyLogger() {
}
public:
static void cloneParentLogger(const std::string& parentName,
const std::string& parentAppenderName, LoggerPtr& child,
const std::string& childName) {
std::string newName = parentName + "." + childName;
LoggerPtr loggerMst = LoggerPtr(Logger::getLogger(parentName));
Appender* app = loggerMst->getAppender(parentAppenderName);
app->close();
AppenderPtr newAppender = app->getClass().newInstance();
if (newAppender->instanceof(FileAppender::getStaticClass())) {
Appender* p = newAppender;
reinterpret_cast<FileAppender*>(p)->setFile(newName + ".log");
}
child = LoggerPtr(Logger::getLogger(newName));
newAppender->setName(childName);
newAppender->setLayout(app->getLayout());
Pool p;
newAppender->activateOptions(p);
child->addAppender(newAppender);
child->setAdditivity(false);
}
};
class Foo {
private:
LoggerPtr logger;
public:
Foo(int id) {
MyLogger::cloneParentLogger("foo", "R1", logger, std::to_string(id));
}
const LoggerPtr& getLogger() const {
return logger;
}
};
Properties file
# Set root logger level to DEBUG and its only appender to A1.
log4j.rootLogger=DEBUG
log4j.logger.foo=DEBUG, R1
log4j.appender.R1=DelayedRollingFileAppender
log4j.appender.R1.MaxFileSize=50MB
log4j.appender.R1.MaxBackupIndex=1
log4j.appender.R1.layout=org.apache.log4j.PatternLayout
log4j.appender.R1.layout.ConversionPattern=%p %t %c - %m%n
Custom appender with delayed file creation:
#ifndef DELAYEDROLLINGFILEAPPENDER_H_
#define DELAYEDROLLINGFILEAPPENDER_H_
#include <log4cxx/rollingfileappender.h>
#include <log4cxx/helpers/object.h>
#include <log4cxx/helpers/pool.h>
#include <log4cxx/helpers/classregistration.h>
#include <log4cxx/logstring.h>
namespace log4cxx {
class DelayedRollingFileAppender: public RollingFileAppender {
private:
bool firstAppend;
LogString file;
bool app;
bool bufferedIo;
size_t bufferSize;
public:
//DECLARE_LOG4CXX_OBJECT(DelayedRollingFileAppender)
class ClazzDelayedRollingFileAppender: public helpers::Class {
public:
ClazzDelayedRollingFileAppender() :
helpers::Class() {
}
virtual ~ClazzDelayedRollingFileAppender() {
}
virtual LogString getName() const {
return LOG4CXX_STR("DelayedRollingFileAppender");
}
virtual helpers::ObjectPtr newInstance() const {
return new DelayedRollingFileAppender();
}
};
virtual const helpers::Class& getClass() const;
static const helpers::Class& getStaticClass();
static const helpers::ClassRegistration& registerClass();
DelayedRollingFileAppender();
virtual ~DelayedRollingFileAppender();
virtual void append(const spi::LoggingEventPtr& event,
helpers::Pool& pool1);
virtual void setFile(const LogString& file, bool append, bool bufferedIO,
size_t bufferSize, helpers::Pool& p);
};
} /* namespace log4cxx */
#endif /* DELAYEDROLLINGFILEAPPENDER_H_ */
Cpp file:
#include "DelayedRollingFileAppender.h"
#include <log4cxx/writerappender.h>
#include <log4cxx/helpers/fileoutputstream.h>
#include <log4cxx/helpers/bufferedwriter.h>
namespace log4cxx {
using namespace helpers;
//IMPLEMENT_LOG4CXX_OBJECT(DelayedRollingFileAppender)
const ::log4cxx::helpers::Class& DelayedRollingFileAppender::getClass() const {
return getStaticClass();
}
const ::log4cxx::helpers::Class& DelayedRollingFileAppender::getStaticClass() {
static ClazzDelayedRollingFileAppender theClass;
return theClass;
}
const helpers::ClassRegistration& DelayedRollingFileAppender::registerClass() {
static helpers::ClassRegistration classReg(
DelayedRollingFileAppender::getStaticClass);
return classReg;
}
namespace classes {
const ::log4cxx::helpers::ClassRegistration& DelayedRollingFileAppenderRegistration =
DelayedRollingFileAppender::registerClass();
}
DelayedRollingFileAppender::DelayedRollingFileAppender() {
firstAppend = true;
this->app = false;
this->bufferSize = 0;
this->bufferedIo = false;
}
DelayedRollingFileAppender::~DelayedRollingFileAppender() {
}
void DelayedRollingFileAppender::append(const spi::LoggingEventPtr& event,
helpers::Pool& pool1) {
if (firstAppend) {
firstAppend = false;
FileAppender::setFile(file, app, bufferedIo, bufferSize, pool1);
}
WriterAppender::append(event, pool1);
}
void DelayedRollingFileAppender::setFile(const LogString& file, bool append,
bool bufferedIO, size_t bufferSize, helpers::Pool& p) {
this->file = file;
this->app = append;
this->bufferSize = bufferSize;
this->bufferedIo = bufferedIO;
OutputStreamPtr outStream;
try {
outStream = new FileOutputStream("/dev/null", false);
} catch (IOException& ex) {
throw;
}
WriterPtr newWriter(createWriter(outStream));
if (bufferedIo) {
newWriter = new BufferedWriter(newWriter, bufferSize);
}
setWriter(newWriter);
}
} /* namespace log4cxx */