Log4Qt快速入门——Log4Qt日志格式化源码解析

Log4Qt快速入门——Log4Qt日志格式化源码解析

一、Layout

1、Layout简介

Log4Qt提供了多种Layout对象,用于格式化日志输出,指定日志级别、线程名称、Logger名称、日期时间等信息。
Log4Qt快速入门——Log4Qt日志格式化源码解析
Layout类是Log4Qt API中的抽象类。
PatternLayout:根据一个模式字符串输出日志事件;
SimpleLayout:输出日志事件的级别和消息;
TTCCLayout:输出日志事件的时间、线程名称、Logger名称和嵌套的诊断上下文信息。
PatternLayout和TTCCLayout通过PatternFormatter来实现格式化。当PatternFormatter解析模式字符串时,会根据发现的信息创建一个PatternConverter链,每个PatternConverter会处理LoggingEvent的某个成员。
转换字符:用于指定数据的类型,例如:类别、级别、日期、线程名称。Log4Qt中的转换字符有:
c:Logger 名称。
d{format_string}:日期。参数 format_string 可选,用于格式化日期。
m:消息内容
p:消息级别
r:启动程序的相对时间
t:线程名称
x:NDC(嵌套的诊断上下文)名称
X:MDC(映射的诊断上下文)名称
F:文件名称
M:方法名称
L:行号
l:位置信息
n:平台相关的行分隔符,Windows:\r\n,Linux:\n

2、NDC简介

NDC(Nested Diagnostic Context)即嵌套诊断上下文,是log4J用于存储上下文信息(context information)的类,NDC采用栈的机制push和pop上下文,每个线程有独立的上下文,如果要存储的上下文信息是堆栈式的在选择NDC。
NDC常用接口如下:
static QString pop();
将NDC栈顶元素弹出
static void push(const QString &rMessage);
将rMessage压入NDC栈
static void clear();
清空NDC栈
static int depth();
获取NDC栈的深度
static void setMaxDepth(int maxDepth);
设置NDC栈的最大深度
static QString peek();
获取NDC栈顶的数据
通常在context或servlet入口将线程相关的应用信息保存,在需要记录日志log信息等时将信息输出,并保证在当前线程的结束或servlet的出口使用clear()移除,防止信息泄露。

3、MDC简介

MDC(Mapped Diagnositc Context)即映射诊断上下文,是log4J用于存储上下文信息(context information)的类,MDC内部采用Hash容器实现,是线程独立的,但一个子线程会自动获得一个父线程MDC的copy,如果要存储的上下文信息是key/value式的选择MDC。
MDC常用接口如下:
static void put(const QString &rKey, const QString &rValue);
将rKey/rValue数据存储到Hash容器中
static void remove(const QString &rKey);
从Hash容器中删除key为rKey的key/value
static QString get(const QString &rKey);
从Hash容器中获取key为rKey的key/value
static QHash<QString, QString> context();
获取Hash容器中所有的内容

4、Layout常用接口

QString footer() const;
获取Layout对象的footer
QString header() const;
获取Layout对象的header
QString name() const;
获取Layout对象的对象名称
void setFooter(const QString &rFooter);
设置Layout对象的footer
void setHeader(const QString &rHeader);
设置Layout对象的header
void setName(const QString &rName);
设置Layout对象的对象名称
virtual QString format(const LoggingEvent &rEvent) = 0;
Layout对象的日志消息格式化接口,派生类PatternLayout、SimpleLayout、TTCCLayout通过format函数来确定具体要输出信息的格式。

二、PatternLayout

1、PatternLayout 简介

PatternLayout是Layout的一个派生类,如果想生成基于模式匹配的特定格式的日志信息,可以使用PatternLayout来进行格式化。
PatternLayout的枚举ConversionPattern定义了两个常用的模式:

enum ConversionPattern
{
    DEFAULT_CONVERSION_PATTERN,// "%m,%n"
    TTCC_CONVERSION_PATTERN,//"%r [%t] %p %c %x - %m%n"
};

2、PatternLayout常用接口

