zoukankan      html  css  js  c++  java
  • log4cxx的使用

    log4cxx是业界通用的日志系统,建议我们在写程序的时候可以直接拿来使用,关于工程包及相关的lib及dll文件,网上有很多说明,略过。以下只讲怎样使用。

    一、建测试工程:testlog4cxx,直接选控制台应用程序,    在配置属性页中,选C/C++,常规,在附加包含目录中加入“./”;选链接器,常规,在附加库目录中加入"./",点选中常规下面的输入,在附加依赖项中加入“log4cxx/log4cxx.lib”

    二、在测试工程目录下加入log4cxx文件包

    三、加入include头文件:

    #include <log4cxx/logger.h>

    #include <log4cxx/propertyconfigurator.h>

    四、定义配置文件log4cxx.properties的位置

    log4cxx::PropertyConfigurator::configure("log4cxx.properties");

    此处的作用为定义配置文件的位置,如果想让程序在D盘根目录下加载配置文件,可以如下定义:

    log4cxx::PropertyConfigurator::configure("D:\log4cxx.properties");

    五、定义不同的打印级别

    此在配置文件中log4cxx.properties将会有所定义。假设有这样的场景,你必须使用别人提供一个DLL用来获取接口,此DLL中使用了log4cxx日志,然后你又想在自己的工程中同样引入log4cxx日志,为了区分你的日志和别人的日志,你该如何做呢,假设别人使用的为log4j.rootLogger顶级接口。(默认情况下,所有的日志都会在顶级接口对应的日志文件中进行记录)

    这样一个设置可使得顶级接口与子接口分离:

    # 屏蔽gather的Appender继承 
    log4j.additivity.gather = false

    以下配置假设引用的DLL库使用了log4cxx的根接口,并且输出两种级别的文件,一种为error,一种为debug

    # 设置root logger为DEBUG级别,使用了两个Appender log4j.rootLogger=DEBUG, COM, ERR

    # 设置sample logger为DEBUG级别 log4j.logger.sample = DEBUG, sample # 屏蔽sample的Appender继承 log4j.additivity.sample = false

    log4j.logger.sample.error = WARN, sample.error #log4j.additivity.sample.error = false

    log4j.appender.COM=org.apache.log4j.RollingFileAppender log4j.appender.COM.File=../log/dll_output.log log4j.appender.COM.Append=false log4j.appender.COM.MaxFileSize=3MB log4j.appender.COM.MaxBackupIndex=10 log4j.appender.COM.ImmediateFlush=true log4j.appender.COM.layout=org.apache.log4j.PatternLayout log4j.appender.COM.layout.ConversionPattern=%d %-5p %m%n

    log4j.appender.ERR=org.apache.log4j.RollingFileAppender log4j.appender.ERR.File=../log/dll_error.log log4j.appender.ERR.Append=false log4j.appender.ERR.Threshold=ERROR log4j.appender.ERR.MaxFileSize=3MB log4j.appender.ERR.MaxBackupIndex=10 log4j.appender.ERR.layout=org.apache.log4j.PatternLayout log4j.appender.ERR.layout.ConversionPattern=%d %-5p %m%n

    log4j.appender.sample=org.apache.log4j.RollingFileAppender log4j.appender.sample.File=../log/sample_output.log log4j.appender.sample.Append=false log4j.appender.sample.MaxFileSize=10MB log4j.appender.sample.MaxBackupIndex=10 log4j.appender.sample.ImmediateFlush=true log4j.appender.sample.layout=org.apache.log4j.PatternLayout log4j.appender.sample.layout.ConversionPattern=%d %-5p %m%n

    log4j.appender.sample.error=org.apache.log4j.RollingFileAppender log4j.appender.sample.error.File=../log/sample_error.log log4j.appender.sample.error.Append=false log4j.appender.sample.error.MaxFileSize=3MB log4j.appender.sample.error.MaxBackupIndex=10 log4j.appender.sample.error.ImmediateFlush=true log4j.appender.sample.error.layout=org.apache.log4j.PatternLayout log4j.appender.sample.error.layout.ConversionPattern=%d %-5p %m%n

    六、后台打印的日志与控制台显示的级别不同(一般控制台打印比较慢,显示的尽可能少,后台则尽可能详尽)

    使用log4j.appender.ca.Threshold=WARN可达到控制台显示与后台打印不相同,如下一个配置文件设置:

    # 设置root logger为DEBUG级别,使用了两个Appender log4j.rootLogger=DEBUG, server, ca

    # 设置kline logger为DEBUG级别 log4j.logger.kline = DEBUG, kline, ca # 屏蔽kline的Appender继承 log4j.additivity.kline = false

    log4j.logger.kline.error = WARN, kline.error, ca #log4j.additivity.kline.error = false

    log4j.appender.server=org.apache.log4j.RollingFileAppender log4j.appender.server.File=../log/server_output.log log4j.appender.server.Append=false log4j.appender.server.MaxFileSize=3MB log4j.appender.server.MaxBackupIndex=10 log4j.appender.server.ImmediateFlush=true log4j.appender.server.layout=org.apache.log4j.PatternLayout log4j.appender.server.layout.ConversionPattern=%d %-5p %m%n

    log4j.appender.server.error=org.apache.log4j.RollingFileAppender log4j.appender.server.error.File=../log/server_error.log log4j.appender.server.error.Append=false log4j.appender.server.error.Threshold=ERROR log4j.appender.server.error.MaxFileSize=3MB log4j.appender.server.error.MaxBackupIndex=10 log4j.appender.server.error.layout=org.apache.log4j.PatternLayout log4j.appender.server.error.layout.ConversionPattern=%d %-5p %m%n

    log4j.appender.kline=org.apache.log4j.RollingFileAppender log4j.appender.kline.File=../log/kline_output.log log4j.appender.kline.Append=false log4j.appender.kline.MaxFileSize=10MB log4j.appender.kline.MaxBackupIndex=10 log4j.appender.kline.ImmediateFlush=true log4j.appender.kline.layout=org.apache.log4j.PatternLayout log4j.appender.kline.layout.ConversionPattern=%d %-5p %m%n

    log4j.appender.kline.error=org.apache.log4j.RollingFileAppender log4j.appender.kline.error.File=../log/kline_error.log log4j.appender.kline.error.Append=false log4j.appender.kline.error.MaxFileSize=3MB log4j.appender.kline.error.MaxBackupIndex=10 log4j.appender.kline.error.ImmediateFlush=true log4j.appender.kline.error.layout=org.apache.log4j.PatternLayout log4j.appender.kline.error.layout.ConversionPattern=%d %-5p %m%n

    #对Appender ca进行设置: # 这是一个控制台类型的Appender #  输出格式(layout)为PatternLayout log4j.appender.ca=org.apache.log4j.ConsoleAppender log4j.appender.ca.Threshold=WARN log4j.appender.ca.layout=org.apache.log4j.PatternLayout log4j.appender.ca.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %.16c - %m%n

    七、打印日志的方法

    LOG4CXX_INFO(log4cxx::Logger::getLogger("hello"), "你好,log4cxx!");

    以上打印方法可行,不过写起来比较麻烦,建议进行一番包装。

    如下代码所示:

    /******************************************************************************
      author  : luhx
      purpose : 日志系统,以宏log_XXX开头,封装log4cxx日志。
    *******************************************************************************/
    #pragma once
     
     
    #include "log4cxx/logger.h"
    #include "log4cxx/propertyconfigurator.h"
    /*
    日志类
    */
     
    #include<string>
    using namespace std;
     
    class CServerlog;
    extern CServerlog* g_serverlog;
     
    #define log_debug(pszFormat, ...)    g_serverlog->WriteFormatDebugLog( pszFormat, __VA_ARGS__)
    #define log_info(pszFormat, ...)    g_serverlog->WriteFormatInfoLog( pszFormat, __VA_ARGS__)
    #define log_warn(pszFormat, ...)    g_serverlog->WriteFormatWarnLog( pszFormat, __VA_ARGS__)
    #define log_error(pszFormat, ...)    g_serverlog->WriteFormatErrorLog( pszFormat, __VA_ARGS__)
     
    class CServerlog
    {
    public:
        CServerlog();
        ~CServerlog();
     
        void WriteFormatDebugLog(char* lpszFormat, ...);
        void WriteFormatInfoLog(char* lpszFormat, ...);    
     
        void WriteFormatWarnLog(char* lpszFormat, ...);
        void WriteFormatErrorLog(char* lpszFormat, ...);
     
    protected:
     
        log4cxx::LoggerPtr infologger;
        log4cxx::LoggerPtr errorlogger;
    };
    #include <Windows.h> 
    #include <tchar.h> 
    #include <stdio.h> 
    #include "serverlog.h"
     
     
    CServerlog* g_serverlog = new CServerlog();
     
    CServerlog::CServerlog()
    {
        log4cxx::PropertyConfigurator::configure("log4cxx.properties");
        infologger = (log4cxx::Logger::getLogger("server"));
        errorlogger = (log4cxx::Logger::getLogger("server.error"));
    }
     
    CServerlog::~CServerlog()
    {
    }
     
     
    void CServerlog::WriteFormatDebugLog(char* lpszFormat, ...)
    {
        va_list args;
        va_start(args, lpszFormat);
        CHAR szBuffer[1024];
        vsprintf(szBuffer, lpszFormat, args);
        va_end(args);
        infologger->debug(szBuffer);
    }
     
     
    void CServerlog::WriteFormatInfoLog(char* lpszFormat, ...)
    {
        va_list args;
        va_start(args, lpszFormat);
        CHAR szBuffer[1024];
        vsprintf(szBuffer, lpszFormat, args);
        va_end(args);
        infologger->info(szBuffer);
    }
     
    void CServerlog::WriteFormatWarnLog(char* lpszFormat, ...)
    {
        va_list args;
        va_start(args, lpszFormat);
        CHAR szBuffer[1024];
        vsprintf(szBuffer, lpszFormat, args);
        va_end(args);
     
        errorlogger->warn(szBuffer);
    }
     
    void CServerlog::WriteFormatErrorLog(char* lpszFormat, ...)
    {
        va_list args;
        va_start(args, lpszFormat);
        CHAR szBuffer[1024];
        vsprintf(szBuffer, lpszFormat, args);
        va_end(args);
        errorlogger->error(szBuffer);
    }
     

    另外,发现打印出的日志在某些机器上不支持中文, 中文显示为乱码,通过在配置文件中增加如下配置项即可解决:

    log4j.appender.sample.encoding=UTF-8,这里,sample即为你的日志类.

    前面已经说完了怎样使用log4cxx进行日志记录,今天发现问题稍有点复杂。原因是系统中用到的一个dll已经使用了log4cxx。我们在开发的过程中也想使用log4cxx,但不想与DLL中的日志写到同一个文件中,问题就来了,怎样区别打印到不同的文件中呢,DLL中采用的为应该为getRootLogger的方式。

    这个网址中的文章很好,解决方案主要参考此文:http://www.open-open.com/doc/view/4bf2bd4f517c4044b1f7d4e2d22eccaf

    log4cxx主要是由三部分组成:loggers, appenders和layouts.这三个主要组成部分,协同协作能够使我们根据实际的需要进行日志的输出,它们规定了日志信息的类型和级别,控制应用程序运行时的日志信息组成方式以及日志记录的输出方式。

    Logger是Log4cxx的核心,Logger具有继承关系的层次结构,最顶层为RootLogger,每个Logger都有一个级别(Level),每个Logger可以附加多个Appender.Appender代表了日志输出的目标,对于每一个Appender可以通过Layout进行格式配置。

    Logger命名:保持Logger与其所在的类的名称一致的方法是目前所知的最好的命名策略。

    一个关于Logger继承的例子:

    #设置root logger 为DEBUG级别,使用了ca, fa两个Appender

    log4j.rootLogger = DEBUG, ca, fa

    #设置list logger

    log4j.logger.list = DEBUG, listApp

    #设置list.voice logger

    log4j.logger.list.voice= INFO, listVoice, listVoiceBak

    list是list.voice的父亲Logger, list.voice是list的儿子Logger. rootLogger是根Logger, 在此例中list和list.voice两个Logger又都继承了rootLogger,不过只是继承了Appenders,Level并没有继。(此解有待验证)

    还是看配置文件:log4cxx.properties

    # 设置root logger为DEBUG级别,使用了ca和fa两个Appender 
    log4j.rootLogger=DEBUG, fa, ca 
    # 设置.listApp logger,屏蔽logger-list的LEVEL继承 
    log4j.logger.listApp=DEBUG, listApp

    # 设置.listApp2 logger,屏蔽logger-list的LEVEL继承 
    log4j.logger.listApp2=DEBUG, listApp2

    #屏蔽listApp的Appender继承 
    log4j.additivity.listApp=false

    #屏蔽listApp2的Appender继承 
    log4j.additivity.listApp2=false

    #对Appender fa进行设置:# 这是一个文件类型的Appender, 
    log4j.appender.fa=org.apache.log4j.FileAppender 
    log4j.appender.fa.ImmediateFlush=true

    # 其输出文件(File)为 Runlog.log, 
    log4j.appender.fa.File=Runlog.log 
    log4j.appender.fa.layout=org.apache.log4j.PatternLayout

    # 输出方式(Append)为覆盖方式, 
    log4j.appender.fa.Append=false

    # 输出格式(layout)为PatternLayout 
    log4j.appender.fa.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %.16c - %m%n

    #对Appender ca进行设置:

    # 这是一个控制台类型的Appender 
    log4j.appender.ca=org.apache.log4j.ConsoleAppender

    # 输出格式(layout)为PatternLayout 
    log4j.appender.ca.layout=org.apache.log4j.PatternLayout 
    log4j.appender.ca.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %.16c - %m%n

    #对Appender listApp进行设置# 这是一个文件类型的Appender, 
    log4j.appender.listApp=org.apache.log4j.FileAppender

    #立即写入日志文件 
    log4j.appender.listApp.ImmediateFlush=true

    # 其输出文件(File)为 listApp.log 
    log4j.appender.listApp.File=listApp.log

    # 输出方式(Append)为覆盖方式, 
    log4j.appender.listApp.Append=false 
    log4j.appender.listApp.layout=org.apache.log4j.PatternLayout 
    log4j.appender.listApp.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %.16c - %m%n

    #对Appender listApp2进行设置 
    log4j.appender.listApp2=org.apache.log4j.FileAppender 
    log4j.appender.listApp2.ImmediateFlush=true 
    log4j.appender.listApp2.File=listApp2.log 
    log4j.appender.listApp2.Append=false 
    log4j.appender.listApp2.layout=org.apache.log4j.PatternLayout 
    log4j.appender.listApp2.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %.16c - %m%n

    以下为实现代码:

    // testlog4cxx.cpp : 定义控制台应用程序的入口点。
    //
     
    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    #include <log4cxx/logger.h>
    #include <log4cxx/propertyconfigurator.h>
     
    using namespace log4cxx;
    using namespace log4cxx::helpers;
     
    int _tmain(int argc, _TCHAR* argv[])
    {
     
        PropertyConfigurator::configure("log4cxx.properties");
     
        LOG4CXX_INFO(log4cxx::Logger::getLogger("list5"), "list,log4cxx!");
        LOG4CXX_INFO(log4cxx::Logger::getLogger("list5"), "list,mylog4cxx!");
     
        LOG4CXX_INFO(log4cxx::Logger::getLogger("listApp"), "listApp,log4cxx!");
     
        LOG4CXX_INFO(log4cxx::Logger::getLogger("listApp2"), "listApp2, hello world!");
     
        return 0;
    }

    将log4cxx.properties与生成后的testlog4cxx.exe放置同一目录,运行后发现目录下生成三个文件,分别为:他们的文件名及内容分别为

    Runlog.log:

    2012-04-06 21:13:56 INFO  list5 - list,log4cxx! 
    2012-04-06 21:13:56 INFO  list5 - list,mylog4cxx!

    listApp.log:

    2012-04-06 21:13:56 INFO  listApp - listApp,log4cxx! 
    2012-04-06 21:13:56 INFO  listApp - listApp TimeRsp.nErrno: 123

    listApp2.log:

    2012-04-06 21:13:56 INFO  listApp2 - listApp2, hello world!

    由此可以看出,所有Logger默认继承于rootLogger的Appender,一般情况下(Level级别允许)总会在Runlog.log中打出,若想有所例外,需用配置log4j.additivity.AppenderName = false将默认继承去除。

  • 相关阅读:
    matlab在图像中画长方形(框)
    将matlab的figure保存为pdf,避免图片太大缺失
    机器学习经典书籍
    2008年北大核心有效期 计算机类核心(2011-01-31 15:02:46)
    解决Matlab画图直接保存.eps格式而导致图不全的问题
    matlab从文件夹名中获得该文件夹下所图像文件名
    获取图片中感兴趣区域的信息(Matlab实现)
    Eclipse 浏览(Navigate)菜单
    Eclipse 查找
    Eclipse 悬浮提示
  • 原文地址:https://www.cnblogs.com/fire909090/p/7495444.html
Copyright © 2011-2022 走看看