4. 日志级别详解(DEBUG、INFO、WARN、ERROR)

日志级别这东西,刚接触 Cromwell 的同事往往会忽略。说实话,我曾经也觉得“能打日志就行”,管它什么级别。结果有一次排查一个诡异的重启问题,日志文件刷了十几万行,全是一条 INFO 级别的“Task started”反复出现,真正关键的 WARN 和 ERROR 被淹没了。嗯,从那以后,我再也不敢小看日志级别了。

Cromwell 的日志体系沿用了标准日志分级,一共四种级别:DEBUG、INFO、WARN、ERROR。它们像四个筛子,从最细的 DEBUG 到最严重的 ERROR,你设置的级别决定了能看到什么层次的日志。我个人习惯在开发测试环境用 DEBUG,在生产环境用 INFO 或 WARN,等出了异常再临时切到 DEBUG 查细节。

为什么要搞明白这四个级别?

你想想看,Cromwell 调度几百个 workflow,每个 workflow 下又有几十个 task。如果全开 DEBUG,输出文件几分钟就能上 GB。别说分析,光是打开编辑器都卡半天。反过来,如果只开 ERROR,一些早期征兆(比如资源占用偏高、磁盘 IO 抖动)就会被错过。所以,选对日志级别,就是平衡信息量和可读性。说白了,这是工程师的基本功。

DEBUG

DEBUG 级别包含了所有细节:每个方法的调用、每个变量的中间值、每步 MySQL 查询、每个 REST 请求的全文。我觉得它是“手术刀”——只在需要解剖问题时才用。

举个例子,排查 workflow 提交失败时,我会先看 ERROR,找到失败点,然后临时把日志级别降到 DEBUG,重现一次。这样能捕获提交请求的完整 payload 和返回值。

# cromwell.conf 配置示例
akka.loggers = ["akka.event.slf4j.Slf4jLogger"]
logging {
  level = "DEBUG"   # 谨慎使用
}

注意:我在项目中遇到过,DEBUG 会打印敏感信息(如 token、密码),生产环境千万不能开,否则合规风险很大。

INFO

INFO 是日常的“晴雨表”。它告诉你流程正常推进了哪些步骤:workflow 开始、task 提交、job 完成、重试次数等。我个人习惯在监控看板里消费 INFO 日志,它能反映系统健康度。

# 典型 INFO 日志片段
2025-04-10 14:23:01 INFO  WorkflowManager - Workflow 1234 starting
2025-04-10 14:23:05 INFO  JobExecution - Job 5678 completed successfully
2025-04-10 14:23:10 INFO  WorkflowManager - Workflow 1234 finished (status: Succeeded)

避坑:我曾经天真地以为 INFO 日志很少,但 Cromwell 的 INFO 量其实不小,尤其是并行度高的场景。建议结合日志轮转,保留最近 7 天就够。

WARN

WARN 是我的“预警灯”。它表示出了点小问题,但系统还能自己消化,比如 job 重试了一次、某个依赖服务返回了 503 但重试成功、磁盘空间低于阈值但还没爆。如果 WARN 频繁出现,你就要警觉了。

我记得有一次,集群频繁报 WARN:

2025-04-10 15:01:12 WARN  JobExecution - Job 6790 failed, retrying (attempt 1/3)
2025-04-10 15:01:15 WARN  JobExecution - Job 6790 failed, retrying (attempt 2/3)
2025-04-10 15:01:18 WARN  JobExecution - Job 6790 failed, retrying (attempt 3/3)
2025-04-10 15:01:21 ERROR JobExecution - Job 6790 failed permanently

注意,WARN 连续出现后一定会转成 ERROR。我当时排查才发现是某个 worker 节点的内存泄漏导致每次 job 运行到一半就被 OOM 杀掉。如果早一点关注 WARN 趋势,可能就避免了一串失败。

ERROR

ERROR 是“火灾报警器”。它表示系统已经无法自动恢复,需要人工介入。最常见的类型:backend 连接失败、workflow 内部错误、数据库连接池耗尽、资源分配异常等。我甚至会把 ERROR 日志接入 PagerDuty,一旦出现立刻推送。

# 典型 ERROR 日志
2025-04-10 16:00:01 ERROR ServiceRegistry - Cannot connect to backend "Local" after 3 retries
2025-04-10 16:00:02 ERROR WorkflowManager - Workflow 2000 failed unrecoverably
java.lang.OutOfMemoryError: Java heap space
    at ...

嗯,这里有个很重要的点:不要只看 ERROR 日志本身,要把关联的 WARN 和 INFO 也拉出来看上下文。我见过有人只盯着 ERROR 行,忽略了几分钟前的 WARN 预警,结果花了大半天才复现根因。

级别对比速查表

级别含义是否影响系统运行典型场景建议使用环境
DEBUG调试信息,最详细否问题复现、开发排查开发/测试
INFO正常流程跟踪否日常监控、流程审计开发/测试 / 生产(谨慎)
WARN潜在异常,系统可自愈否(但预示风险)重试、降级、资源告警生产(重点关注)
ERROR严重故障,需人工介入是连接失败、OOM、workflow 崩溃生产(必须告警)

日志过滤和级别的实际关系

你设置日志级别后,Cromwell 会输出该级别及更严重级别的日志。例如设置 level = "WARN",则只会看到 WARN 和 ERROR,不输出 INFO 和 DEBUG。这个规则很多人忽略。

小技巧:我个人习惯在启动 Cromwell 时通过环境变量覆盖日志级别,比如排查问题时不改配置文件,直接加 JVM 参数 -Dlogging.level=DEBUG,用完就恢复。

注意:Cromwell 默认日志级别是 INFO,但不同模块(如 akka、dbms)可能有独立级别。如果你改了全局级别却发现某些日志没出来,先检查子模块配置。

日志级别过滤流向 DEBUG 输出所有日志 INFO 输出 INFO + 更严重 WARN 输出 WARN + ERROR ERROR 仅输出 ERROR 实际配置示例 1. 设置 logging.level = "INFO" → 看到 INFO + WARN + ERROR 2. 设置 logging.level = "WARN" → 只看到 WARN + ERROR

总结一句话:DEBUG 是显微镜,INFO 是日常巡检,WARN 是预警雷达,ERROR 是灭火器。搞懂它们,你的 Cromwell 日志分析节奏就握在手里了。