当前位置: 首页 > article >正文

log4c库使用

log4c库

介绍

log4c 是一个 C 语言实现的日志库,它是 log4j(Java 语言的日志框架)的 C 语言版本,旨在为 C 语言应用程序提供灵活、可配置的日志功能。log4c 提供了丰富的日志功能,包括日志级别、日志输出目标、日志格式等,支持不同的日志策略,比如滚动文件、按大小或按日期滚动等,具有良好的可扩展性和配置能力

安装

解压安装

下载链接
https://sourceforge.net/projects/log4c/files/log4c/1.2.4/log4c-1.2.4.tar.gz/download?use_mirror=onboardcloud&login=from_csdn

tar -zxvf log4c-1.2.4.tar.gz
cd log4c-1.2.4
./configure --prefix=/usr/local/log4c # 必须明确指定安装路径
make
make install

注意
--prefix 必须明确指定安装路径
/usr/local/log4c 这个是系统路径,安装完了之后就可以直接使用,不需要指明头文件位置
如果安装到其他位置,再执行完make install 之后会出现在指定的目录下,使用的时候需要指明头文件位置;

apt安装

sudo apt update
sudo apt install liblog4c-dev

使用方式

cmake 文件编写

apt安装
# 指定 CMake 的最低版本要求
cmake_minimum_required(VERSION 3.10)

# 指定项目名称和语言
project(kylin-wine-starter VERSION 1.0 LANGUAGES C)

# 设置 C 编译器标准
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)

# 自动查找所有的 .c 文件
file(GLOB SOURCES "*.c")

# 定义可执行文件的名称和源文件
add_executable(${PROJECT_NAME} ${SOURCES})

pkg_check_modules(LOG4C REQUIRED log4c)

include_directories(${LOG4C_INCLUDE_DIRS})
link_directories(${LOG4C_LIBRARY_DIRS})

target_link_libraries(${PROJECT_NAME} ${LOG4C_LIBRARIES})
解压安装

请添加图片描述
此处展示的文件结构是本篇文章演示的文件结构

# 指定 CMake 的最低版本要求
cmake_minimum_required(VERSION 3.10)

# 指定项目名称和语言
project(kylin-wine-starter VERSION 1.0 LANGUAGES C)

# 设置 C 编译器标准
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)

# 自动查找所有的 .c 文件
file(GLOB SOURCES "*.c")

# 定义可执行文件的名称和源文件
add_executable(${PROJECT_NAME} ${SOURCES})

set(3RDLIB_PATH ${PROJECT_SOURCE_DIR}/third)  
list(APPEND 3RD_LIBS_INCLUDE "${3RDLIB_PATH}/include")  
list(APPEND 3RD_LIBS_INCLUDE "${3RDLIB_PATH}/include/log4c") 
link_directories("${3RDLIB_PATH}/lib")  
target_link_libraries(${PROJECT_NAME} log4c)   
# link_libraries(log4c)   # 禁止使用这种链接方式
target_include_directories(${PROJECT_NAME} PUBLIC   
    ${PROJECT_BINARY_DIR}   
    ${EXTRA_INCLUDE}   
    ${3RD_LIBS_INCLUDE}  
)

配置输出位置以及轮转策略

log4c使用结构图
在这里插入图片描述
创建一个category管理多个appender,
每个appender都是一个文件,
每个appender中都有一个layout,
每个layout都规定了日志文件中输出的格式;
每个appender都可以设置轮转格式,
需要给appender指定一个轮转文件rollingfile,
给rollingfile指定一个轮转策略rolling_policy,
给rolling_policy 指定一个限制文件大小rolling_sizewin。
这样就能实现通过文件大小进行轮转了

配置文件
  1. 配置文件使用xml格式,默认在当前工作目录下找;默认找到是log4crc(不带扩展名),如果有扩展名(log4crc.xml)需要特别配置环境变量
  2. LOG4C_RCPATH 配置环境变量
  3. 优先找工作目录配置文件,再通过环境变量找配置文件;只要找到了就会停下来,不论这个配置文件是对是错
    配置文件category,appender,rollingpolicy,layout 的相互关系是通过name来相互绑定的
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE log4c SYSTEM "">

