← 文章 / 编程开发
openobserve 1小时前 · 2026-09-11 10:27:46 · 0 阅读

日志级别详解:DEBUG、INFO、WARN、ERROR(2026 完全指南)

Simran Kumari

现在试用 OpenObserve Cloud,获得更高效、性能更出色的可观测性。

免费开始使用 目录Log levels explained: DEBUG, INFO, WARN, and ERROR severity hierarchy

每个日志库都内置一组固定的级别:DEBUG、INFO、WARN、ERROR,通常还有 TRACE 和 FATAL。看着简单,但大多数团队直到遇到以下两种情况之一才会认真考虑日志级别:生产环境出事了,唯一能解释原因的日志被海量 INFO 噪音埋没;或者凌晨三点值班工程师被一条 ERROR 告警叫醒,结果发现那完全是预期行为。

这两个问题的根源相同:各团队没有一套统一的标准来定义每个级别到底该用在哪。本文会讲清楚每个级别的用途、严重度层次和过滤机制如何运作、这些概念在 Python、Java、Node.js 中如何对应,以及让日志级别真正有用而非徒增噪音的最佳实践。

什么是日志级别?

日志级别(也叫日志严重度)是附在每条日志上的标签,标明这条日志有多重要、多紧急。有了日志级别,就不用对所有消息一视同仁,而是可以:

  • 过滤输出内容,比如开发环境显示全部,生产环境只看 WARN 及以上
  • 路由差异化处理,比如 ERROR 级别直接推给告警系统,INFO 只写入存储
  • 检索按严重度查询,比如"查一下过去一小时结账服务的所有 ERROR"
  • 告警只对真正重要的信号告警,而不是被海量日志淹没

主流日志库——Python 的 logging、Java 的 Log4j2 和 SLF4J、Node.js 的 Winston 和 Pino、Go 的 log/slog,以及 Unix syslog 标准——都在实现同一个思路:一组有限的、有序的严重度等级,每条日志必须归入其中之一。

日志级别层次:从低到高

日志级别构成一个层级体系,这正是"按级别过滤日志"的核心机制。当你将最低级别设为 INFO 时,只会看到该级别及更严重的日志(WARN、ERROR、FATAL),而更低级别的(DEBUG、TRACE)则完全不会被写入或显示。

级别 严重程度 含义
TRACE 最低 极低粒度、逐步执行的细节信息。仅在深度调试时才会启用。
DEBUG 开发或排障时有用的诊断信息,正常运行时不需要。
INFO 正常 确认系统按预期运行;标准的"系统健康"审计记录。
WARN (WARNING) 偏高 出现了非预期情况,但系统已恢复或仍在正常运行;值得关注,但不紧急。
ERROR 某项操作失败,需要关注;结果不符合预期。
FATAL / CRITICAL 最高 应用程序或其关键部分无法继续运行。

DEBUG:适用场景与使用时机

DEBUG 回答的是你在开发或排障时才会关心的问题:这个变量的值是什么、代码走到了哪个分支、请求体在转换之前长什么样。

logging.debug("Cache lookup for key=%s: %s", cache_key, "hit" if found else "miss")

DEBUG 日志对正常生产流量来说几乎总是过于冗长细碎,同时也是意外数据泄露的常见来源。开发者往往会在 DEBUG 级别把整个对象、请求体或查询参数都打出来,理由是"反正生产环境看不到"。不要抱有这种假设:只要级别没有关闭,DEBUG 日志依然会被写入、采集和存储,因此敏感数据的处理规范同样适用于 DEBUG。

INFO:适用场景与使用时机

INFO 是大多数生产系统的默认运行级别,用来记录应用正常运行中的各类事件,形成一份审计记录:服务启动、请求完成、定时任务跑完、配置加载等。

logging.info("Order %s placed successfully for customer %s", order_id, customer_id)