QString conversionPattern() const;
获取PatternLayout对象的转换模式匹配字符串
void setConversionPattern(const QString &rPattern);
设置PatternLayout对象的转换模式匹配字符串
void setConversionPattern(ConversionPattern conversionPattern);
设置PatternLayout对象的转换模式匹配方式

3、format格式化实现

QString PatternLayout::format(const LoggingEvent &rEvent)
{
    Q_ASSERT_X(mpPatternFormatter, "PatternLayout::format()", "mpPatternConverter must not be null");

    return mpPatternFormatter->format(rEvent);
}

调用PatternFormatter格式化函数根据模式转换器链表的每个模式转换器格式化信息。

QString PatternFormatter::format(const LoggingEvent &rLoggingEvent) const
    {
        QString result;
        PatternConverter *p_converter;
        Q_FOREACH(p_converter, mPatternConverters)
            p_converter->format(result, rLoggingEvent);
        return result;
    }

PatternFormatter使用模式匹配字符串创建一个模式转换器mPatternConverters,每个转换符对应一个模式转换器。

    void PatternFormatter::createConverter(const QChar &rChar, 
                                           const FormattingInfo &rFormattingInfo, 
                                           const QString &rOption)
    {
        Q_ASSERT_X(mConversionCharacters.indexOf(rChar) >= 0, "PatternFormatter::createConverter", "Unknown conversion character" );

        LogError e("Creating Converter for character '%1' min %2, max %3, left %4 and option '%5'");
        e << QString(rChar)
          << FormattingInfo::intToString(rFormattingInfo.mMinLength) 
          << FormattingInfo::intToString(rFormattingInfo.mMaxLength) 
          << rFormattingInfo.mLeftAligned 
          << rOption;
        logger()->trace(e);

        switch (rChar.toLatin1())
        {
            case 'c':
                mPatternConverters << new LoggerPatternConverter(rFormattingInfo, 
                                                                 parseIntegerOption(rOption));
                break;
            case 'd':
            {
                QString option = rOption;
                if (rOption.isEmpty())
                   option = QLatin1String("ISO8601");
                mPatternConverters << new DatePatternConverter(rFormattingInfo, 
                                                               option); 
                break;
            }
            case 'm':
                mPatternConverters << new BasicPatternConverter(rFormattingInfo,
                                                                BasicPatternConverter::MESSAGE_CONVERTER); 
                break;
            case 'p':
                mPatternConverters << new BasicPatternConverter(rFormattingInfo,
                                                                BasicPatternConverter::LEVEL_CONVERTER); 
                break;
            case 'r':
                mPatternConverters << new DatePatternConverter(rFormattingInfo,
                                                               QLatin1String("RELATIVE")); 
                break;
            case 't':
                mPatternConverters << new BasicPatternConverter(rFormattingInfo,
                                                                BasicPatternConverter::THREAD_CONVERTER); 
                break;
            case 'x':
                mPatternConverters << new BasicPatternConverter(rFormattingInfo,
                                                                BasicPatternConverter::NDC_CONVERTER); 
                break;
            case 'X':
                mPatternConverters << new MDCPatternConverter(rFormattingInfo, 
                                                              rOption); 
                break;
            default:
                Q_ASSERT_X(false, "PatternFormatter::createConverter", "Unknown pattern character");
        }
    }

4、PatternLayout使用示例

#include <QCoreApplication>
#include <log4qt/logger.h>
#include <log4qt/patternlayout.h>
#include <log4qt/consoleappender.h>
#include <log4qt/loggerrepository.h>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 获取rootLogger
    Log4Qt::Logger *logger = Log4Qt::Logger::rootLogger();
    // 创建PatternLayout(根据模式字符串输出日志事件)
    Log4Qt::PatternLayout *layout = new Log4Qt::PatternLayout();
    // 设置标头信息
    layout->setHeader("----- start -----");
    // 设置页脚信息
    layout->setFooter("----- end -----");
    // 设置转换模式
    layout->setConversionPattern("%d{yyyy-MM-dd hh:mm:ss} [%p] - %m%n");
    // 激活Layout
    layout->activateOptions();

    // 创建ConsoleAppender
    Log4Qt::ConsoleAppender *appender = new Log4Qt::ConsoleAppender(layout, Log4Qt::ConsoleAppender::STDOUT_TARGET);
    appender->activateOptions();
    logger->addAppender(appender);

    logger->setLevel(Log4Qt::Level::DEBUG_INT);
    logger->debug("Debug, Log4Qt!");
    logger->info("Info, Log4Qt!");

    // 关闭 logger
    logger->removeAllAppenders();
    logger->loggerRepository()->shutdown();

    return a.exec();
}
// output:
// ----- start -----
// 2018-10-11 21:25:30 [DEBUG] - Debug, Log4Qt!
// 2018-10-11 21:25:30 [INFO] - Info, Log4Qt!
// ----- end -----

5、配置PatternLayout

使用log4qt.properties配置文件配置PatternLayout:

# 定义 rootLogger
log4j.rootLogger=DEBUG, console

# 定义 ConsoleAppender
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.immediateFlush=true
log4j.appender.console.target=STDOUT_TARGET

# 为 ConsoleAppender 定义 Layout
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.header=----- start -----
log4j.appender.console.layout.footer=----- end -----
log4j.appender.console.layout.conversionPattern=%d{yyyy-MM-dd hh:mm:ss} [%t] %p %c %x - %m%n

程序使用示例:

#include <QCoreApplication>
#include <log4qt/logger.h>
#include <log4qt/loggerrepository.h>
#include <QThread>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QThread::currentThread()->setObjectName("MainThread");

    // 获取rootLogger
    Log4Qt::Logger* logger = Log4Qt::Logger::rootLogger();

    // 打印消息
    logger->debug("Debug, Log4Qt!");
    logger->info("Info, Log4Qt!");

    // 关闭rootLogger
    logger->removeAllAppenders();
    logger->loggerRepository()->shutdown();

    return a.exec();
}
// output:
// ----- start -----
// 2018-10-11 21:35:58 [MainThread] DEBUG root  - Debug, Log4Qt!
// 2018-10-11 21:35:58 [MainThread] INFO root  - Info, Log4Qt!
// ----- end -----

三、SimpleLayout

1、SimpleLayout简介

SimpleLayout 是Layout的一个派生类,对日志消息的格式化只包含日志的级别和消息内容。

2、format格式化实现

QString SimpleLayout::format(const LoggingEvent &rEvent)
    {
        return rEvent.level().toString() + QLatin1String(" - ") + rEvent.message() + Layout::endOfLine();
    }

SimpleLayout对日志消息的格式化只包含日志的级别和消息内容。

3、SimpleLayout示例

#include <QCoreApplication>
#include <log4qt/logger.h>
#include <log4qt/simplelayout.h>
#include <log4qt/consoleappender.h>
#include <log4qt/loggerrepository.h>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 创建SimpleLayout
    Log4Qt::Logger *logger = Log4Qt::Logger::rootLogger();
    Log4Qt::SimpleLayout *layout = new Log4Qt::SimpleLayout();
    layout->setFooter("end");
    layout->setHeader("start");
    layout->activateOptions();

    // 创建ConsoleAppender
    Log4Qt::ConsoleAppender *appender = new Log4Qt::ConsoleAppender(layout, Log4Qt::ConsoleAppender::STDOUT_TARGET);
    appender->activateOptions();
    logger->addAppender(appender);

    logger->setLevel(Log4Qt::Level::DEBUG_INT);
    logger->debug("Debug, Log4Qt!");
    logger->info("Info, Log4Qt!");

    // 关闭 logger
    logger->removeAllAppenders();
    logger->loggerRepository()->shutdown();

    return a.exec();
}
// output:
// start
// DEBUG - Debug, Log4Qt!
// INFO - Info, Log4Qt!
// end

4、配置SimpleLayout

使用log4qt.properties配置文件配置SimpleLayout:

# 定义 rootLogger
log4j.rootLogger=DEBUG, console

# 定义 ConsoleAppender
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.immediateFlush=true
log4j.appender.console.target=STDOUT_TARGET