<log4c version="1.2.4">

	<config>
		<bufsize>0</bufsize>
		<debug level="2"/>
		<nocleanup>0</nocleanup>
		<reread>1</reread>
	</config>
    <category name="root" priority="error" appender="stdout"/>
	<appender name="stdout" type="stream" layout="basic"/>
	<appender name="stderr" type="stream" layout="dated"/>
	<appender name="syslog" type="syslog" layout="basic"/>
	<layout name="basic" type="basic"/>
	<layout name="dated" type="dated"/>
</log4c>
log4c_init();// 初始化
// 代码中也是通过配置文件中的name进行获取的
log4c_category_t* mycat = log4c_category_get("root"); 
log4c_category_log(mycat,LOG4C_PRIORITY_DEBUG,"输出内容");
log4c_fini();// 销毁
layout 日志输出格式

<layout name="basic" type="basic"/> 这里的type可以替换为下面库里面提供的这些

// layout
const log4c_layout_type_t log4c_layout_type_basic = {
    "basic",// 布局名称,可以替换到layout的type位置
    basic_format,// 布局函数,可以在接下来介绍的API部分为layout设置type
};
const log4c_layout_type_t log4c_layout_type_basic_r = {
    "basic_r",
    basic_r_format,
};
const log4c_layout_type_t log4c_layout_type_dated_local_r = {
    "dated_local_r",
    dated_local_r_format,
};
const log4c_layout_type_t log4c_layout_type_dated_local = {
    "dated_local",
    dated_local_format,
};
const log4c_layout_type_t log4c_layout_type_dated_r = {
    "dated_r",
    dated_r_format,
};
const log4c_layout_type_t log4c_layout_type_dated = {
    "dated",
    dated_format,
};
appender 日志文件

<appender name="myrollingfileappender" type="rollingfile" logdir="." prefix="myprefix" layout="dated_time" rollingpolicy="myrollingpolicy" />
使用下面字符串中的内容替换 type

// 将日志信息写入内存映射文件(mmap)。内存映射文件是操作系统提供的一种将文件或设备映射到内存中的技术,允许程序像操作内存一样操作文件。
const log4c_appender_type_t log4c_appender_type_mmap = {
    "mmap",
    mmap_open,
    mmap_append,
    mmap_close,
};
// 将日志信息写入到文件中,并在日志文件大小达到一定限制时自动进行轮转(即生成新的日志文件)
const log4c_appender_type_t log4c_appender_type_rollingfile = {
    "rollingfile",
    rollingfile_open,
    rollingfile_append,
    rollingfile_close
};
// 将日志信息输出到一个流(如标准输出流、文件流等)。这种方式适用于将日志输出到控制台或文件等流设备。
const log4c_appender_type_t log4c_appender_type_stream = {
    "stream",
    stream_open,
    stream_append,
    stream_close,
};
// 这应该是 stream 的另一种实现,可能有不同的实现或配置,用于特殊场景。
const log4c_appender_type_t log4c_appender_type_stream2 = {
    "stream2",
    stream2_open,
    stream2_append,
    stream2_close,
};
// 将日志信息发送到操作系统的系统日志(通常是 syslog)。适用于需要将日志信息传递给系统日志守护进程进行集中管理的场景。
const log4c_appender_type_t log4c_appender_type_syslog = {
    "syslog",
    syslog_open,
    syslog_append,
    syslog_close,
};

logdir="." 当 type 为rollingfile 的时候设置日志存储位置
prefix="myprefix"当 type 为rollingfile 的时候设置日志的前缀,通常轮转之后的文件是prefix.数字
rollingpolicy 指的是轮转策略
<rollingpolicy name="myrollingpolicy" type="sizewin" maxsize="1024" maxnum="3" />
库中只提供了一种通过文件大小进行轮转的策略
maxsize 表示每个文件最大容量
maxnum 轮转过程中保存最近3个文件

const log4c_rollingpolicy_type_t log4c_rollingpolicy_type_sizewin = {
    "sizewin", // 写入 type 位置
    sizewin_init,
    sizewin_is_triggering_event,
    sizewin_rollover,
    sizewin_fini
};
catgory 用来管理appender

<category name="root" priority="error" appender="stdout"/> priority 可以替换为下面的这些, 将下面注释中的字符串进行替换

// priority —— 输出等级,值越小的等级越高
 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;
直接API

一般情况下只需要引用 log4c.h 这个头文件就可以了,不需要像我下面这样一个一个的列出来,如果在使用的时候发现没有再添加引用就可以了
安装到系统中,头文件引用方式如下

// #include "log4c.h"
// #include "log4c/appender.h"
// #include "log4c/appender_type_rollingfile.h"
// #include "log4c/rollingpolicy.h"
// #include "log4c/rollingpolicy_type_sizewin.h"
// #include "log4c/layout_type_dated.h"

未安装到系统中,头文件引用方式如下

#include "third/include/log4c.h"
#include "third/include/log4c/rc.h"
#include "third/include/log4c/appender.h"
#include "third/include/log4c/layout.h"
#include "third/include/log4c/category.h"
#include "third/include/log4c/appender_type_stream.h"
#include "third/include/log4c/appender_type_rollingfile.h"
#include "third/include/log4c/rollingpolicy.h"
#include "third/include/log4c/rollingpolicy_type_sizewin.h"
#include "third/include/log4c/layout_type_dated_local.h"
#include "third/include/log4c/layout_type_dated.h"
#include "third/include/log4c/layout_type_basic.h"
#include "third/include/log4c/priority.h"


log4c_category_t* mycat = NULL;
void create_log4c_API(char* dir,char* filename,long long size,int num){
	// log4c初始化
    if(log4c_init()){
        puts("497 log4c_init error");
        return;
    }
    // 创建category
    mycat = log4c_category_new(__FILE__);
    if(mycat == NULL){
        puts("mycat is NULL");
        return;
    }
    // 创建appender
    log4c_appender_t* appender = log4c_appender_new("myappender");
    if(appender == NULL){
        puts("appender is NULL");
        return;
    }
    // 设置appender类型
    log4c_appender_set_type(appender, &log4c_appender_type_rollingfile);// 文件轮转类型
	// 为category 设置 appender
    log4c_category_set_appender(mycat,appender);
	
	// 设置轮转的文件相关信息
    rollingfile_udata_t * rollingfile_udata = rollingfile_make_udata();
    // 设置目录
    rollingfile_udata_set_logdir(rollingfile_udata,dir);
    // 设置文件前缀
 rollingfile_udata_set_files_prefix(rollingfile_udata,filename);
	// 判断目录是否可写
    if(access(dir,W_OK) == -1){
        puts("no write permission");
        return;
    }

    // 配置文件滚动策略(基于文件大小滚动)
    log4c_rollingpolicy_t* rollingpolicy = log4c_rollingpolicy_new("sizewin");
    // 为文件设置滚动策略
rollingfile_udata_set_policy(rollingfile_udata,rollingpolicy);

    // 设置滚动策略参数
    rollingpolicy_sizewin_udata_t* swup = sizewin_make_udata();
    sizewin_udata_set_file_maxsize(swup, size);  // 每个日志文件最大大小为1MB
    sizewin_udata_set_max_num_files(swup, num);  // 最多保留5个文件
    // 为策略设置滚动策略参数
    log4c_rollingpolicy_set_udata(rollingpolicy,swup);
    // 初始化滚动策略
    int result = log4c_rollingpolicy_init(rollingpolicy, rollingfile_udata);
    if (result != 0) {
        // 处理错误
        puts("373 error");
        return;
    }
    // 设置附加器的滚动策略
    log4c_appender_set_udata(appender, rollingfile_udata);
    
	// 创建输出格式
    log4c_layout_t* mylayout = log4c_layout_new("mylayout");
    log4c_layout_set_type(mylayout,&log4c_layout_type_dated);
    // 为输出日志设置输出格式
    log4c_appender_set_layout(appender,mylayout);
	
	// 创建/打开日志文件,一般情况下是不需要明确的打开文件
	// 在验证日志没有正确的写入是不是因为没有打开文件造成的时候,可以使用这个函数排除错误
    // if(log4c_appender_open(appender) == 0){
    //     puts("537 file open success");
    // }else{
    //     puts("failed to open");
    // }
    // 输出必须要设置日志等级
    log4c_category_set_priority(mycat,LOG4C_PRIORITY_DEBUG);
    // 输出日志
    log4c_category_log(mycat,LOG4C_PRIORITY_INFO,"log4c_api 配置完成");
    // log4c 销毁
    log4c_fini();
}
log4c 创建和销毁
log4c_init(); // 创建
log4c_fini(); // 销毁
layout 日志输出格式
  1. log4c_layout_t* mylayout = log4c_layout_new("mylayout"); 创建layout
  2. log4c_layout_t* mylayout = log4c_layout_get("mylayout"); 从配置文件中获取namemylayout 的layout
  3. log4c_layout_set_type(mylayout,&log4c_layout_type_dated); 设置输出格式
// layout
const log4c_layout_type_t log4c_layout_type_basic = {
    "basic",
    basic_format, // 布局函数,替换到第二个参数
};
const log4c_layout_type_t log4c_layout_type_basic_r = {
    "basic_r",
    basic_r_format,
};
const log4c_layout_type_t log4c_layout_type_dated_local_r = {
    "dated_local_r",
    dated_local_r_format,
};
const log4c_layout_type_t log4c_layout_type_dated_local = {
    "dated_local",
    dated_local_format,
};
const log4c_layout_type_t log4c_layout_type_dated_r = {
    "dated_r",
    dated_r_format,
};
const log4c_layout_type_t log4c_layout_type_dated = {
    "dated",
    dated_format,
};
  1. log4c_appender_set_layout(appender,mylayout); 将layout绑定到appender上
appender 日志文件
  1. log4c_appender_t* appender = log4c_appender_new("myappender"); 创建
  2. log4c_appender_t* appender = log4c_appender_get("myappender"); 获取配置文件中namemyappenderappender
  3. log4c_appender_set_type(appender, &log4c_appender_type_rollingfile); 设置appender类型,下面的放到第二个参数的位置
// 将日志信息写入内存映射文件(mmap)。内存映射文件是操作系统提供的一种将文件或设备映射到内存中的技术,允许程序像操作内存一样操作文件。
const log4c_appender_type_t log4c_appender_type_mmap = {
    "mmap",
    mmap_open,
    mmap_append,
    mmap_close,
};
// 将日志信息写入到文件中,并在日志文件大小达到一定限制时自动进行轮转(即生成新的日志文件)
const log4c_appender_type_t log4c_appender_type_rollingfile = {
    "rollingfile",
    rollingfile_open,
    rollingfile_append,
    rollingfile_close
};
// 将日志信息输出到一个流(如标准输出流、文件流等)。这种方式适用于将日志输出到控制台或文件等流设备。
const log4c_appender_type_t log4c_appender_type_stream = {
    "stream",
    stream_open,
    stream_append,
    stream_close,
};
// 这应该是 stream 的另一种实现,可能有不同的实现或配置,用于特殊场景。
const log4c_appender_type_t log4c_appender_type_stream2 = {
    "stream2",
    stream2_open,
    stream2_append,
    stream2_close,
};
// 将日志信息发送到操作系统的系统日志(通常是 syslog)。适用于需要将日志信息传递给系统日志守护进程进行集中管理的场景。
const log4c_appender_type_t log4c_appender_type_syslog = {
    "syslog",
    syslog_open,
    syslog_append,
    syslog_close,
};
  1. rollingfile_udata_t * rollingfile_udata = rollingfile_make_udata(); 只能使用这种方式创建轮转的文件相关信息
  2. rollingfile_udata_set_logdir(rollingfile_udata,dir); 设置目录
  3. rollingfile_udata_set_files_prefix(rollingfile_udata,prefix); 设置文件前缀
  4. log4c_rollingpolicy_t* rollingpolicy = log4c_rollingpolicy_new("sizewin"); 配置文件滚动策略(基于文件大小滚动)
  5. rollingpolicy_sizewin_udata_t* swup = sizewin_make_udata(); 只能使用这种方式创建滚动策略参数
  6. sizewin_udata_set_file_maxsize(swup, size); 设置每个文件限定大小
  7. sizewin_udata_set_max_num_files(swup, num); 设置最多保留多少个轮转文件
  8. log4c_appender_set_layout(appender,mylayout); 为输出日志设置输出格式
  9. log4c_appender_set_udata(appender, rollingfile_udata); 设置附加器的滚动策略
  10. rollingfile_udata_set_policy(rollingfile_udata,rollingpolicy); 为文件设置滚动策略
  11. log4c_rollingpolicy_set_udata(rollingpolicy,swup); 为策略设置滚动策略参数
  12. log4c_rollingpolicy_init(rollingpolicy, rollingfile_udata); 初始化滚动策略
catgory 用来管理appender
  1. log4c_category_t* mycat = log4c_category_new("mycategory") 创建
  2. log4c_category_t* mycat = log4c_category_get("mycategory") 从配置文件中获取namemycategory 的category
  3. log4c_category_set_priority(mycat,LOG4C_PRIORITY_DEBUG); 设置日志等级
  4. log4c_category_log(mycat,LOG4C_PRIORITY_INFO,"log4c_api 配置完成"); 输出日志
  5. log4c_category_set_appender(mycat,appender); 设置 appender
    设置日志等级和输出日志部分都需要日志等级,可以使用下面的进行替换
// priority —— 输出等级,值越小的等级越高
 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;

网上的教程很少,AI的回答中使用的函数也都是log4c中没有的,我只能为后来者尽一些绵薄之力,文章讲解不清的地方请见谅,如果要想更精细的控制轮转需要把头埋进源码,希望对各位有帮助

参考

log4c 使用心得+总结


http://www.kler.cn/a/413896.html

相关文章:

  • CentOS上如何离线批量自动化部署zabbix 7.0版本客户端
  • 了解 CSS position 属性
  • Flink CDC 使用实践以及遇到的问题
  • K8s的水平自动扩容和缩容HPA
  • 计算机操作系统——进程控制(Linux)
  • 5.Feign与ReflectiveFeign
  • 【数据结构与算法】链表之美-复杂链表的复制与链表的插入排序
  • 占用磁盘100%?Apache DolphinScheduler 日志如何定时清理!
  • IntelliJ+SpringBoot项目实战(十七)--在SpringBoot中整合SpringSecurity和JWT(下B)
  • Excel按固定行数拆分为多个Excel
  • 屏幕触控支持指纹修改
  • 数据集成工具Kafka、Nifi和Talend功能大对比!
  • Jenkins的使用
  • 【Git】常用命令汇总
  • MySQL底层概述—5.InnoDB参数优化
  • 【Linux】剧幕中的灵魂更迭:探索Shell下的程序替换
  • 每日速记10道java面试题02
  • 从0开始Linux(34)——进程信号(3)信号保存
  • 泡泡玛特出海,如何走出舒适区
  • webrtc ios h264 硬编解码
  • Vue3+Typescript+Axios+.NetCore实现导出Excel文件功能
  • 并行区块链全解:执行原理、代表项目及技术发展周期
  • 深度学习:自然语言处理
  • JS-06-事件监听
  • MongoDB的SQL注入测试方法
  • ubuntu上安装redis