判断一条日志该不该用 INFO,有个简单的标准:事情发生了,而且不需要任何人因此采取行动,那就是 INFO。一旦可能需要人工介入处理,就该归入 WARN 或更高级别。

WARN(WARNING):用途与使用场景

WARN 介于“一切正常”和“出问题了”之间,覆盖那些异常但尚未构成故障的情况:请求重试后最终成功、调用了已废弃的 API、走了降级逻辑、磁盘用量超过软阈值等。

logging.warning("Payment gateway timed out, retrying (attempt %d/3)", attempt)

WARN 是团队最容易用偏的级别,而且两个方向都会出错:要么用得太少,真正有价值的早期预警信号 never 冒不出来;要么把常规情况也往里塞,导致它沦为没人看的背景噪音——这和没有 WARN 级别在效果上没什么区别。

ERROR:用途与使用场景

ERROR 表示操作确实失败了:未捕获的异常、没提交成功的数据库写入、上游 API 返回了无法使用的结果、应用无法为调用方完成的请求等。

logging.error("Failed to charge customer %s: %s", customer_id, str(exc))

告警和值班通知通常都建立在 ERROR 之上,所以这是最需要保持“诚实”的级别。如果把本属预期之内、已有处理逻辑的情况也记成 ERROR(比如普通的校验失败、资源确实不存在),值班工程师就会对 ERROR 告警失去信任,真正的故障也会被当成噪音一起忽略掉。

四大级别之外:TRACE 和 FATAL/CRITICAL

除了 DEBUG、INFO、WARN、ERROR 之外,大多数日志库还定义了两个级别:

  • TRACE 比 DEBUG 更细粒度,通常用于在特定函数或库内部逐行追踪执行流程。大多数团队只在针对某个难以复现的具体问题做定点调试时才会开启它。
  • FATAL(或 CRITICAL,取决于所用库)位于 ERROR 之上:仅用于严重到应用或其关键子系统无法继续运行的故障,例如启动时无法获取必需资源,或内部状态已损坏、继续运行存在安全风险。

Unix syslog 标准(RFC 5424)采用了一套更细粒度的八级量表,早于大多数应用日志库:Emergency、Alert、Critical、Error、Warning、Notice、Informational 和 Debug。即使在底层应用已改用更简洁的五级或六级量表时,基础设施和网络工具仍习惯使用这套术语。

各语言和框架中日志级别的差异

日志级别的概念是通用的,但具体名称、默认值甚至编号因生态系统而异,这在多语言开发环境中确实容易造成混淆。

概念 Python logging Log4j2 / SLF4J(Java) Winston(Node.js) Syslog(RFC 5424)
最严重 CRITICAL (50) FATAL* error (0) Emergency (0)、Alert (1)、Critical (2)
故障 ERROR (40) ERROR error (0) Error (3)
可恢复 / 异常 WARNING (30) WARN warn (1) Warning (4)
正常运行 INFO (20) INFO info (2) Notice (5)、Informational (6)
诊断详情 DEBUG (10) DEBUG debug (5) Debug (7)
最细粒度 NOTSET(罕见) TRACE silly (6) 未定义

*Log4j2 为向后兼容保留了 FATAL,但其官方文档建议大多数应用级故障使用 ERROR

最容易让人踩坑的细节:Winston 的默认级别编号方向与 Python 和 Log4j 恰好相反。在 Winston 中,error0debug5,数字越小表示越严重。而在 Python 的 logging 模块和 Log4j 中规则相反:数字越大越严重。把这两种心智模型搞混,是跨 Python/Java 后端和 Node.js 服务协作时日志级别阈值配错的常见原因。

