日志问题精要:分析与总结

记录应用系统日志主要有三个原因:记录操作轨迹、监控系统运行状况、回溯系统故障。 记录操作轨迹:可以数据化分析用户偏好,有助于优化系统业务逻辑,为用户提供个性化服务。如:通过access.log记录用户的操作频率和跳转链接,有助于分析用户后续行为。监控系统运行状况:全面有效的日志系统有助于建立完善的应用监控体系。通过应用监控体系,可以实时监控系统运行状况,及时预警,避免故障发送。系统运行状况是指服务器的运行状态,如内存、CPU等使用情况;应用运行状况,如接口RT(响应时间)、QPS等。应用错误信息,如NPE、SQL异常、数据转换失败等。回溯系统故障:完整的现场日志方便快速定位问题,并迅速处理

一、日志的记录点要求

在程序执行过程中,以下5类日志记录点必须记录日志:

本系统接受到外部请求时(本地入口);

本系统调用其他模块或系统时(调用其他);

本系统调用其他模块或系统结束时(调用结束);

本系统处理结束时(本地出口);

本系统捕捉到错误时(出错时);

初始化参数时

初始化参数在各种框架里面可以看到一些内容,而在自己开发的业务中则使用打印业务参数阅读相关内容 系统核心角色,组件关键动作 :主要是核心业务的触发动作,但是需要避免非常高频率的打印,同时对于日志进行提炼 上述日志记录点,除出错时,均应该按[INFO]级别登记

二、日志的记录内容规则

应用程序日志原则上使用UTF-8字符编码,以便于将来的日志文件分析。 不要使用系统输出记录日志,如System.out.print, printStackTrace。不能将应用日志写入生产环境基础系统的日志。(如SystemErr.log、SystemOut.log); 日志记录应及时、完整,日志应该符合安全规范,不要在日志信息里包含安全敏感信息,敏感信息主要有客户身份信息如客户账号、名称、证件号、交易核心信息如交易金额、交易备注、安全控制信息如安全认证方式、密码。

1.日志输出不允许影响系统正常运行。

2.日志输出需符合安全审计要求,不允许产生安全问题,不允许输出敏感信息,支持保密机制。

3.日志输出格式严格按照要求、合理的打印信息,如对于交易日志,必须记录,对于程序调试中非关键节点的日志交付前进行删除,无需记录

4.日志输出内容能够提供开发和运维人员快速定位到故障问题原因。

5.日志按照一定的策略支持备份,如日期、时间等。

6.最小10M,缺省情况下,每个日志文件的大小限制为100M,超过限制,则必须写入到另一个带新序号的日志文件中

7.一定要控制日志输出量,以免出现磁盘空间不足。同时要为日志设置合理的生命周期,及时清理过期日志。避免重复打印,务必在日志配置文件中设置additivity=false

三、日志的性能要求

1、输出日志记录不能过于频繁。一般情况下10毫秒内不能输出3条以上日志信息;

2、输出的日志内容不能过长。一般情况下每行日志信息原则上不能超过2K字节,一条日志输出代码产生的日志内容不能超过40行;

3、输出日志信息的函数代码不能包含复杂的CPU计算,导致产生过多的CPU。

4.不建议打印查询list,尤其没有分页的

5.控制日志输出的长度在一定范围内,比如请求参数,避免打印大量的业务日志 如日志layout中 msg配置为 %.-4096msg,输出日志长度最长为4096字节,多余的将从后面截断不打印;

6.【建议】在循环,响应式编程中谨慎log

7.【建议】批量任务,大量mq,不建议每行均打印

8.【建议】gateway等网关中log需谨慎, gateway默认线程数很少,等你打印io线程消耗性能,遇到上传文件+报文解密+打印日志的时候,并发能力下降到2位数

9.【建议】报文加/解密 前后打印log,没必要 和第三方交互时,入参、出参可能是需要加密和解密,如果报文体积较大,明文和密文都打印没有意义,算法测试成功后,个人认为加解密成功的情况下打印明文,计算失败时异常中打印原文即可

10.【建议】如果开源jar包日志需要特别注意 如shardingsphere-jdbc等,需要关闭日志 如无法关闭,可以设置独立的logger,和其他应用日志分开 mybatis,eureka心跳等日志建议分开打印,不要和业务日志混在一起 日志按用途划分,避免业务日志,框架日志,混合,业务日志也应分模块打印: www.jb51.net/article/247...

11.在tps有高要求的场景应该异步打印,参考:www.cnblogs.com/yangyongjie...

四、日志的等级分类

DEBUG 细粒度的、对出错(debug)、以及系统调试时候输出的信息、事件。

INFO 在正常运行状态中,粗粒度的、关于重要流程/事件的、可用来表示系统健康度的信息、事件。在INFO级别不允许把SQL语句、报文等这些作为日志内容输出。

WARN 有潜在风险的、不会造成大危害的错误(往往由应用外部因素造成,如不正确的输入数据)

ERROR 应用发生错误(包括业务错误和技术错误),但后续流程还能够继续进行 FATAL 应用发生严重错误(技术型异常),应用服务被终止。

五、日志的目录和文件名

1.应用日志输出至/app/logs目录下;

2.应用日志文件名以.log后缀结尾;

3.应用日志中每行以[LEVEL][yyyy-MM-dd HH:mm:ss,SSS]开头;

