glog默认按severity分文件且高等级日志冗余写入低等级文件,如error同时写入info、warning、error文件;无法关闭冗余,严格分级需自定义logsink或换用spdlog等库。

glog 默认不按级别分文件,而是按 severity 分散写入多个文件
glog(C++ 版)本身没有“把 INFO 单独写进 info.log、ERROR 单独写进 error.log”这种单文件单级别模式。它的默认行为是:每个日志级别(INFO/WARNING/ERROR/FATAL)都写入**各自独立的文件**,且高等级日志会**自动冗余写入低等级文件**。比如一条 LOG(ERROR) 会同时出现在 INFO、WARNING、ERROR 三个日志文件中。
所以“分级输出到不同文件”在 glog 里是开箱即用的,但你要清楚它不是“过滤后定向写入”,而是“全量复制 + 级别覆盖”。关键配置项只有两个:
-
GLOG_log_dir:必须设置,否则日志写进系统临时目录(/tmp或%TEMP%),文件名不可控 -
GLOG_stderrthreshold:控制哪些级别额外打屏(不影响文件写入)
如何让 INFO 只进 info.log,ERROR 只进 error.log?不行,但可以绕过
glog 没提供关闭“冗余写入”的开关——你不能让 LOG(ERROR) 不进 INFO 文件。这是设计使然,不是 bug。
如果你真需要严格隔离(比如审计要求 ERROR 日志绝对不混在 INFO 文件里),只能换方案:
- 改用
google::SetLogDestination()手动接管每个级别目标,但注意:它只控制“主文件前缀”,仍会保留冗余逻辑(ERROR 还是会写 INFO 前缀文件) - 用
google::AddLogSink()注册自定义LogSink,完全接管输出,自己做 level 判断 + 单文件写入(需自行处理线程安全、缓冲、滚动) - 放弃 glog,换成
spdlog或g3log,它们原生支持 per-level handler
命令行参数和代码中设置 GLOG_log_dir 的顺序很重要
GLOG_log_dir 必须在 google::InitGoogleLogging() **之前**设置,否则无效。环境变量方式最稳妥:
export GLOG_log_dir="./logs" ./myapp --logtostderr=1
如果在代码里设,必须这样写:
FLAGS_log_dir = "./logs"; // 注意是 FLAGS_ 开头,不是 GLOG_ google::InitGoogleLogging(argv[0]);
常见错误:
- 先调
InitGoogleLogging()再赋值FLAGS_log_dir→ 日志还是进/tmp - 写成
GLOG_log_dir = "./logs"(少个FLAGS_)→ 编译不过或静默忽略 - 路径不存在且无写权限 → 日志静默丢弃,不报错
文件名格式固定,无法自定义,但可预测
glog 生成的文件名格式为:<program>.<hostname>.<user>.log.<severity>.<date>-<time>.<pid></pid></time></date></severity></user></hostname></program>。例如:
myapp.devhost.alice.log.INFO.20260930-203501.12345
这意味着:
- 你无法改成
info.log这种静态名字;每次启动都会新建带时间戳的文件 - 同一进程多次运行会产生多个 INFO 文件,不会自动轮转合并
- 若要归档,得靠外部脚本按
.log.INFO后缀批量处理,不能依赖 glog 自身
真正容易被忽略的是:glog 不做日志滚动(rotation),也不压缩旧文件。长期运行的服务必须配外部 logrotate 或自己封装 wrapper。











