日志传习录(下篇)· 日志级别

📂 365bet足球比分直播 ⏳ 2025-08-15 13:19:48 👽 admin 👁️ 6073 💾 876
日志传习录(下篇)· 日志级别

前言

写日志是一项具有挑战性的任务,在工作中我们常常面临一些困境,比如:

开发人员在编写代码时常常陷入纠结,不确定在何处打印日志才是最有意义的;

SRE人员在调查生产问题时可能因为缺乏必要的日志信息而束手无策;

运维人员在面对处理海量日志时往往需要耗费大量的精力进行维护;

项目管理者面对大量的无实际业务价值的日志,往往不愿投入过多人力和财力进行管理。

这些问题导致了许多矛盾的产生。然而,当问题出现时,我们需要依赖日志记录来建立一种**“不在场证明”,**找出哪一方有问题。

正是由于这种需求,我们在开发应用程序时需要遵循良好的实践,选择成熟的日志收集机制和管理方案,从而缓解这些矛盾。

矛盾的起因

首先,我们探讨为何需要记录日志以及日志的作用。

实际上,对于大多数开发人员来说,在调试代码问题、解决不同环境的 Bug 时,日志的价值是显而易见的。作为调试的得力助手和生产环境中不可或缺的救星。

通过查询日志,我们能够确定代码的执行过程、API请求的正确性、核心业务数据的准确性,以及是否存在错误的堆栈信息等等操作,这些条件也构成了开发和运维人员判断代码和生产问题的首要手段。在一个复杂庞大的系统中,如果没有记录任何日志,那么在排查生产环境中的 Bug 时将变得极为困难。

若每一行代码都记录上下文,是否就能解决所有问题呢?

理论上确实是可行的,但目前仍存在一些无法解决的问题。

首先是日志存储量的问题,典型的中大型系统日志可能达到TB级,而超大型系统的日志规模甚至可能达到PB级。

这对于存储而言是一个巨大的挑战。其次是搜索性能的下降,常见的日志存储方案如Elasticsearch数据库在面对海量日志时,可能导致维护的映射关系急剧增长,即使划分不同的索引、分布式管理不同的ElasticSearch集群,也难以做到搜索性能不随数据量增加而下降。最后,海量日志的生成可能在峰值时拖慢系统性能,增加出现故障的风险。

因此,日志既不能记录过多导致存储和管理困难,也不能因记录过少而导致运维人员无法排查问题。尽管听起来似乎自相矛盾,但这正是关于日志重要所在!在日志记录中,我们需要在**“太多”和“太少”**之间找到平衡点,以确保既能有效排查问题同时又能够高效管理和存储日志。

日志级别

在决定记录日志之前,通常需要考虑选择适当的日志级别。在讨论如何确定日志级别之前,我们先来了解一下日志级别的作用。

确定日志信息的优先级: 通过设定不同的日志级别,我们可以对日志信息进行优先级排序,从而有效减少信息噪音和警报疲劳。不同的日志级别对应不同的信息重要性,开发人员可以根据当前需求选择适当的级别,确保在解决问题或分析系统行为时能够集中关注最重要的信息。

在查询日志时进行过滤: 添加日志级别的过滤可以在查询日志时更加精准地获取所需的信息。例如,在调试阶段可能需要详细的调试信息,而在生产环境中可能只关心警告和错误级别的日志。通过合理使用日志级别,可以提高日志的可读性和查询效率,同时降低处理冗余信息的成本。

因此,选择适当的日志级别是一项关键决策,它能够在不同场景中平衡信息的详细程度,帮助开发人员和运维人员更好地理解和管理系统的行为。

常见的日志级别有以下几类,并且从高到低的顺序是:致命(FATAL)、错误(ERROR)、警告(WARN)、信息(INFO)、调试(DEBUG)、痕迹(TRACE)和全部(ALL)

致命

错误

警告

信息

调试

痕迹

全部

致命

X

错误

X

X

警告

X

X

X

信息

X

X

X

X

调试

X

X

X

X

X

痕迹

X

X

X

X

X

X

全部

X

X

X

X

X

X

X

**FATAL:**严重错误级别,表示系统无法继续运行。

**ERROR:**错误级别,用于记录错误信息。

**WARN:**警告级别,表示潜在的问题,但不影响程序的运行。

**INFO:**信息级别,用于记录程序的正常运行信息。

**DEBUG:**调试级别,用于详细记录调试信息。

**TRACE:**追踪级别,提供比DEBUG更详细的信息。

**ALL:**最低级别,用于启用所有日志记录。

常见场景

场景

某工程师在调查生产环境中某个创建资源的 API 性能问题时,发现该 API 接口中打印了INFO 级别的日志,导致业务峰期时出现海量日志,耗尽 Buffer 区内存,拖慢主线程,影响服务性能。

后续功能优化中工程师删除了写业务INFO级别日志的操作以解决性能问题。

然而,由于某天修改了 API 服务调用链路上的某服务代码,导致 API 创建出的对象存在错误。但是在生产环境中缺少了该资源的日志,工程师无法准确排查问题。在这种情况下,工程师可能需要重新修改日志级别,将业务日志重新启用,并重新构建发布上线,

场景