4.把不同类型的日志分离出去,应用中的扩展日志(如打点、临时监控、访问日志等)命名方式: appName_logType_logName.log。logType:日志类型,如 stats/monitor/access/error 等;logName:日志描述。这种命名的好处:通过文件名就可知道日志文件属于什么应用,什 么类型,什么目的,也有利于归类查找。说明:推荐对日志进行分类,如将错误日志和正常 日志分开存放,便于开发人员查看,也便于通过日志对系统进行及时监控。

六、日志的大小

日志文件的大小应该可以通过参数控制(log4j2 可配置),如果超过限制,则必须写入到另一个带新序号的日志文件中,且不能超过本次磁盘预警值: 参考:log4j2官网:Log4j -- Log4j 2 Appenders 下面是一个示例配置,它使用滚动文件追加器,其时间和大小都基于时间 触发策略,将在同一天创建最多 100 个存档 (1-100) 存储在目录中 根据当前年份和月份,并将压缩每个 使用 gzip 存档,每小时滚动一次。 在每次翻转期间,此配置将删除与" /app- .log.gz"匹配的文件 并且出生 30 天或以上, 但保留最近的 100 GB 或最近的 10 个文件,以先到者为准 logback:官网:Chapter 4: Appenders 译文:第四章:Appenders - logback 中的maxHistory处 其他注意点:www.cnblogs.com/ZTPX/p/1409...

七、日志的清理

一般情况下,日志文件按照磁盘预警值和监控组对接需求定时清理一次,移出日志目录; 对于有审计需求的日志,按照审计规定对这些文件进行归档,归档数据转入存储服务器。

八、日志打印注意事项

1.记录异常时一定要输出异常堆栈。如下:logger.error("xxx"+e.getMessage(), e)

2.日志中如果输出对象实例,要确保实例类重写了toString方法,否则只会输出对象的hashCode值。 注:logger应被定义为static,与类绑定,防止浪费资源。 使用slf4j+日志库模式时,要防止日志库冲突,一旦发生则可能会出现日志打印功能失效问题

3.不要在打印日志时造成异常

4.日志框架选型 logback、log4j2 logback:推荐,Springboot默认的日志框架 log4j2:版本大于2.15.0

5.日志格式 日志输出基本格式(有任何需求按规范添加): •pid[级别] [时间][应用名称][调用链标识][调用层级标识][业务标识] [线程名] [线程上线映射变量] [类名] [行号] [日志内容] [换行] 即:[%-5p] [%d{yyyy-MM-dd HH:mm:ss,SSS}] [%t] [%-1X{变量名}] [%C:%L] [%m] %n

6.日志级别得支持动态修改,要么actuator通过post接口动态修改日志级别,要么放到配置中心来修改

7.链路追踪 通过 AOP 切面,日志框架 MDC 等技术结合,在日志中打印traceId,而后根据traceId可检索整个请求链路的日志

1)AOP切面结合MDC方式 ①、日志配置文件中配置traceId占位符 Gherkin %date{yyyy-MM-dd HH:mm:ss.SSS}|%t|%-5level|%X{traceId}|%C{0}#%M:%L|%msg%n ②、AOP切入要增强traceId的方法 ③、在增强类中往MDC中添加traceId字段,并赋值,并在finally块移除MDC中traceId字段

2)直接使用MDC方式

①、日志配置文件中配置traceId占位符,同上

②、在方法执行业务逻辑前往MDC中添加traceId字段,并赋值

③、在方法返回前移除MDC中的traceId字段

3)在线程池中没采取阿里ttl方式做mdc前线程池必须手动使用mdc打印,防止链路追踪失败

  1. 不要记录异常又抛出 记录之后抛出异常是非常危险的操作,因为外层可能会因为内层捕获异常之后不会再次处理,如果是自定义异常更是难以排查问题,此外这样做法会导致堆栈二次打印,非常浪费系统性能,

  2. 核心功能模块日志 如果是核心功能模块的日志,其实多打印一些内容是可以接受的,但是需要注意打印的日志必须要第一时间可以定位到问题所在。 监控系统集成:建议将日志和监控系统打通,将日志信息传递给监控系统,以便实时监控系统的运行状态和性能指标。

  3. 理想的日志中应该记录不多不少的信息 l 不要在日志中记录无用的信息,实践中常见到的无用的日志有: 1)能够放在一条日志里的东西,放在多条日志中输出; 2)预期会发生且能够被正常处理的异常,打印出一堆无用的堆栈; 3)开发人员在开发过程中为了调试方便而加入的"临时"日志 l 对于日志的使用者,能够从日志中得到所有需要的信息

相关推荐
BillKu26 分钟前
Java + Spring Boot + Mybatis 插入数据后,获取自增 id 的方法
java·tomcat·mybatis
全栈凯哥27 分钟前
Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解
java·算法·leetcode·链表
chxii28 分钟前
12.7Swing控件6 JList
java
全栈凯哥29 分钟前
Java详解LeetCode 热题 100(27):LeetCode 21. 合并两个有序链表(Merge Two Sorted Lists)详解
java·算法·leetcode·链表
YuTaoShao30 分钟前
Java八股文——集合「List篇」
java·开发语言·list
PypYCCcccCc35 分钟前
支付系统架构图
java·网络·金融·系统架构
华科云商xiao徐1 小时前
Java HttpClient实现简单网络爬虫
java·爬虫
扎瓦1 小时前
ThreadLocal 线程变量
java·后端
BillKu1 小时前
Java后端检查空条件查询
java·开发语言
jackson凌2 小时前
【Java学习笔记】String类(重点)
java·笔记·学习