java日志规约

日志规约

      • 日志目标
      • 日志规约
      • 日志内容
      • java日志打印最佳实践(SLF4J为例)
      • 日志级别
      • 一些其他建议

日志目标

  1. 了解系统运行状态:标识程序运行中的危险操作、错误操作,进而便于在出现问题时排查问题
  2. 发现潜在性能问题:通过日志提供的详细执行时间记录来定位在开发阶段难以发现的性能瓶颈
  3. 实时监控预警:针对关键性异常、bug等错误进行实时跟踪和预警,避免问题扩大
  4. 价值数据分析:记录对于后续业务或系统分析有价值的数据,例如埋点数据等

日志规约

【强制】不打无用的、无意义、不完全的日志。

【强制】日志打印的时候不能因为打印日志引入新的异常,例如打印一个可能为null的对象的属性。
【强制】使用门面模式的日志框架来打印日志,有利于维护和各个类的日志处理方式统一。
		例如在Java中应使用slf4j来记录日志而非直接使用log4j
		
【强制】使用参数化信息的方式打印日志,避免使用字符串拼接形式,
		这样将会产生很多的非必要的字符串对象,影响性能。
		
【强制】应用中的扩展日志(如打点、临时监控、访问日志等)命名方式:appName_logType_logName.log。
		logType:日志类型,推荐分类有 stats/desc/monitor/visit 等;
		logName:日志描述;这种命名的好处是通过文件名就可知 道日志文件属于什么应用,什么类型,什么目的,也有利于归类查找。
		
【强制】日志文件推荐至少保存 15 天,因为有些异常具备以“周”为频次发生的特点。

【强制】避免重复打印日志,浪费磁盘空间,禁止在一个递归程序或未知循环次数的循环体中打印日志
		以造成磁盘空间占满风险增加。
		
【强制】异常信息应该包括两类信息:案发现场信息和异常堆栈信息,如果不处理,那么通过关键字 throws 往上抛出。

【强制】生产环境只开启info级别以上的日志。

日志内容

  • 重要的启动配置
  • 对持久化数据的更改
  • 系统主要组件间的请求和响应
  • 非常重要的状态转换
  • 重要的逻辑分支判断
  • 系统性异常、崩溃信息

java日志打印最佳实践(SLF4J为例)

  • 日志打印需依赖使用日志框架SLF4J 中的 API,使用门面模式的日志框架,且在一个对象中通常只使用一个Logger对象,Logger应该是static final
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

private static final Logger LOGGER = LoggerFactory.getLogger(ClassName.class);

  • 不打印重复的日志,避免重复打印日志,浪费磁盘空间,务必在logback.xml中设置 additivity = false
<logger name="com.spring.cloud.dao" level="DEBUG" additivity="false"></logger>
  • 合理使用日志级别,对不同日志进行分文件、分级输出,便于后续日志的统一管理、清理,并增强问题排查的效率。
    Java的日志框架一般会提供以下日志级别,缺省打开info级别,也就是debug,trace级别的日志在生产环境不会输出,在开发和测试环境可以通过不同的日志配置文件打开debug级别。
fatal - 严重的,造成服务中断的错误;
error - 其他错误运行期错误,在各方法的catch块中使用;
warn - 警告信息,如程序调用了一个即将作废的接口,接口的不当使用,运行状态不是期望的但仍可继续处理等;
info - 有意义的事件信息,如程序启动,关闭事件,收到请求事件等;
debug - 调试信息,可记录详细的业务处理到哪一步了,以及当前的变量状态;
trace - 更详细的跟踪信息。

  • 使用参数化信息的方式:不要进行字符串拼接,那样会产生很多String对象,占用空间,影响性能。
LOGGER.debug("Processing trade with id: [{}], symbol: [{}]", id, symbol);

日志级别

优先级由高到低:OFF>FATAL>ERROR>WARN>INFO>DEBUG>ALL

引用文章:https://www.cnblogs.com/zyybb/p/10535735.html


ALL:最低等级的,用于打开所有日志记录。

TRACE: 很低的日志级别,一般不会使用。

DEBUG: 指出细粒度信息事件对调试应用程序是非常有帮助的,主要用于开发过程中打印一些运行信息。

INFO:  消息在粗粒度级别上突出强调应用程序的运行过程。
		打印一些你感兴趣的或者重要的信息,这个可以用于生产环境中输出程序运行的一些重要信息,
		但是不能滥用,避免打印过多的日志。

WARN: 表明会出现潜在错误的情形,有些信息不是错误信息,但是也要给程序员的一些提示。

ERROR: 指出虽然发生错误事件,但仍然不影响系统的继续运行。
		打印错误和异常信息,如果不想输出太多的日志,可以使用这个级别。

FATAL: 指出每个严重的错误事件将会导致应用程序的退出。
		这个级别比较高了。重大错误,这种级别你可以直接停止程序了。

OFF: 最高等级的,用于关闭所有日志记录。

如果将log level设置在某一个级别上,那么比此级别优先级高的log都能打印出来。
	例如,如果设置优先级为WARN,那么OFF、FATAL、ERROR、WARN 4个级别的log能正常输出,
	而INFO、DEBUG、TRACE、 ALL级别的log则会被忽略。
	Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。

从我们实验的结果可以看出,log4j默认的优先级为ERROR或者WARN(实际上是ERROR)。

一些其他建议

  1. 推荐利用Spring AOP切面配置打印每个方法的耗时,有利于后续代码的性能问题定位和优化;
  2. 业务日志内容应尽量使用业务语言进行表达而非用程序语言表达,这样做的好处是能够从日志反应业务流程,可读性高,即便不是这段代码的编写人也可以读懂;
  3. 涉及到资源类的使用,推荐关键性日志,比如说磁盘访问,比如数据库访问,比如请求网络服务器,这些都算是与小系统的交互,必须要将输入和输出写入日志。而且这些内容都会伴有异常,遇到异常更是要以error写入logger;
  4. 若业务涉及到跨系统或服务的交互,推荐在服务入口处(通常是消息总线或网关程序)生成请求链路ID(TraceID),后续在所有日志打印中通过框架自动把TraceID打印出来,有利于问题的快速排查和定位;
  5. 推荐日志打印格式为:时间(毫秒粒度)[日志级别] [机器名(IP)] [类名(全路径).方法名] [TraceID] [线程名] 日志内容
  6. 日志打印应设置通过日期和文件大小双重滚动,确保每个日志文件的大小可控,日志文件名中需要带入日期,便于后续日志的归档和清理;
  7. 日志文件合理分类,一般主要分为业务、性能、错误、埋点、其他等类型,将这些类型的日志分文件输出有助于日志归集、分析和管理。

你可能感兴趣的:(java,core,spring-mvc,java,异常)