假设将生产环境的日志设置为 ERROR 级别。某一时刻,依赖的下游服务故障,导致请求大量超时。由于业务峰期 QPS 非常高,短时间内集中产生大量错误日志,导致磁盘 IO ****急剧提高,消耗大量 CPU,导致整个服务瘫痪。

场景

某工程师在排查生产问题时,发现 INFO 级别的日志无法满足排查根本原因。他需要 DEBUG 级别的日志,但生产环境只配置为 INFO 级别。

日志级别规范与动态调整

日志级别的规范和动态调整有助于在开发、调试和生产环境中更有效地管理日志信息。

日志级别规范

**TRACE:**在开发期间可以使用,但确保不要将它们提交到版本控制系统中,以避免不必要的日志信息混入生产环境。

**DEBUG:**在进入生产阶段之前,对调试语句进行审查和缩减,只保留最关键、最有意义的调试信息。

**INFO:**记录用户驱动的事件或系统的特定操作。这可以包括定期计划的任务、用户登录等。保持信息简洁明了,避免过多的冗余信息。

**WARN:**记录可能成为错误的事件。例如,耗时较长的操作、接近容量的内存缓存等。允许设置自动警报,以及在故障排除期间更好地了解系统在故障之前的行为。

**ERROR:**记录每个错误条件,包括 API 调用返回的错误或内部错误条件。

**FATAL:**只用于表示整个服务已经无法工作的情况。通常,FATAL 级别记录表示程序的结束。

动态调整日志级别

配置文件动态调整

使用配置文件(如 logback.xml 或 log4j2.xml)来配置日志级别。这样,可以在不重新启动应用程序的情况下调整日志级别。

logback.xml

%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n

log4j2.xml

logback-spring.xml

%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n

logback-spring.xml 可以通过配置,定时地检测配置修改,但是这会带来额外的资源消耗。

使用外部配置中心,例如 Spring Cloud Config,可以通过远程配置动态更改日志级别。

在这里,${LOG_LEVEL:-INFO} 使用了Spring表达式,它会从Spring Cloud Config中获取名为LOG_LEVEL的配置,如果未配置则默认为INFO级别。

JMX(Java Management Extensions)

使用 JMX 允许在运行时修改日志级别。

通过 JConsole,VisualVM 或其他 JMX 工具,可以直接管理日志框架的运行时配置。

在 application.properties 或 application.yml 中启用 JMX:

spring.jmx.enabled=true

远程管理工具

使用远程管理工具,例如 Spring Boot Actuator,可以通过 HTTP 端点或其他远程管理手段动态调整日志级别。

Spring Boot Actuator 为Spring Boot应用程序提供了丰富的监控和管理功能。通过使用HTTP Endpoint(端点)或JMX(Java Management Extensions)来监视和管理应用程序,从而更好地理解其运行状况并进行调整。

确保在pom.xml中添加了Spring Boot Actuator的依赖

org.springframework.boot

spring-boot-starter-actuator

配置application.yml文件

# 设置日志级别为INFO

logging:

level:

root: INFO

# 允许Actuator修改日志配置

management:

endpoints:

web:

exposure:

include: loggers

最后,使用curl命令查看和修改日志级别:

查看日志配置:

curl -X GET http://localhost:8080/actuator/loggers

你会看到根日志记录器的级别是INFO。

修改日志级别:

curl -X POST http://localhost:8080/actuator/loggers/com.example -H 'Content-Type: application/json' -d '{"configuredLevel": "DEBUG"}'

这会将com.example包下的日志级别设置为DEBUG。

条件日志

在关键代码路径中使用条件日志,根据配置的条件来决定是否记录日志。这样可以更灵活地控制日志输出。

在 application.properties 或 application.yml 中添加一个属性,表示是否启用条件日志:

myapp.logging.enabled=true

创建一个类来进行条件日志,使用 @ConditionalOnProperty 注解来根据配置的条件来判断是否创建这个类的 Bean。这个类可以用于条件日志记录。

@Configuration

@ConditionalOnProperty(name = "myapp.logging.enabled", havingValue = "true")

public class ConditionalLoggerConfig

集成监控系统

将日志级别调整集成到监控系统中,例如 Prometheus、Grafana 等,以便在需要时能够通过监控界面进行动态调整。

总结

综合利用这些方法,可以在不同的环境和阶段更好地管理日志级别,既保持足够的信息用于排查问题,又避免在生产环境中过度记录冗余信息。

参考链接:

Spring Boot Actuator 官方文档:docs.spring.io/spring-boot…

Spring Boot Actuator GitHub 仓库:github.com/spring-proj…

相关数据包

告别卡顿,轻松掌握:Android应用进程关闭全攻略

告别卡顿,轻松掌握:Android应用进程关闭全攻略

📅 07-14 🔗 365bet足球比分直播
三胎最新消息河南,河南三胎罚款多少

三胎最新消息河南,河南三胎罚款多少

📅 07-29 🔗 365bet足球比分直播
揭秘传说中的彼岸花为什么在冥界入口,死人花的由来!
LOL黑桃皇牌伊泽瑞尔值得入手吗(各皮肤价格、特效与稀有度)
← iPhone 定时关机设置教程,透过 iOS 捷径在指定时间让 iPhone 自动关机或重开机 王者荣耀正常帧数是多少 帧数低怎么办 →