当前位置: 首页 > 工具软件 > Log4c > 使用案例 >

Linux log工具:交叉编译log4c及使用示例

张成济
2023-12-01

1、概述


就是一个开源的日志系统,嗯。

优点:代码纯c,比log4cpp&log4cplus可移植性高;

缺点:不再维护(最新版本为1.2.4),不是面向对象,存在内存泄漏问题。(但还是了解下使用方法吧)


2、交叉编译log4c


log4c有是否使用expat库来解析xml的2种不同编译方式,不过README文档里推荐使用expat库。当然如果不想依赖这些库也可以在./configure时使用--without-expat选项,这样就不使用expat库来解析,而是使用了yacc/lex。以下分别介绍2种编译方式:

2.1 使用expat库的编译方式

① 先编译expat库:

由于log4c依赖expat库来解析xml文件,所以先编译得到它的库。

下载地址:https://github.com/libexpat/libexpat/releases

编译步骤:

tar xjvf expat-2.2.10.tar.bz2
cd expat-2.2.10/
./configure --prefix=$PWD/tmp --host=arm-linux-gnueabihf CC=arm-linux-gnueabihf-gcc
make
make install

② 再编译log4c

下载地址:http://log4c.sourceforge.net/

tar xzvf log4c-1.2.4.tar.gz
cd log4c-1.2.4/
./configure --prefix=$PWD/tmp --host=arm-linux-gnueabihf CC=arm-linux-gnueabihf-gcc \
	CFLAGS=-I$PWD/../expat-2.2.10/tmp/include \
	LDFLAGS=-L$PWD/../expat-2.2.10/tmp/lib
make
make install
2.2 不使用expat库的编译方式
tar xzvf log4c-1.2.4.tar.gz
cd expat-2.2.10/
./configure --prefix=$PWD/tmp --host=arm-linux-gnueabihf CC=arm-linux-gnueabihf-gcc --without-expat
make
make install

编译安装完成之后将tmp/目录下的文件拷贝到目标板对应的目录即可。


3、log4c使用


3.1 配置文件log4crc的基本概念

log4crc文件可以放在安装路径的etc目录、也可以是家目录下的.log4crc,也可以与可执行程序放到同一目录下(参考log4c-1.2.4-arm/src/log4c/init.c),它的内容是xml形式。文件内容主要包含三个重要的概念:

  • category(类别): 用于区分不同的logger,通过它可以设定多个logger。category需要指定它的appender:
    • name:日志的名称;
    • priority:日志的优先级,有fatal/alert/crit/error/warn/notice/info/debug/trace/notest/unknow共11个级别;
    • appender:用于指定特定的appender;
  • appender(附加): 用来描述输出目的地,决定log信息流出到什么地方,比如stdout、stderr、文件等。appender需要指定它的layout来设定日志信息的格式:
    • name:输出流的名称;
    • type:输出流的类型;
    • layout:输出日志格式的名称,用于指定特定的layout;
    • rollingpolicy:输出日志文件策略的名称,用于指定特定的rollingpolicy;
  • layout(布局): 设置日志信息的格式,比如是否加上时间戳、文件位置信息等:
    • name:输出日志格式的名称;
    • type:输出日志格式的类型;
      • basic:以“[日志的级别] [日志的category] - [日志的内容]”格式输出;
      • dated:以“[日志的时间] [日志的级别] [日志的category] - [日志的内容]”格式输出,时间格式为yyyymmdd hh:mm:ss.ms;
  • rollingpolicy(滚动策略):
    • name:日志文件输出的策略名称;
    • type:输出日志文件的策略类型;
    • maxsize:输出日志文件的最大值,默认为20KByte;
    • maxnum:保存的历史日志文件总数,默认为5。

log4crc示例:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE log4c SYSTEM "">

<log4c>

    <config>
        <bufsize>0</bufsize>
        <debug level="0"/>
        <nocleanup>0</nocleanup>
    </config>

    <!-- root category ========================================= -->
    <category name="root" priority="notice"/>

    <category name="log4c.mytest" priority="debug" appender = "stdout"/>

    <!-- default appenders ===================================== -->
    <appender name="stdout" type="stream" layout="basic"/>
    <appender name="stderr" type="stream" layout="dated"/>
    <appender name="syslog" type="syslog" layout="basic"/>

    <!-- default layouts ======================================= -->
    <layout name="basic" type="basic"/>
    <layout name="dated" type="dated"/>
