使用log4cxx

时间:2018-08-04 17:40:10

标签: c++ log4cxx

我想在代码中创建记录器的附加程序,但同时我想在属性文件上进行配置。我以这种方式创建了追加器:

class Foo {
private:
    LoggerPtr logger;
public:
    Foo(int id) {
        logger = LoggerPtr(Logger::getLogger("foo." + std::to_string(id)));
        RollingFileAppender* appender = new RollingFileAppender();
        appender->setAppend(true);
        appender->setMaxFileSize("1MB");
        appender->setMaxBackupIndex(1);
        appender->setFile("foo." + std::to_string(id) + ".log");
        PatternLayout* layOut = new PatternLayout();
        layOut->setConversionPattern(
                "%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n");
        appender->setLayout(LayoutPtr(layOut));
        appender->setName("fooAppender");
        Pool p;
        appender->activateOptions(p);
        logger->addAppender(AppenderPtr(appender));
        logger->setAdditivity(false);
    }
    const LoggerPtr& getLogger() const {
        return logger;
    }
};

这里的目标是为Foo类的每个实例创建不同的文件,并且由于数字是动态的,因此我无法在属性文件中创建记录器(也许我可以从0到2 * 1024 * 1024,但这很疯狂)。为了实现这个目标,我需要几个附加器,但是我想在属性文件中添加类似的东西:

log4j.appender.foo=org.apache.log4j.RollingFileAppender
log4j.appender.foo.MaxFileSize=50MB
log4j.appender.foo.MaxBackupIndex=1
log4j.appender.foo.layout=org.apache.log4j.PatternLayout
log4j.appender.foo.layout.ConversionPattern=%p %t %c - %m%n

是否有可能使自定义附加程序不断从属性文件中读取配置?

1 个答案:

答案 0 :(得分:1)

我回复自己。您需要什么:您需要创建一个新的自定义附加程序并将其设置为第一级记录器中的附加程序,而不是您可以克隆该附加程序的代码。作为奖励,在您的自定义附加程序中,您可以管理延迟的文件创建,因此,如果没有日志,则不再有空文件;)这里的代码:

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;
    }
};

属性文件

# 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

具有延迟的文件创建的自定义附加程序:

#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文件:

#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 */