版本范围:a5b0c71a(base)→ 280ccd40(head)
分支:v1.0.10
变更规模:1 个文件、+16 / -1 行
本次增量仅涉及 1 个文件:
| 文件 | 变更性质 | 说明 |
|---|---|---|
internal/logging/logger.go | 功能增强 | 日志格式按运行环境自动切换:容器内输出结构化 JSON,本地 TTY 保持人类可读格式,支持 LOG_FORMAT 覆盖 |
func Init() {
time.Local = timeutil.CST
- logrus.SetFormatter(&CustomFormatter{})
+ // 日志格式:容器内默认 JSON(平台可直接查 duration/level 等字段),本地 TTY 保持 CustomFormatter
+ if useJSONLogs() {
+ logrus.SetFormatter(&logrus.JSONFormatter{TimestampFormat: time.RFC3339Nano})
+ } else {
+ logrus.SetFormatter(&CustomFormatter{})
+ }
logrus.SetReportCaller(true)
...
}
+
+// useJSONLogs 判定是否输出结构化 JSON 日志:
+// 容器内 stdout 不是 TTY(docker logs 采集)→ 默认 JSON;本地 TTY 保持 CustomFormatter;`LOG_FORMAT=json|console` 可显式覆盖。
+func useJSONLogs() bool {
+ if v := strings.TrimSpace(os.Getenv("LOG_FORMAT")); v != "" {
+ return strings.EqualFold(v, "json")
+ }
+ fi, err := os.Stdout.Stat()
+ if err != nil {
+ return false
+ }
+ return fi.Mode()&os.ModeCharDevice == 0
+}
docker logs 采集)默认输出 JSON,便于观测平台(OpenObserve)按 level/duration 等字段直接检索。CustomFormatter。LOG_FORMAT=json|console 环境变量显式覆盖自动判定。针对新增代码逐项核验:
| 检查项 | 结论 |
|---|---|
新增依赖导入(os、strings、time) | ✅ 三个包均已在 import 块中,无编译问题 |
os.Stdout.Stat() 错误处理 | ✅ err != nil 时安全回退为 false(即 CustomFormatter),不会 panic |
| TTY 判定逻辑 | ✅ fi.Mode()&os.ModeCharDevice == 0 表示非字符设备(管道/文件/容器)→ JSON,语义正确 |
LOG_FORMAT 覆盖逻辑 | ✅ 使用 strings.TrimSpace + strings.EqualFold,大小写/空白容错;仅 json 开启 JSON,其它值(含 console)回退非 JSON |
原 CustomFormatter 行为 | ✅ else 分支完整保留,本地体验不变 |
| 日志时区 | ✅ JSON 时间戳采用 RFC3339Nano,携带偏移量;time.Local = CST 在前,时区语义保持 |
结论:变更逻辑正确、边界处理稳健,未发现 Bug。
依据 codescan.issues_diff(base a5b0c71a → head 280ccd40):
同时针对 internal/logging/logger.go 单独查询质量地图:0 条问题,该文件干净。
全仓共 107 条历史质量问题,均为复杂度/重复代码/耦合度等既有存量项,与本次变更文件无关,故不在增量范围内展开。
文档缺口(Low):README「环境变量」表已列 LOG_LEVEL,但新增的 LOG_FORMAT 未登记。建议补充一行:
| LOG_FORMAT | 日志格式(json/console),缺省按 TTY 自动判定 | 自动 |
以免运维不知晓该开关。
行为边界提示(信息性):自动判定基于 stdout 是否为 TTY。本地开发若重定向/管道输出(如 go run ./cmd/dispatcher | tee app.log),会得到 JSON 而非彩色日志;如需彩色可显式设置 LOG_FORMAT=console。此为设计预期行为,仅作提示。
可测试性(可选):useJSONLogs 依赖进程级 os.Stdout/环境变量,未提供单测。若后续希望覆盖,可将其改为接收 io.Writer/env getter 参数以便注入测试,非必须。
本次为低风险的功能性小改动,聚焦日志可观测性提升:
唯一建议为补充 LOG_FORMAT 的 README 文档说明。