【问题标题】:Configuration with custom and dynamic appender with log4cxx使用 log4cxx 使用自定义和动态附加程序进行配置
【发布时间】:2018-08-04 17:40:09
【问题描述】:

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

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

是否可以让自定义附加程序继续从属性文件中读取配置?

【问题讨论】:

    标签: c++ log4cxx


    【解决方案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 */
    

    【讨论】:

    • 你可能会觉得我的另一个answer很有趣
    猜你喜欢
    • 2015-07-05
    • 2011-11-08
    • 1970-01-01
    • 2020-03-04
    • 1970-01-01
    • 2013-03-09
    • 1970-01-01
    • 2019-01-20
    • 2015-01-03
    相关资源
    最近更新 更多