Log4cxx自定义appender

时间:2009-05-17 13:59:08

标签: c++ logging log4cxx

是否可以为log4cxx编写自定义appender并通过属性文件(如内置的appender)进行配置?如果可能的话,我更喜欢这样做,而不必重建log4cxx(例如,通过派生/扩展现有的appender)。

你能指点我一个例子吗?

3 个答案:

答案 0 :(得分:7)

答案 1 :(得分:4)

brlcad的建议是正确的 - 在我的公司,我们已将此方法用于我们自己的自定义附加程序。

实际上,您已经可以从配置文件中配置这些 - 在类定义中设置log4cxx环境的DECLARE_LOG4CXX_OBJECT(CustomAppenderClassName)等宏。您可以通过" CustomAppenderClassName"来引用您的appender类型。 显示标准和自定义appender的configfile(旧式),使用自定义appender的标准布局:

# Set "realtime" logger level to DEBUG and create two appenders - one to be
# a standard rolling file appender, the other custom.
log4j.logger.realtime=ERROR, StandardAppender, CustomAppender

# StandardAppenderis set to be a RollingFileAppender
log4j.appender.StandardAppender=org.apache.log4j.RollingFileAppender
log4j.appender.StandardAppender.File=example.log

log4j.appender.StandardAppender.MaxFileSize=100KB
# Keep one backup file
log4j.appender.StandardAppender.MaxBackupIndex=1

# StandardAppender uses PatternLayout.
log4j.appender.StandardAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.StandardAppender.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

# CustomAppender uses PatternLayout too
log4j.appender.CustomAppender=CustomAppenderClassName
log4j.appender.CustomAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.CustomAppender.layout.ConversionPattern=%m

答案 2 :(得分:2)

我正在添加此答案,因为评分最高的答案中的链接似乎来自旧版本。我使用version 1.2.0创建了一个自定义appender,遵循他们在SysLogAppender中所做的事情。在高级别,您将需要执行以下步骤:

  • 创建一个继承其Appender类的自己的类。
  • 实施纯虚函数void close()void append(const spi::InternalLoggingEvent& event)
  • 使用AppenderFactoryRegistry注册您的appender类。

这是一个带有代码的示例类,其中包含名称空间yournamespace :: ExampleCustomAppender:

#include <log4cplus/appender.h>

namespace yournamespace {
    class ExampleCustomAppender : public Appender
    {
    public:
        ExampleCustomAppender(const log4cplus::helpers::Properties & properties);

        // Dtor
        virtual ~ExampleCustomAppender();

        // Methods
        virtual void close();

        /** Register the appender with the factory registry. */
        static void registerAppender();

    protected:
        virtual void append(const spi::InternalLoggingEvent& event);
    };
}

然后执行方法:

#include <log4cplus/spi/factory.h>
#include <sstream>

namespace yournamespace {

    ExampleCustomAppender::ExampleCustomAppender(const helpers::Properties & properties)
        : Appender(properties)
    {
    // if you want to use properties to configure your object do so here
    }

    ExampleCustomAppender::~ExampleCustomAppender()
    {
    }

    void ExampleCustomAppender::registerAppender()
    {
        log4cplus::spi::AppenderFactoryRegistry & reg
            = log4cplus::spi::getAppenderFactoryRegistry();
        LOG4CPLUS_REG_PRODUCT(reg, "log4cplus::", ExampleCustomAppender, 
            yournamespace::, log4cplus::spi::AppenderFactory);
    }

    void ExampleCustomAppender::close()
    {
        // do anything you need to close the appender
        closed = true;
    }

    // This method does not need to be locked since it is called by
    // doAppend() which performs the locking
    void LoggingCallbackAppender::append(const spi::InternalLoggingEvent& event)
    {
        if (!closed) {
            std::stringstream logOutput;
            layout->formatAndAppend(logOutput, event);
            std::string outputString = logOutput.str();
        }
    }
}

以及最后一个如何在配置文件中使用的示例:

log4cplus.rootLogger=INFO, STDOUT, ROLLING, EXAMPLE
// other definitions for STDOUT and ROLLING here and then  ...
log4cplus.appender.EXAMPLE=log4cplus::ExampleCustomAppender
log4cplus.appender.EXAMPLE.layout=log4cplus::PatternLayout
log4cplus.appender.EXAMPLE.layout.ConversionPattern=%d{%m/%d %H:%M:%S} [%t] %-5p %c{2} - %m%n

我通过剪切其他代码来完成此代码,因此它本身并没有以这种格式编译。让我知道任何问题,我会纠正它。