日志级别最佳实践

  • 按环境设置不同级别。本地开发用 DEBUG 或 TRACE,预发布和生产环境默认用 INFO 或 WARN。不要所有环境套用同一阈值。
  • 让级别支持动态配置。最需要看 DEBUG 输出的时候往往是故障处理期间,而仅仅为了改个日志级别就重新部署,会浪费最关键的几分钟。现代日志库和平台大多支持运行时调整级别。
  • 无论什么级别,都不要记录敏感数据。DEBUG 不是绕过数据管理规范的理由。密码、令牌、完整支付信息和个人数据在任何级别下都不应出现在日志中。
  • 使用结构化日志,让级别成为一个可查询的字段而非纯文本前缀。一个支持过滤的 level 字段(如 level="ERROR")远比从纯文本行中解析 [ERROR] 高效得多。
  • ERROR 只留给真正的故障。可预期的、已妥善处理的状况(正常的 404、带有明确用户提示的校验失败)不算 ERROR,把它留给真正需要介入的问题。
  • 跨服务保持级别定义一致。在微服务架构中,一个共享的日志封装或库能避免五个团队各自定义不同版本的 WARN 标准。
  • 告警基于 ERROR 和持续性的 WARN 激增,而非 INFO 或 DEBUG 的量。如果值班告警系统和监控仪表盘基于同一信号触发,要么漏报,要么被噪音淹没。
  • 对高流量的 DEBUG 和 TRACE 日志采用采样或限流,而不是完全关闭。正常运行时按 1/100 的比例采样 DEBUG 输出,就足以发现规律,还省下了全部采集和存储的成本。
  • 每个级别的日志都要带上足够的上下文信息,才能派上用场。在 WARN 或 ERROR 日志里附上 request ID、trace ID 或 tenant ID,你就不用为了理解问题而专门复现它。
  • 常见的日志级别使用误区

    • 所有日志都记成 INFO,因为没人花时间想清楚什么内容该归哪一级。这样日志级别就完全失去了意义。
    • 把可预期的、已正常处理的情况记成 ERROR,久而久之,值班工程师就会对 ERROR 告警习以为常、选择性忽略。
    • 在生产环境长期开着 DEBUG,既悄悄推高基础设施成本,也增加了敏感数据被写进日志的风险。
    • 各服务之间的日志级别标准不一致,同类事件在一个服务里是 WARN,在另一个服务里却是 ERROR,跨服务的日志关联就不可靠了。
    • 改日志级别必须重新部署,意味着最实用的排障工具,恰恰在你最需要它的时候用不上。

    在 OpenObserve 中按日志级别查询和告警

    如果日志平台不能快速、低成本地按级别过滤和告警,前面讲的这些就都没什么意义。在 OpenObserve 里,日志级别只是一个普通的结构化字段,按严重程度过滤就是一条普通查询,而不是对原始文本做正则匹配:

    SELECT * FROM app_logs WHERE level = 'ERROR' ORDER BY _timestamp DESC LIMIT 100
    

    在此基础上,上面的最佳实践可以直接落到平台功能上:针对 ERROR 比例或 WARN 持续飙升设置告警,而不是盯着原始日志量;用日志搜索与过滤直达你关心的严重级别;依托基于对象存储的保留策略,把 DEBUG 级别的细节低成本留存下来,以备那些(少有的)确实需要回头查看的时刻。

    结语

    日志级别只是一项很小的配置,但它对事故排查时日志是否真正有用,影响却大得多。把 DEBUG、INFO、WARN、ERROR 用对,关键不在于背定义,而在于整个团队就一个问题达成共识:这条日志需要有人关注吗?紧急程度如何?把这一点统一起来,再让日志级别阈值可以不重新部署就调整,整套日志体系的可信度就会显著提升。

    延伸阅读: 结构化日志最佳实践微服务可观测性:日志、指标与链路追踪避免告警疲劳最佳日志分析工具,以及 将 Log4j2 集成到 OpenObserve

    常见问题

    标准日志级别按严重程度排序是怎样的?

    从低到高依次为:TRACE、DEBUG、INFO、WARN(WARNING)、ERROR、FATAL(或 CRITICAL)。大多数应用日常主要使用 DEBUG、INFO、WARN 和 ERROR 四级;TRACE 和 FATAL 虽在多数日志库中都有,但实际使用频率较低。

    WARN 和 ERROR 有什么区别?

    WARN 表示发生了意外但系统已恢复或仍在正常运行,例如请求被重试、走了降级路径。ERROR 表示某个操作确实失败了,例如抛出了未捕获的异常、请求无法完成。判断标准很简单:不需要任何人做任何事,就是 WARN;确实出了问题,就是 ERROR。

    生产环境应该用什么日志级别?

    INFO 是生产环境最常见的默认级别,既能记录正常运维事件,又不会像 DEBUG 或 TRACE 那样产生大量日志、拉高成本。很多团队默认跑在 WARN,排查具体问题时再临时、动态地开启 INFO 或 DEBUG。

    一直开着 DEBUG 日志会不会拖慢应用或增加成本?

    是的,在大多数系统中确实如此。DEBUG 和 TRACE 日志的量通常远大于 INFO 及以上级别,这会显著增加应用的 CPU 和 I/O 开销,同时推高日志平台的采集与存储成本。因此,大多数团队只在开发、预发布环境或事故排查期间临时开启 DEBUG。

    FATAL 和 CRITICAL 有什么区别?

    含义完全相同:指严重程度足以导致应用(或其关键部分)无法继续运行的错误。不同日志库只是用了不同的名字——Python 的 logging 模块称之为 CRITICAL,而 Log4j 及许多其他库称之为 FATAL。

    Python、Java、Node.js 的日志级别如何对应?

    概念是一致的(一端是严重故障,另一端是细粒度诊断信息),但具体名称和编号有差异。Python 的 logging 模块使用 DEBUG(10)、INFO(20)、WARNING(30)、ERROR(40)、CRITICAL(50);Log4j2 和 SLF4J 使用 TRACE、DEBUG、INFO、WARN、ERROR,以及遗留的 FATAL;Node.js 的 Winston 则采用 npm 风格编号,数字越小严重度越高(error 为 0,debug 为 5),与 Python 和 Java 的编号方向正好相反。

    关于作者

    Simran Kumari

    Simran Kumari

    热衷于可观测性、AI 系统和云原生工具,全身心投入 DevOps 与开发者体验的改进。

    在 Google 上关注 OpenObserve

    将 OpenObserve 设为首选信息源,以便在 Google 搜索和"热门话题"中看到更多我们的文章。

    最新博客

    上一篇 下一篇 查看全部文章How to Send uberAgent Data to OpenObserve with Nginx and njs 实操指南 集成 日志 可观测性

    如何用 Nginx 和 njs 将 uberAgent 数据发送到 OpenObserve

    一套可用的 uberAgent 数据接入 OpenObserve 方案,涵盖让 uberAgent 的 Elasticsearch 数据流批量格式正确落地的 Nginx njs 垫片、代理配置、验证方法、时间戳映射及故障排查。

    Chaitanya SistlaChaitanya Sistla2026-09-10
    在 Windows 上使用 OpenTelemetry Collector 监控 VMware vSphere How To OpenTelemetry Monitoring Integrations

    在 Windows 上使用 OpenTelemetry Collector 监控 VMware vSphere

    一份在 Windows 上使用 OpenTelemetry Collector Contrib 发行版监控 VMware vSphere 的完整指南:涵盖 vCenter 配置、完整的 collector 配置、作为服务运行、ESXi syslog、指标参考、验证方法,以及导致 Metrics explorer 空白的 stream-name 坑点。

    Chaitanya SistlaChaitanya Sistla2026-09-10
    日志级别详解:DEBUG、INFO、WARN、ERROR 及最佳实践 How To Logging Observability Monitoring

    日志级别详解:DEBUG、INFO、WARN、ERROR 及最佳实践

    一份日志级别完整指南:DEBUG、INFO、WARN、ERROR、TRACE 和 FATAL 到底各代表什么,日志级别的层级与过滤机制如何运作,以及在不同环境中如何选择合适级别的最佳实践。

    Simran KumariSimran Kumari2026-09-08
    2026 年最佳遥测代理对比:OpenTelemetry、Fluent Bit 等 Engineering OpenTelemetry Logging Monitoring

    2026 年最佳遥测代理对比:OpenTelemetry、Fluent Bit 等

    从性能、资源占用和 OTel 兼容性等维度,对比 2026 年用于收集日志、指标和链路追踪的最佳遥测采集代理。

    Simran KumariSimran Kumari2026-08-31
    Datadog 合成监控定价:按次收费的陷阱 工程 监控 对比 可观测性

    Datadog 合成监控定价:按次收费的陷阱

    Datadog 合成监控按 API 测试和浏览器测试的每次运行收费。算上检查频率、多地域部署和 Journey 数量之后,实际开销到底多少?本文附上具体计算,并介绍一种固定价格、按用量计费的替代方案长什么样。

    Simran KumariSimran Kumari2026-08-31
    Uno.ai 如何用 OpenObserve 实现三大云统一可观测性,从第一天就降低成本

    Uno.ai 如何用 OpenObserve 实现三大云统一可观测性,从第一天就降低成本

    一个可观测性客户案例:Uno.ai 是面向 GRC 和企业风险的 AI 原生 agentic 平台,通过 OpenObserve 统一管理 GCP、AWS 和 Azure 上的遥测数据,同时遏制不断攀升的云原生监控成本。

    2026-08-31
    错误预算详解:何时该停止发布功能 工程 SRE 告警 监控

    错误预算详解:何时该停止发布功能

    错误预算详解:工作原理、如何编写错误预算策略,以及预算耗尽时实际会发生什么。

    Simran KumariSimran Kumari2026-08-24
    OpenObserve vs ClickHouse:十亿条日志记录 工程 OpenObserve ClickHouse 基准测试

    OpenObserve vs ClickHouse:十亿条日志记录

    我们生成了 10 亿条日志记录(共 2 TiB NDJSON),将完全相同的字节同时写入 ClickHouse 和两个 OpenObserve 实例,各占一个独立节点。两侧均建了全文索引,跑完 19 条查询后,OpenObserve 快了 3.4~4.6 倍,磁盘用量却只有对方的三分之二。仅调一项 compaction 参数,带来的收益就超过了换文件格式。

    Hengfei YangHuaijin HaoHengfei Yang, Huaijin Hao2026-08-22
    把可靠性变成数字:SLO 与 Burn-Rate 告警正式发布 公告 SRE 告警 可观测性

    把可靠性变成数字:SLO 与 Burn-Rate 告警正式发布

    OpenObserve 可靠性版本发布:原生 SLO 支持(含 error budget 与多窗口 burn-rate 告警)、按主机或指标序列独立分组的告警、以及双向 Terraform / GitOps 支持,让告警、仪表盘和 SLO 都能以代码形式管理。

    Simran KumariJake SwissSimran Kumari, Jake Swiss2026-08-19
    OpenObserve 对比 Prometheus & Mimir:指标基准测试 工程 OpenObserve Prometheus Mimir

    OpenObserve 对比 Prometheus & Mimir:指标基准测试

    我们将约 22 亿个样本通过同一个 OTel Collector 同时推入 Prometheus、Grafana Mimir 和 OpenObserve(Parquet 与 Vortex 两种存储),再对一份冻结的 109 万序列数据集执行相同的 PromQL 查询。OpenObserve 回答 irate 查询快了约 15 倍,百万序列直方图查询快了约 6 倍,写入阶段内存占用仅为 Prometheus 的一半。

    Hengfei YangHengfei Yang2026-08-16
    原始来源: openobserve

    评论 (0)