zoukankan      html  css  js  c++  java
  • 一起学习log4cxx

    目前成熟的日志系统有很多,比如log4cxx,log4cpp等,今天一起来学习log4cxx吧,之所以学习这个,首先,这个日志库比较成熟,一直由apach基金在维护,而log4cpp缺乏维护.再者,这个库的性能相对高一些,大约为10w行/s.

    log4cxx依赖于apach的另外两个开源库apr和apr-util.

    准备工作:

    首先下载 apr-1.7.0.tar.gz, apr-util-1.6.1.tar.gzlog4cxx库

    百度网盘

    提取码: kzwc 

    1. 安装依赖库apr和apr-util

    #首先解压压缩包
    $ tar -zxvf apr-1.7.0.tar.gz
    $ cd apr-1.7.0
    
    $ ./configure --prefix=/usr/local
    $ make
    $ sudo make install
    #首先解压压缩包
    $ tar -zxvf apr-util-1.6.1.tar.gz
    $ cd apr-util-1.6.1
    
    $ ./configure --prefix=/usr/local --with-apr=/usr/local
    $ make
    $ sudo make install

    2.安装log4cxx

    tar -zxvf apache-log4cxx-0.10.0.tar.gz  
    cd apache-log4cxx-0.10.0  
    ./configuer --prefix=/usr/local/ --with-apr=/usr/local/ --with-apr-util=/usr/local/  --with-charset=utf-8 --with-logchar=utf-8  
    make
    sudo make install

    安装log4cxx可能会报错:

    解决办法:

    1 inputstreamreader.cpp:66: error: 'memmove' was not declared in this scope  
    2 make[3]: *** [inputstreamreader.lo] 错误 1  
    #这是由于以下几个文件缺少了标准库文件,添加上就可以了
    3 src/main/cpp/inputstreamreader.cpp添加#include <string.h>  
    4 src/main/cpp/socketoutputstream.cpp添加#include <string.h>  
    5 src/examples/cpp/console.cpp添加#include <string.h>;#include <stdio.h>;

    3. 封装log4cxx日志库
    /*!
    * Email: scictor@gmail.com
    * Auth: scictor
    * Date: 2019-9-8
    * File: zlog4cxx.h
    * Class: zlog4cxx (if applicable)
    * Brief:
    * Note:
     */
    
    #ifndef ZLOG4CXX_H
    #define ZLOG4CXX_H
    
    #include <log4cxx/logger.h>
    #include <log4cxx/logstring.h>
    #include <log4cxx/propertyconfigurator.h>
    #include<string>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    using namespace log4cxx;
    using namespace log4cxx::helpers;
    #include <stdarg.h>
    using namespace std;
    #define SAFE_DELETE_ARRAY(v_para)
    do 
    {
        if (NULL != v_para) {
        delete[] v_para;
        v_para = NULL;
        }
    } while (0)
    //TRACE < DEBUG < INFO < WARN < ERROR < FATAL
    typedef enum _LOG_LEVEL
    {
        LOG_TRACE_ = 0,
        LOG_DEBUG_,
        LOG_INFO_,
        LOG_WARN_,
        LOG_ERROR_,
        LOG_FATAL_
    }LOG_LEVEL;
    #ifndef IN
    #define IN
    #endif
    #ifndef OUT
    #define OUT
    #endif
    /*
    写日志函数
    IN const char* module,//在log4cxx.properties文件中设置了很多个append,这个参数用来设置模块,例如本实例中的fa
    IN const LOG_LEVEL level,日志级别 ERROR、INFO等
    IN const char* file,打印日志函数调用的文件
    IN const char* function, 打印日志的函数
    IN const int line, 打印日志的行号
    IN const char* format,//打印日志的格式 如: "%s%d%f"
    ...                  //可变参数输入
    */
    void log4cxx_package(IN const char* module,IN const LOG_LEVEL level, IN const char* file, IN const char* function,
                         IN const int line, IN const char* format, ...);//
    //宏定义封装,__FILE__, __FUNCTION__, __LINE__ 分别是打印日志的文件名、函数名,行号
    #define LOG(module,level, format,...) log4cxx_package(module,level, __FILE__, __FUNCTION__, __LINE__, format,__VA_ARGS__)
    //按照不同的级别定义宏
    #define FIRE_ERROR(format,...) LOG("fa",LOG_ERROR_, format,__VA_ARGS__)
    #define FIRE_INFO(format,...) LOG("fa",LOG_INFO_, format,__VA_ARGS__)
    #define FIRE_TRACE(format,...) LOG("fa",LOG_TRACE_, format,__VA_ARGS__)
    #define FIRE_DEBUG(format,...) LOG("fa",LOG_DEBUG_, format,__VA_ARGS__)
    #define FIRE_WARN(format,...) LOG("fa",LOG_WARN_, format,__VA_ARGS__)
    #define FIRE_FATAL(format,...) LOG("fa",LOG_FATAL_, format,__VA_ARGS__)   //
    //初始化日志库,传入log4cxx.properties文件的名称
    void log4cxx_init(IN const char* conffile);
    //根据append或者模块名称来获取模块的日志指针。如果是root模块,直接用Logger::getRootLogger();获取
    LoggerPtr get_logger_ptr(IN const char* user);
    
    #endif // ZLOG4CXX_H
    源文件
    /*!
    * Email: scictor@gmail.com
    * Auth: scictor
    * Date: 2019-9-8
    * File: zlog4cxx.cpp
    * Class: zlog4cxx (if applicable)
    * Brief:
    * Note:
     */
    #include "zlog4cxx.h"
    
    static std::string ensure_log_complete(IN const char* format,IN va_list args)
    {
        if (NULL == format)
        {
            return "";
        }
    
        int iNum = 0;
        unsigned int uiSize = 1024;
        string strLog("");
    
        char *pcBuff = new(std::nothrow) char[uiSize];
        if (NULL == pcBuff)
        {
            return strLog;
        }
    
        while(true)
        {
            memset(pcBuff, 0,uiSize);
    
            iNum = vsnprintf(pcBuff, uiSize, format, args);
            if ((iNum > -1) && (iNum < (int)uiSize))
            {
                strLog = pcBuff;
                SAFE_DELETE_ARRAY(pcBuff);
    
                return strLog;
            }
    
            //如果字符串值比默认分配大,则分配更大空间
            uiSize = (iNum > -1)?(int)(iNum + 1):(uiSize * 2);
            SAFE_DELETE_ARRAY(pcBuff);
    
            pcBuff = new(std::nothrow) char[uiSize];
            if (NULL == pcBuff)
            {
                return strLog;
            }
        }
    
        SAFE_DELETE_ARRAY(pcBuff);
    
        return strLog;
    }
    /*
    写日志函数
    IN const char* module,//在log4cxx.properties文件中设置了很多个append,这个参数用来设置模块,例如本实例中的fa
    IN const LOG_LEVEL level,日志级别 ERROR、INFO等
    IN const char* file,打印日志函数调用的文件
    IN const char* function, 打印日志的函数
    IN const int line, 打印日志的行号
    IN const char* format,//打印日志的格式 如: "%s%d%f"
    ... //可变参数输入
    */
    void log4cxx_package(IN const char* module,IN const LOG_LEVEL level, IN const char* file, IN const char* function,
                         IN const int line, IN const char* format, ...)
    {
        if (level > LOG_FATAL_ || level < LOG_TRACE_)
        {
            return;
        }
    
        if (NULL == file || NULL == function || NULL == format)
        {
            return;
        }
    
        LoggerPtr pLogger=nullptr;
        if (module!=NULL)
        {
            pLogger=get_logger_ptr(module);
        }
        if(pLogger==NULL)
        {
             pLogger= Logger::getRootLogger();
        }
    
        char acTmp[30] = { 0 };
        sprintf(acTmp,"%d",line);
    
        va_list args;
        std::string strLog;
        strLog = "[" + std::string(file) + ":" + std::string(function) + "(" + std::string(acTmp) + ")] ";
    
        va_start(args, format);
        strLog += ensure_log_complete(format, args);
        va_end(args);
    
    
        switch (level)
        {
        case LOG_TRACE_:
            LOG4CXX_TRACE(pLogger, strLog.c_str());
            break;
        case LOG_DEBUG_:
            LOG4CXX_DEBUG(pLogger, strLog.c_str());
            break;
        case LOG_INFO_:
            LOG4CXX_INFO(pLogger, strLog.c_str());
            break;
        case LOG_WARN_:
            LOG4CXX_WARN(pLogger, strLog.c_str());
            break;
        case LOG_ERROR_:
    
            LOG4CXX_ERROR(pLogger, strLog.c_str());
            break;
        case LOG_FATAL_:
            LOG4CXX_FATAL(pLogger, strLog.c_str());
            break;
        default:
            break;
        }
    
        return;
    }
    
    void log4cxx_init(IN const char* conffile)//初始化日志库
    {
        // 读取配置文件
        using namespace log4cxx;
        PropertyConfigurator::configure(File(conffile));
        return ;
    }
    
    LoggerPtr get_logger_ptr(IN const char* user)//获取日志模块指针
    {
        // 建立logger
        return Logger::getLogger(user);
    }

    4. 测试

    /*!
    * Email: scictor@gmail.com
    * Auth: scictor
    * Date: 2019-9-8
    * File: %{Cpp:License:FileName}
    * Class: %{Cpp:License:ClassName} (if applicable)
    * Brief:
    * Note:
     */
    #include <bits/stdc++.h>
    #include "zlog4cxx.h"
    using namespace std;
    
    int main(int argc,char **argv){
        log4cxx_init("log4cxx.properties");
        char *pStr = "YES";
        FIRE_INFO("that is ok? %s", pStr);
        printf("hello world!
    ");
        return 0;
    }

    编译: 

    g++11 zlog4cxx.cpp main.cpp -o xlog -llog4cxx

    结果输出

     
    
    
  • 相关阅读:
    停止与暂停线程
    flume日志收集框架
    mysql数据库索引
    junit
    freemarker
    python脚本
    java多线程编程核心技术学习-1
    spring 网站
    [MongoDB]学习笔记--Linux 安装和运行MongoDB
    [Spring MVC]学习笔记--form表单标签的使用
  • 原文地址:https://www.cnblogs.com/guxuanqing/p/11488964.html
Copyright © 2011-2022 走看看