zoukankan      html  css  js  c++  java
  • example of log4cpp properties configuration

    log 的优先级别解读,参阅源码 log4cpp-0.3.5rc3/include/log4cpp/Priority.hh
    由高到低

    EMERG
    FATAL
    ALERT
    CRIT
    ERROR
    WARN
    NOTICE
    INFO
    DEBUG
    NOTSET

    对应到 Category 相应函数,参阅源码 log4cpp-0.3.5rc3/include/log4cpp/Category.hh

    Category::emerg()
    Category::fatal()
    Category::alert()
    Category::crit()
    Category::error()
    Category::warn()
    Category::notice()
    Category::info()
    Category::debug()

    以上函数都有 2 个重载函数,可分别接受格式化字串或 std::string,例如 debug(),有

    void debug(const char* stringFormat, ...) throw();
    void debug(const std::string& message) throw();

    关于优先级别使用的建议
    开发运行时,设为 DEBUG 级,而正式运营时,则设为 NOTICE ;
    一定要显示出来的信息则可以用 NOTICE 或以上级别;
    跟踪函数运行痕迹的信息用 INFO 级别;
    运行时调试的信息用 DEBUG 级别;
    举例说明

    void initialize(int argc, char* argv[])
    {
    log.info("initialize() : argc=%d", argc);

    for (int i=0; i < argc; ++i)
    {
        log.debug("initialize() : argv[%d]=%s", i, argv[i]);
    }

    log.notice("initialize() : done");
    }

    log4cpp 的 category 分为 rootCategory 和其它自定义的 category。

    而每个 category 都可以输出到多个 appender。并且 category 也是有包含关系的。

    例如 rootCategory 就是所有 category 的根。而自定义的 category 也可以在配置文件中定义其包含关系。

    先看一个 rootCategory 的配置

    log4cpp.rootCategory=DEBUG, console, sample

    这个定义里,指定了 rootCategory 的 log 优先级是 DEBUG,其 appender 有 2 个,分别是 console 和 sample。

    即是说,等号右边内容以逗号分隔,第一项是优先级别,接下来的都是 appender 名字,可以有一个或多个。

    现在来看看自定义的 category

    log4cpp.category.demo=DEBUG, sample

    这里定义了一个名字为 demo 的 category,其优先级为 DEBUG,appender 为 sample。

    注意, category 和 appender 名字可以完全相同。

    再来看看有包含关系的 category 的定义

    log4cpp.category.demo.son=DEBUG, son
    log4cpp.category.demo.daughter=DEBUG, daughter

    以上定义了 2 个 category,名字分别为 son 和 daughter,其父 category 为 demo。

    son 产生的 log 会写到 son 和 demo 的 appender 中。同理,daughter 的 log 会写到 daughter 和 demo 的 appender 中。

    现在来看看 appender 的定义。appender 有很多种,我这里只介绍几种,分别是

    ConsoleAppender : 控制台输出,即 std::cout
    Win32DebugAppender : VC IDE 的输出,即 ::OutputDebugString
    FileAppender : 文件输出
    RollingFileAppender : 有待研究

    现在看一个 ConsoleAppender 的例子

    log4cpp.appender.console=ConsoleAppender
    log4cpp.appender.console.layout=PatternLayout
    log4cpp.appender.console.layout.ConversionPattern=%d [%p] - %m%n

    以上信息解释为:一个名为 console 的 appender,其类型为 ConsoleAppender,即 控制台输出 log 输出的布局是 指定的样式
    输出的格式 是 "%d [%p] - %m%n" (稍后再解释)

    再看一个 FileAppender 的例子

    log4cpp.appender.sample=FileAppender
    log4cpp.appender.sample.fileName=sample.log
    log4cpp.appender.sample.layout=PatternLayout
    log4cpp.appender.sample.layout.ConversionPattern=%d [%p] - %m%n

    以上信息解释为:一个名为 sample 的 appender,其类型为 FileAppender,即 文件输出指定的 log 文件名为 sample.log,输出的布局是 指定的样式,输出的格式 是 "%d [%p] - %m%n"

    对应 category 和 appender 的配置方式,可以发现

    category 是 "log4cpp.category." + "category name"

    category 名字可以用 "." 分隔,以标识包含关系

    appender 是 "log4cpp.appender." + "appender name"

    appender 名字 不能 用 "." 分隔,即是说 appender 是没有包含关系的

    现在看一个完整的配置文件例子

    #定义 root category 的属性
    log4cpp.rootCategory=DEBUG, console

    #定义 console 属性
    log4cpp.appender.console=ConsoleAppender
    log4cpp.appender.console.layout=PatternLayout
    log4cpp.appender.console.layout.ConversionPattern=%d [%p] - %m%n

    #定义 sample category 的属性
    log4cpp.category.sample=DEBUG, sample

    #定义 sample appender 的属性
    log4cpp.appender.sample=FileAppender
    log4cpp.appender.sample.fileName=sample.log
    log4cpp.appender.sample.layout=PatternLayout
    log4cpp.appender.sample.layout.ConversionPattern=%d [%p] - %m%n

    #定义 sample.son category 的属性
    log4cpp.category.sample.son=DEBUG, son

    #定义 son appender 的属性
    log4cpp.appender.son=FileAppender
    log4cpp.appender.son.fileName=son.log
    log4cpp.appender.son.layout=PatternLayout
    log4cpp.appender.son.layout.ConversionPattern=%d [%p] - %m%n

    #定义 sample.daughter category 的属性
    log4cpp.category.sample.daughter=DEBUG, daughter

    #定义 daughter appender 的属性
    log4cpp.appender.daughter=FileAppender
    log4cpp.appender.daughter.fileName=daughter.log
    log4cpp.appender.daughter.layout=PatternLayout
    log4cpp.appender.daughter.layout.ConversionPattern=%d [%p] - %m%n

    ConversionPattern 参数解读,参阅源码 log4cpp-0.3.5rc3/src/PatternLayout.cpp

    %m log message 内容, 即 用户写 log 的具体信息
    %n 回车换行
    %c category 名字
    %d 时间戳
    %p 优先级
    %r 距离上一次写 log 的间隔, 单位毫秒
    %R 距离上一次写 log 的间隔, 单位秒
    %t 线程名
    %u 处理器时间
    %x NDC ?

    窃以为,以下格式就足够了,即输出 "时间 [线程名] 优先级 - log内容 回车换行"

    %d [%t] %p - %m%n

    配置的知识就差不多了,现在看看实际代码应用

    首先是初始化 log4cpp 的配置,例如我的配置文件名是 log4cpp.properties

    try
    {
    log4cpp::PropertyConfigurator::configure("log4cpp.properties");
    }
    catch (log4cpp::ConfigureFailure & f)
    {
    std::cerr << "configure problem " << f.what() << std::endl;
    }

    初始化完成后,就可以这样用了(具体的应用技巧,你自己摸索吧)

    log4cpp::Category & log = log4cpp::Category::getInstance(std::string("sample"));

    log.debug("test debug log");
    log.info("test info log");

    // 用 sample.son

    log4cpp::Category & log = log4cpp::Category::getInstance(std::string("sample.son"));

    log.debug("test debug log of son");
    log.info("test info log of son");


    // 用 sample.daughter

    log4cpp::Category & log = log4cpp::Category::getInstance(std::string("sample.daughter"));

    log.debug("test debug log of daughter");
    log.info("test info log of daughter");

    再举一个在自定义类中的使用

    #include <log4cpp/Category.hh>

    namespace demo
    {
    class Sample
    {
    public:
        Sample();
        ~Sample();

    public:
        Testing(int i);

    private:
        static log4cpp::Category & log;
    };

    }

    #include "Sample.h"

    namespace demo
    {
    log4cpp::Category & Sample::log = log4cpp::Category::getInstance(std::string("sample"));

    Sample::Sample()
    {
        log.debug("Sample::Sample()");
    }

    Sample::~Sample()
    {
        log.debug("Sample::~Sample()");
    }

    Sample::Testing(int i)
    {
        log.debug("Sample::Testing() : i=%d", i);
    }
    }

  • 相关阅读:
    PortalBasic Java Web 应用开发框架:应用篇(一) —— 配置文件
    PortalBasic Java Web 应用开发框架:应用篇(六) —— 公共组件
    PortalBasic Java Web 应用开发框架:应用篇(三) —— 国际化
    普通软件项目开发过程规范(五)—— 总结
    PortalBasic Java Web 应用开发框架:应用篇(四) —— 文件上传和下载
    PortalBasic Java Web 应用开发框架 —— 前言
    PortalBasic Java Web 应用开发框架:应用篇(二) —— Action 使用
    dll 问题 (转)
    不同服务器数据库之间的数据操作
    USB鼠标经常出现不能用的情况——解决方法
  • 原文地址:https://www.cnblogs.com/lancidie/p/3941090.html
Copyright © 2011-2022 走看看