# 为 ConsoleAppender 定义 Layout
log4j.appender.console.layout=org.apache.log4j.SimpleLayout
log4j.appender.console.layout.header=----- start -----
log4j.appender.console.layout.footer=----- end -----

程序使用示例:

#include <QCoreApplication>
#include <log4qt/logger.h>
#include <log4qt/loggerrepository.h>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 获取 rootLogger
    Log4Qt::Logger* logger = Log4Qt::Logger::rootLogger();

    // 打印消息
    logger->debug("Hello, Log4Qt!");
    logger->info("Hello, Log4Qt!");

    // 关闭 rootLogger
    logger->removeAllAppenders();
    logger->loggerRepository()->shutdown();

    return a.exec();
}
// output:
// ----- start -----
// DEBUG - Hello, Log4Qt!
// INFO - Hello, Log4Qt!
// ----- end -----

四、TTCCLayout

1、TTCCLayout简介

TTCCLayout 是Layout的一个派生类,负责提供有关日志事件的详细信息,通常包含以下内容:
Time:从启动应用程序开始,以毫秒数计算的时间;
Thread:调用线程;
Category:用于创建日志事件的类别或Logger;
Context:NDC信息。NDC信息不会自动包含在LoggingEvent 对象中,必须专门包含NDC信息。因此,Context是TTCCLayout的一个可选输出,即使启用NDC设置,如果LoggingEvent 不包含任何NDC设置,TTCCLayout也可能不会显示任何NDC 数据。
 TTCCLayout有多个可选参数,但即使不设置任何选项, TTCCLayout仍然会输出下列信息:
Level:日志消息的级别;
Message:日志消息本身。
TTCCLayout预定义了多种日期格式,定义如下:

enum DateFormat
{
    NONE,//没有日期格式
    ISO8601,// yyyy-MM-dd hh:mm:ss.zzz
    ABSOLUTE,// HH:mm:ss.zzz
    DATE,//MMM YYYY HH:mm:ss.zzzz
    RELATIVE // 程序启动开始的毫秒数量
};

2、TTCCLayout常用接口

bool categoryPrefixing() const;
获取是否格式化输出Logger名称
bool contextPrinting() const;
获取是否格式化输出NDC信息
QString dateFormat() const;
获取日期格式的字符串
bool threadPrinting() const;
获取是否格式化输出线程名称
void setCategoryPrefixing(bool categoryPrefixing);
设置指定Logger名称是否是格式化输出。
void setContextPrinting(bool contextPrinting);
设置是否格式化输出NDC信息
void setDateFormat(const QString &rDateFormat);
设置rDateFormat字符串表示的日期格式
void setDateFormat(DateFormat dateFormat);
设置DateFormat枚举类型定义的日期格式类型
void setThreadPrinting(bool threadPrinting);
设置是否格式化输出线程名称
virtual QString format(const LoggingEvent &rEvent);
格式化日志信息接口
static void Log4Qt::NDC::push(const QString &rMessage);
将rMessage信息压入NDC栈
static QString Log4Qt::NDC::pop();
将NDC栈顶信息出栈

3、format格式化实现

QString TTCCLayout::format(const LoggingEvent &rEvent)
{
    Q_ASSERT_X(mpPatternFormatter, "TTCCLayout::format()", "mpPatternConverter must not be null");

    return mpPatternFormatter->format(rEvent);
}

TTCCLayout的格式化与PatternLayout的格式化方法相同,都是根据模式匹配字符串创建的模式转换器链表的每个模式转换器格式化信息。

4、TTCCLayout示例