</log4c>

3.2 C语言使用示例

3.2.1 C语言API接口:

/* 定义 */
typedef struct __log4c_category {
	char*         cat_name;
	int           cat_priority;
	int           cat_additive;
	const log4c_category_t*   cat_parent;
	log4c_appender_t*     cat_appender;
}log4c_category_t;

/* 初始化 */
LOG4C_API int log4c_init(void);

/* 反初始化 */
LOG4C_API int log4c_fini(void);

/* 根据参数a_name获取一个已有的category */
LOG4C_API log4c_category_t* log4c_category_get(const char* a_name);

/* 日志输出,最后参数为变参 */
void log4c_category_log(const log4c_category_t* a_category,
						int a_priority,
						const char* a_format,
						...);

/* 日志输出,参数加入调用者位置信息 */
void log4c_category_log_locinfo(const log4c_category_t* a_category, 
                                const log4c_location_info_t* a_locinfo, 
                                int a_priority, 
                                const char* a_format, 
                                ...);

/* 日志级别 */
typedef enum {
   /** fatal */    LOG4C_PRIORITY_FATAL    = 000,
   /** alert */    LOG4C_PRIORITY_ALERT    = 100,
   /** crit */     LOG4C_PRIORITY_CRIT	   = 200,
   /** error */    LOG4C_PRIORITY_ERROR    = 300,
   /** warn */     LOG4C_PRIORITY_WARN 	   = 400,
   /** notice */   LOG4C_PRIORITY_NOTICE   = 500,
   /** info */     LOG4C_PRIORITY_INFO     = 600,
   /** debug */    LOG4C_PRIORITY_DEBUG    = 700,
   /** trace */    LOG4C_PRIORITY_TRACE    = 800,
   /** notset */   LOG4C_PRIORITY_NOTSET   = 900,
   /** unknown */  LOG4C_PRIORITY_UNKNOWN  = 1000
} log4c_priority_level_t;

3.2.2 C语言使用例程:

(logcrc内容见上面示例)

#include <stdio.h>
#include "log4c.h"

int main(int argc, char **argv)
{
    log4c_category_t *mytest = NULL;
    
    /* 初始化 */
    if(log4c_init()){
        printf("log4c_init error!\n");
        goto err;
    }
    
    /* 获取已配置的category */
    mytest = log4c_category_get("log4c.mytest");

    /* 输出日志 */
    log4c_category_log(mytest, LOG4C_PRIORITY_INFO, "hello, world!");

    /* 反初始化 */
    if(log4c_fini()){
        printf("log4c_fini error!\n");
        goto err;
    }

    return 0;

err:
    return -1;
}

编译:

arm-linux-gnueabihf-gcc mytest.c -o mytest -llog4c -I./log4c-1.2.4/tmp/include -L./log4c-1.2.4/tmp/lib

测试:

$ ./mytest
[stdout] 20210324 06:15:51.136 INFO     log4c.mytest- hello, world!

另外,如果想将log直接保存到文件中,则可以将log4crc文件修改为:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE log4c SYSTEM "">

<log4c>

    <config>
        <bufsize>0</bufsize>
        <debug level="0"/>
        <nocleanup>0</nocleanup>
    </config>

    <!-- root category ========================================= -->
    <category name="root" priority="notice"/>

    <!-- 输出到文件mylogfilename.x ========================================= -->
    <category name="log4c.mytest" priority="debug" appender = "myrollingappender"/>
    <appender name="myrollingappender" type="rollingfile" logdir="./" prefix="mylogfilename" layout="dated" rollingpolicy="myrollingpolicy" />
    <rollingpolicy name="myrollingpolicy" type="sizewin" maxsize="1024000" maxnum="10" />

    <!-- default appenders ===================================== -->
    <appender name="stdout" type="stream" layout="basic"/>
    <appender name="stderr" type="stream" layout="dated"/>
    <appender name="syslog" type="syslog" layout="basic"/>

    <!-- default layouts ======================================= -->
    <layout name="basic" type="basic"/>
    <layout name="dated" type="dated"/>
</log4c>

参考文章:
  log4c 使用手册(整合多个资料) - 爱耍流氓的兔子.CSDN
  log4c编译与简单使用总结 - log4c编译与简单使用总结.OSCHINA
  Log4C使用总结_百度文库

 类似资料: