zlog 配置文件三大块参数格式完全详解(global / formats / rules)

📅 2026/8/7 11:29:21
zlog 配置文件三大块参数格式完全详解(global / formats / rules)
参考zlog 官方 UsersGuide Chapter 5Gitee 镜像https://gitee.com/wanghelou/zlog/blob/master/doc/UsersGuide-EN.md#chapter-5-configure-file与 GitHub 上游HardySimpson/zlog同源一、配置文件总览zlog 配置是 ini 风格节section顺序固定[global] → [levels](可选) → [formats] → [rules]通用规则#开头是注释支持行尾注释。等号两侧空格随便加key value和keyvalue都行。自定义格式名、category 名区分大小写内置参数名、级别名不区分大小写。数值可带单位大小写不敏感计数1k1000、1m1000000、1g10^9容量1kb1024、1mb1024²、1gb1024³文件路径、格式字符串必须用双引号包起来。二、[global]全局参数全部字段[global]整块可省略省略时全部走默认值。语法统一为(key) (value)key 是空格分隔的多单词这也是高频坑写rotate_lock_file这种下划线形式会被判未知键而strict init默认true直接zlog_init()返回非 0程序起不来。参数默认值格式 / 取值说明strict inittruetrue/falsetrue时严格校验所有 formats/rules 语法任何错误zlog_init()返回 -1false时忽略错误继续reload conf period0数字可选单位(K/M/G)进程累计写多少条日志后自动zlog_reload()原子操作失败保留旧配置。0不自动重载buffer min1K数字KB/MB/GB每线程初始 malloc 的日志缓冲大小buffer max2MB数字KB/MB/GB0无限制单条日志缓冲上限超长截断0表示不限每次翻倍直到 OOMrotate lock fileself路径 或self多进程安全轮转的 fcntl 锁文件。self用配置文件本身当锁指定路径时确保多进程都有 rw 权限default format%d %V [%p:%F:%L] %m%nformats 块里的名字或双引号模板rules 里没写; formatname时用的默认格式file perms600八进制权限新建日志文件权限最终 file perms ~umaskfsync period0数字条数每条文件规则累计写多少条调一次fsync()。0让 OS 自己刷最快但可能丢最后一批示例带注释[global] strict init true # 错一点就报错方便调试 reload conf period 1M # 每 100 万条自动重载配置 buffer min 4KB # 线程起步 4KB 缓冲 buffer max 8MB # 单条最大 8MB超长截断 rotate lock file /tmp/zlog.lock # 多进程轮转锁 default format %d %V[%p:%F:%L] %m%n # 默认格式模板注意 %V 是级别 file perms 640 # 新建日志文件权限 fsync period 1K # 每 1000 条 fsync 一次⚠️fsync 的性能取舍官方实测量级10 万条日志fsync period0OS 自刷约 1.8s1K约 42s慢 20 倍但安全10K约 6.9s折中。生产一般1K~10K调试可设0。要极致安全不怕慢用 rules 里路径前加-O_SYNC。三、[formats]格式模板3.1 语法格式名 转换字符串格式名字母、数字、下划线作为唯一标识供 rules 引用。字符串必须双引号由普通字符和%转换符组成。3.2 全部转换字符已对照 1.2.18 源码核对字符含义示例输出%d(fmt)日期时间括号内是 strftime 格式省略默认%Y-%m-%d %H:%M:%S%d(%F %T)→2026-07-28 15:30:00%ms毫秒3 位补零045%us微秒6 位补零123456%V级别大写INFO← 打级别用它INFO%v级别小写infoinfo%ccategory 名my_app%p进程 PIDgetpid()← 不是级别2134%t线程 ID十六进制0xba01e700%T线程 ID十进制长整型140633234859776%F源文件全路径__FILE__src/main.c%f源文件名去路径main.c%L行号__LINE__56%U函数名__func__main%H主机名dev-server%E(KEY)环境变量值%E(HOME)→/root%M(key)/%x{key}线程 MDC 键值%M(reqId)→abc123%m用户消息本体hello%n换行跨平台\n%%字面%%易错点再强调级别用%V/%v进程号才是%p没有%P这个级别数字转换符网上某些资料列的%P是错的。3.3 格式修饰对齐 / 截断printf 风格写在%和字母之间%-6V级别左对齐、固定宽 6INFO%8.8f文件名宽 8、超出截断%12.2E(HOME)环境变量值占 12 位3.4 命名模板示例[formats] # 极简只输出消息 simple %m%n # 标准时间 级别 category 文件:行号 消息 normal %d(%F %T) [%V] %c %f:%L | %m%n # 带毫秒 级别对齐 rich %d(%Y-%m-%d %H:%M:%S.%ms) %-6V (%c:%F:%L) - %m%n # MDC 链路追踪 mdc %d [%V] req%M(reqId) uid%M(uid) %m%n四、[rules]规则块最核心、语法最复杂每行一条独立规则多规则可叠加实现同一份日志多目标输出。4.1 完整语法category[.级别筛选] [格式名;] 输出动作[, 输出选项] [文件路径参数]4.2 级别筛选4 种写法写法含义示例cat.*该分类所有级别my_cat.*cat.INFOINFO 及以上含 INFO/NOTICE/WARN/ERROR/FATALmy_cat.INFOcat.DEBUG仅DEBUG不含其他my_dog.DEBUGcat.!ERROR除 ERROR 外所有my_cat.!ERROR内置默认级别低→高DEBUG(20) INFO(40) NOTICE(60) WARN(80) ERROR(100) FATAL(120)。4.3 Category 匹配含通配符写法含义*匹配所有 categorymy_前缀通配my_cat、my_dog都命中my_cat精确匹配!兜底命中所有未被其他规则匹配的4.4 输出动作Action一览动作说明输出选项stdout标准输出无stderr标准错误无null黑洞丢弃无syslog转发 syslog必填, LOG_LOCAL0~LOG_LOCAL7/LOG_USER等/path/file.log写文件可含转换符见下方轮转$user_define用户自定义输出函数无| /usr/bin/cronolog管道到外部程序程序路径/dev/tty直接写终端daemon 推荐替代 stdout无⚠️daemon 千万不要用stdout/stderrdaemon 关掉了 fd 0/1/2zlog 会把日志写到 fd1 当前指向的任意文件可能就是自己的配置文件。改用/dev/tty或文件路径必须用 stderr 时确认它仍开着。4.5 文件输出选项动作后的空格分隔子参数路径 size count [compress] [sync] [guard] ~子参数格式说明size1KB/10MB/100MB单文件达此大小触发轮转count* 3或0 *3保留 3 份旧档0保留全部compressgz或compress旧档 gzip 压缩syncsync每条日志 O_SYNC 强同步极慢但安全guardguard启动时检测文件是否被其他进程占用~~分隔大小*份数与归档路径本身不做 fsync4.6 轮转三种模式# 模式 A简单按大小轮转最常用 aa.log 10MB * 3 ~ # aa.log 满 10MB → 重命名链滚动aa.log→aa.log.0→aa.log.1→aa.log.2最旧删除 # 模式 B按大小 序号命名 保留全部 aa.log 10MB 0 #r ~ # 0不删旧档#r 展开成序号生成 aa.log.0、aa.log.1... # 模式 C按日期分文件 %E(HOME)/log/app_%d(%Y%m%d).log 100MB * 2 ~ # 今天写 app_20260728.log明天自动写 app_20260729.log4.7 文件路径里的转换符动态路径写法展开为%E(HOME)/log/app.log$HOME/log/app.log%c.logcategory 名.log%d(%Y%m%d).log日期.log%12.2E(HOME)/log/%c.log路径宽 12 对齐 HOME category支持%E(NAME)取环境变量、%c取 category。4.8 rules 完整示例逐行拆解[rules] # 1) 默认分类全级别 → stdout用 simple 格式 default.* stdout; simple # 2) 所有分类全级别 → 按 HOME 动态路径1MB 轮转保留 12 份 *.* %12.2E(HOME)/log/%c.log 1MB*12; simple # 3) my_ 前缀 INFO 及以上 → stderr my_.INFO stderr; # 4) my_cat 除 ERROR 外 → 文件 my_cat.!ERROR /var/log/aa.log # 5) my_dog 仅 DEBUG → syslog local0用 simple 格式 my_dog.DEBUG syslog, LOG_LOCAL0; simple # 6) my_mice 全级别 → 用户自定义输出函数 my_mice.* $user_define;五、 生产级完整示例配置文件# zlog.conf —— 控制台 文件按天切 错误单独 fsync syslog 转发 [global] strict init true log level DEBUG buffer min 4KB buffer max 4MB rotate lock file /var/lock/zlog.lock default format %d(%F %T.%ms) [%V] %c %f:%L - %m%n file perms 640 fsync period 5K [formats] rich %d(%F %T.%ms) %-6V [%c] %f:%L | %m%n simple %d(%T.%ms) %V %m%n [rules] # 规则语法category.level 动作/路径 [轮转选项] ; 格式名 # 控制台开发期用daemon 上线后注释掉 app.* stdout ; rich # 主日志按天分文件100MB 兜底轮转保留 7 天 app.INFO /var/log/app_%d(%Y%m%d).log 100MB * 7 ~ ; rich # 错误单独一份每条 fsync 不丢 app.ERROR /var/log/app.err 1MB * 5 sync ~ ; rich # DEBUG 走 syslog local0配合 rsyslog 远程转发 app.DEBUG syslog, LOG_LOCAL0 ; simple或者# # zlog.conf —— 生产级Arm Linux # 顺序固定global → levels → formats → rules # [global] # 配置错一点就报错方便上线前用 zlog-chk-conf 抓笔误 strict init true log level DEBUG # 每线程日志缓冲嵌入式设备线程数多/行长时调大 buffer max buffer min 4KB buffer max 4MB # 多进程共享同一日志文件时的轮转安全锁fork 后各自 zlog_init rotate lock file ./tmp/zlog_app.lock # 默认格式模板注意级别用 %V%p 是进程 PID别写错 default format %d(%Y-%m-%d %H:%M:%S.%ms) [%V] %c %F:%L - %m%n # 新建日志文件权限最终 640 ~umask file perms 640 # 普通日志不强制每条 fsyncOS 异步回写性能优先 fsync period 0 # 每写 100 万条自动重载配置也可靠 SIGHUP 触发 reload conf period 1M [levels] # 用内置六级即可DEBUG INFO NOTICE WARN ERROR FATAL # 如需自定义级别在此追加例如TRACE 10 [formats] # 标准格式时间(带毫秒) 级别 category 文件:行号 消息 rich %d(%Y-%m-%d %H:%M:%S.%ms) %-6V [%c] %F:%L | %m%n # 送 syslog 的精简格式只放消息体时间戳/级别由 rsyslog 负责 sysfmt %m [rules] # ---------- 通道1本地文件现场排查用 ---------- # 主日志按天分文件%d(%Y%m%d)单文件 100MB 兜底轮转保留 7 天 # 规则语法category.level 动作/路径 [轮转选项] ; 格式名 app.INFO ./tmp/app_%d(%Y%m%d).log 100MB * 7 ~ ; rich # 错误日志独立文件每条都 sync 强同步1MB 轮转保留 5 份断电不丢关键日志 app.ERROR ./tmp/app.err 1MB * 5 sync ~ ; rich app.FATAL ./tmp/app.err 1MB * 5 sync ~ ; rich # DEBUG仅本地文件按大小轮转保留 3 份不进主日志避免刷屏 app.DEBUG ./tmp/app.debug 10MB * 3 ~ ; rich # ---------- 通道2远程 syslog集中监控告警用 ---------- # 把 ERROR/FATAL 同步送系统 syslog 的 local0 设施 # 由板子 rsyslogd 转发到远端日志中心UDP / TCP 。 app.ERROR syslog, LOG_LOCAL0 ; sysfmt app.FATAL syslog, LOG_LOCAL0 ; sysfmt # 开发/调试期可临时把全部级别打到控制台daemon 上线务必注释掉 # app.* stdout ; rich配套板子 rsyslog 转发/etc/rsyslog.d/30-remote.conf# UDP 转发 local0 全部到日志中心UDPTCPlocal0.* 192.168.1.100:514改完生效systemctl restart rsyslog# systemd 系统# 或 /etc/init.d/rsyslog restart远程用 UDP零握手、低延迟但可能丢可靠性要求高改 TCP代价是连接断开时可能阻塞 rsyslog 队列。应用代码最小骨架#includestdio.h#includezlog.hintmain(void){intrc;zlog_category_t*zc;rczlog_init(/etc/zlog.conf);if(rc){printf(zlog_init failed\n);return-1;}zczlog_get_category(app);/* 名字必须和 rules 里的 app.* 对应 */if(!zc){zlog_fini();return-2;}zlog_debug(zc,debug trace);/* 本地 app.debug */zlog_info(zc,app started, pid%d,getpid());/* 本地按天文件 */zlog_error(zc,db connect failed: %m);/* 本地 app.err syslog local0 */zlog_fini();return0;}配置文件验证zlog-chk-conf ./zlog.conf提示ERROR(22572:level_list.c:141)str is[], cantfindlevel --[./zlog.conf]syntax right这个报错 str is [], can’t find level 是 zlog 的一个已知问题在 [global] 配置段中缺少log level 配置项导致 zlog 解析全局日志级别时拿到了空字符串触发了错误日志。zlog-chk-conf 最终提示syntax right是因为这不属于语法错误而是语义配置缺失语法结构本身能被解析但运行时会因为找不到全局级别触发异常。在 [global] 段显式添加 log level 配置即可解决.[global] rotate lock file ./tmp/zlog_mp.lock strict init true log level DEBUG [formats] fmt %d(%Y-%m-%d %H:%M:%S.%ms) [%p] %m%n [rules] mp.DEBUG ./log/multi.log, 1MB * 5; fmt