#include <QCoreApplication>
#include <log4qt/logger.h>
#include <log4qt/ttcclayout.h>
#include <log4qt/consoleappender.h>
#include <log4qt/loggerrepository.h>
#include <log4qt/ndc.h>
#include <QThread>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QThread::currentThread()->setObjectName("MainThread");

    Log4Qt::Logger *logger = Log4Qt::Logger::rootLogger();
    // 创建TTCCLayout
    Log4Qt::TTCCLayout *layout = new Log4Qt::TTCCLayout();
    layout->setDateFormat("yyyy-mm-dd hh:mm:ss");
    layout->activateOptions();

    // 创建一ConsoleAppender
    Log4Qt::ConsoleAppender *appender = new Log4Qt::ConsoleAppender(layout, Log4Qt::ConsoleAppender::STDOUT_TARGET);
    appender->activateOptions();
    logger->addAppender(appender);

    logger->setLevel(Log4Qt::Level::DEBUG_INT);
    // NDC信息
    Log4Qt::NDC::push("Thread start");
    logger->debug("Hello, Log4Qt!");
    Log4Qt::NDC::pop();
    logger->info("Hello, Log4Qt!");

    // 关闭 logger
    logger->removeAllAppenders();
    logger->loggerRepository()->shutdown();

    return a.exec();
}
// output:
// 2018-18-11 23:18:12 [MainThread] DEBUG root Thread start - Hello, Log4Qt!
// 2018-18-11 23:18:12 [MainThread] INFO  root  - Hello, Log4Qt!

5、配置TTCCLayout

使用log4qt.properties配置文件配置TTCCLayout:

# 定义rootLogger
log4j.rootLogger=DEBUG, console

# 定义ConsoleAppender
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.immediateFlush=true
log4j.appender.console.target=STDOUT_TARGET

# 为ConsoleAppender定义Layout
log4j.appender.console.layout=org.apache.log4j.TTCCLayout
log4j.appender.console.layout.categoryPrefixing=true
log4j.appender.console.layout.contextPrinting=true
log4j.appender.console.layout.threadPrinting=true
log4j.appender.console.layout.dateFormat=ISO8601

程序使用示例:

#include <QCoreApplication>
#include <log4qt/logger.h>
#include <log4qt/ttcclayout.h>
#include <log4qt/consoleappender.h>
#include <log4qt/loggerrepository.h>
#include <log4qt/ndc.h>
#include <QThread>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QThread::currentThread()->setObjectName("MainThread");

    Log4Qt::Logger *logger = Log4Qt::Logger::rootLogger();

    // NDC信息
    Log4Qt::NDC::push("Thread start");
    logger->debug("Hello, Log4Qt!");
    Log4Qt::NDC::pop();
    logger->info("Hello, Log4Qt!");

    // 关闭 logger
    logger->removeAllAppenders();
    logger->loggerRepository()->shutdown();

    return a.exec();
}
// output:
// 2018-10-11 23:22:09.936 [MainThread] DEBUG root Thread start - Hello, Log4Qt!
// 2018-10-11 23:22:09.936 [MainThread] INFO  root  - Hello, Log4Qt!

转载于:https://blog.51cto.com/9291927/2299389

log4cplus是C++编写的开源的日志系统,功能非常全面,用到自己开发的工程中会比较专业的,:),本文介绍了log4cplus基本概念,以及如何安装,配置。 ### 简介 ### log4cplus是C++编写的开源的日志系统,前身是java编写的log4j系统.受Apache Software License保护。作者是Tad E. Smith。log4cplus具有线程安全、灵活、以及多粒度控制的特点,通过将信息划分优先级使其可以面向程序调试、运行、测试、和维护等全生命周 期; 你可以选择将信息输出到屏幕、文件、 NT event log、甚至是远程服务器;通过指定策略对日志进行定期备份等等。 ### 下载 ### 最新的log4cplus可以从以下网址下载 http://log4cplus.sourceforge.net本文使用的版本为:1.0.2 ### 安装 ### 1. linux下安装 tar xvzf log4cplus-x.x.x.tar.gz cd log4cplus-x.x.x ./configure --prefix=/where/to/install make make install 这里我采用缺省安装路径:/usr/local,下文如无特别说明,均以此路径为准。 2. windows下安装 不需要安装,有一个msvc6存放包括源代码和用例在内的开发工程(for VC6 only),使用之前请先编译 "log4cplus_dll class"工程生成dll,或者编译"log4cplus_static class"工程生成lib. ### 使用前的配置 ### 1. linux下的配置 确保你的Makefile中包含 /usr/local/lib/liblog4cplus.a(静态库)或 -llog4cplus(动态库)即可, 头文件在/usr/local/include/log4cplus目录下。对于动态库,要想正常使用,还得将库安装路径加入到 LD_LIBRARY_PATH 中,我一般是这样做的:以管理员身份登录,在/etc/ld.so.conf中加入安装路径,这里 是/usr/local/lib,然后执行ldconfig使设置生效即可。 2. windows下的配置 将"log4cplus_dll class"工程或"log4cplus_static class"工程的dsp 文件插入到你的工程中,或者直接 把两个工程编译生成的库以及头文件所在目录放到你的工程的搜索路径中,如果你使用静态库,请在你的工程中 "project/setting/C++"的preprocessor definitions中加入LOG4CPLUS_STATIC。 ### 构成要素介绍 ### 虽然功能强大,应该说log4cplus用起来还是比较复杂的,为了更好地使用它,先介绍一下它的基本要素。 Layouts :布局器,控制输出消息的格式. Appenders :挂接器,与布局器紧密配合,将特定格式的消息输出到所挂接的设备终端 (如屏幕,文件等等)。 Logger :记录器,保存并跟踪对象日志信息变更的实体,当你需要对一个对象进行 记录时,就需要生成一个logger。 Categories :分类器,层次化(hierarchy)的结构,用于对被记录信息的分类,层次中 每一个节点维护一个logger的所有信息。 Priorities :优先权,包括TRACE, DEBUG, INFO, WARNING, ERROR, FATAL。 本文介绍了log4cplus基本概念,以及如何安装,配置,下一篇将通过例子介绍如何使用log4cplus。 (二) 本文介绍了使用log4cplus有六个步骤,并提供了一些例子引导你了解log4cplus的基本使用。 ### 基本使用 ### 使用log4cplus有六个基本步骤: 1. 实例化一个appender对象 2. 实例化一个layout对象 3. 将layout对象绑定(attach)到appender对象 4. 实例化一个logger对象,调用静态函数:log4cplus::Logger::getInstance("logger_name") 5. 将appender对象绑定(attach)到logger对象,如省略此步骤,标准输出(屏幕)appender对象会绑定到logger 6. 设置logger的优先级,如省略此步骤,各种有限级的消息都将被记录 下面通过一些例子来了解log4cplus的基本使用。 〖例1〗 cpp 代码 /* 严格实现步骤1-6,appender输出到屏幕, 其中的布局格式和LogLevel后面会详细解释。*/ #include #include #include using namespace log4cplus; using namespace log4cplus::helpers; int main(){ /* step 1: Instantiate an appender object */ SharedObjectPtr _append (new ConsoleAppender()); _append->setName("append for test"); /* step 2: Instantiate a layout object */ std::string pattern = "%d{%m/%d/%y %H:%M:%S} - %m [%l]%n"; std::auto_ptr _layout(new PatternLayout(pattern)); /* step 3: Attach the layout object to the appender */ _append->setLayout( _layout ); /* step 4: Instantiate a logger object */ Logger _logger = Logger::getInstance("test"); /* step 5: Attach the appender object to the logger */ _logger.addAppender(_append); /* step 6: Set a priority for the logger */ _logger.setLogLevel(ALL_LOG_LEVEL); /* log activity */ LOG4CPLUS_DEBUG(_logger, "This is the FIRST log message...") sleep(1); LOG4CPLUS_WARN(_logger, "This is the SECOND log message...") return 0; } 输出结果: 10/14/04 09:06:24 - This is the FIRST log message... [main.cpp:31] 10/14/04 09:06:25 - This is the SECOND log message... [main.cpp:33] 〖例2〗 /* 简洁使用模式,appender输出到屏幕。 */ #include #include using namespace log4cplus; using namespace log4cplus::helpers; int main() { /* step 1: Instantiate an appender object */ SharedAppenderPtr _append(new ConsoleAppender()); _append->setName("append test"); /* step 4: Instantiate a logger object */ Logger _logger = Logger::getInstance("test"); /* step 5: Attach the appender object to the logger */ _logger.addAppender(_append); /* log activity */ LOG4CPLUS_DEBUG(_logger, "This is the FIRST log message...") sleep(1); LOG4CPLUS_WARN(_logger, "This is the SECOND log message...") return 0; } 输出结果: DEBUG - This is the FIRST log message... WARN - This is the SECOND log message... 〖例3〗 /* iostream模式,appender输出到屏幕。 */ #include #include #include /* 其实这个东东还是放到log4cplus头文件中比较合适些,个人意见:) */using namespace log4cplus; int main() { /* step 1: Instantiate an appender object */ SharedAppenderPtr _append(new ConsoleAppender()); _append->setName("append test"); /* step 4: Instantiate a logger object */ Logger _logger = Logger::getInstance("test"); /* step 5: Attach the appender object to the logger */ _logger.addAppender(_append); /* log activity */ LOG4CPLUS_TRACE(_logger, "This is" << " just a t" << "est." << std::endl) LOG4CPLUS_DEBUG(_logger, "This is a bool: " << true) LOG4CPLUS_INFO(_logger, "This is a char: " << 'x') LOG4CPLUS_WARN(_logger, "This is a int: " << 1000) LOG4CPLUS_ERROR(_logger, "This is a long(hex): " << std::hex << 100000000) LOG4CPLUS_FATAL(_logger, "This is a double: " << std::setprecision(15) << 1.2345234234) return 0; } 输出结果: DEBUG - This is a bool: 1 INFO - This is a char: x WARN - This is a int: 1000 ERROR - This is a long(hex): 5f5e100 FATAL - This is a double: 1.2345234234 〖例4〗 /* 调试模式,通过loglog来控制输出调试、警告或错误信息,appender输出到屏幕。 */ #include #include using namespace log4cplus::helpers; void printMsgs(void) { std::cout << "Entering printMsgs()..." << std::endl; LogLog::getLogLog()->debug("This is a Debug statement..."); LogLog::getLogLog()->warn("This is a Warning..."); LogLog::getLogLog()->error("This is a Error..."); std::cout << "Exiting printMsgs()..." << std::endl << std::endl; } int main() { /* LogLog类实现了debug, warn, error 函数用于输出调试、警告或错误信息, 同时提供了两个方法来进一步控制所输出的信息,其中: setInternalDebugging方法用来控制是否屏蔽输出信息中的调试信息,当输入 参数为false则屏蔽,缺省设置为false。 setQuietMode方法用来控制是否屏蔽所有输出信息,当输入参数为true则屏蔽, 缺省设置为false。 LogLog::getLogLog()->setInternalDebugging(false); */ printMsgs(); std::cout << "Turning on debug..." << std::endl; LogLog::getLogLog()->setInternalDebugging(true); printMsgs(); std::cout << "Turning on quiet mode..." << std::endl; LogLog::getLogLog()->setQuietMode(true); printMsgs(); return 0; } 输出结果: Entering printMsgs()... log4cplus:WARN This is a Warning... log4cplus:ERROR This is a Error... Exiting printMsgs()... Turning on debug... Entering printMsgs()... log4cplus: This is a Debug statement... log4cplus:WARN This is a Warning... log4cplus:ERROR This is a Error... Exiting printMsgs()... Turning on quiet mode... Entering printMsgs()... Exiting printMsgs()... 需要指出的是,输出信息中总是包含"log4cplus:"前缀,有时候会感觉不爽,这是因为LogLog在实现时候死定了要这么写: LogLog::LogLog() : mutex(LOG4CPLUS_MUTEX_CREATE), debugEnabled(false), quietMode(false), PREFIX( LOG4CPLUS_TEXT("log4cplus: ") ), WARN_PREFIX( LOG4CPLUS_TEXT("log4cplus:WARN ") ), ERR_PREFIX( LOG4CPLUS_TEXT("log4cplus:ERROR ") ) { } 你可以把这些前缀换成自己看着爽的提示符号,然后重新编译,hihi。除非万不得已或者实在郁闷的不行,否则还是不要这样干。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值