作者:kobe
部门:质量保障
没有仪表盘的车,那是自行车,只要会骑,人人都能骑······ 有仪表盘的车,没有故障灯,会开车的人可以开但也有坏的时候······ 有仪表盘的车,如果全是ERROR告警,估计也没人敢开,因为不知道会发生什么······
客户反馈系统又不好使了,客满找到了技术,技术才知道系统又崩了···
技术开始排查,发现全是ERROR日志,大海捞针,排查难,定位难,故障持续时间长,恢复慢
事后复盘,灵魂拷问:有报ERROR吗?有;有告警嘛?有;那为啥没有第一时间发现呢?日志太多了,告警太多了,被淹没了,关注不到···
以上这些是问题嘛?是,客观存在,是我们一年前面临的问题,怎么办?想办法解决呗··· 面对线上问题,故障频发,发现手段滞后,只能依赖商家客户的反馈,进而导致客服成本高,压力大,针对这种情况,首先明确一个问题,线上问题会被彻底消灭嘛?答案是:不会,那既然不会我们还能做什么呢?第一时间发现,快速修复---要做到这些,监控告警是非常有效的第一时间发现故障的手段,我们期望达到的目标是每一次告警都是有效的,为了这个目标我们做了两个专题:一个是ERROR日志治理的专项工作;另外一个是提升系统业务水位监控告警的敏感度和精确度;这两个专题相辅相成,其中重点介绍一些系统ERROR日志的治理经验总结,这项治理给我们带来的收益是很明显的。
怎么实现呢?先看看问题:
- ERROR级别的日志太多---不精准,不全面,不清晰;
- 告警太多,关注不到---不精准,不具体,范围不够广;
我们先说说ERROR日志的问题,打印日志简单,打印好日志-----难!!!
写日志主要是为了下面的需求:
- 记录用户操作的行为日志。
- 方便快速定位问题,
- 追踪程序执行的过程
- 追踪数据的变化
- 数据统计和性能分析
- 采集运行环境数据
我们遇到一个问题,什么时候打印ERROR,什么时候打印Waring,Info就不说了?
- info 用于打印程序应该出现的正常状态信息,便于追踪定位;
- warn 表明系统出现不合理但不影响运行和使用;
- error表明系统出现了错误,无法完成目标操作,必须人工介入分析处理; 以上是官方的解释,但是具体怎么判断呢,一句话"如果告警出来,你是否需要介入处理,如果是就打ERROR,如果不是就打Waring,不要担心写的ERROR多了,报警出来的就会多,很多时候系统运行正常的情况下是不会有ERROR日志产生的,如果你的ERROR日志处理足够细致准确的情况下"。
确定标准,我们要根据各自系统的情况,确定目标:将每天的error日志降到多少条,100,200···有个目标就行。
具体怎么做的?每天关注生产环境的ERROR日志,进行归类分析并及时解决,持续做好直到达成目标。
- 可以利用运维平台统计应用每天ERROR日志的量,找出Top10并针对性的解决;
- 看一下应用每天磁盘IO的量,来判断日志的读写是否影响磁盘的性能;
问题总结:
- 在ERROR 日志梳理的过程中我们会发现很多线上的bug,需要对ERROR进行深入分析;
- 一些问题可能在代码上线之初是不存在的,但是在数据量达到一定量级的时候就会触发,例如典型mysql 超时的问题,索引失效的问题;
- 对于上下游系统的一些超时配置是否合理进行验证;
- 对代码进行优化调整,在排查问题的过程中发现因为历史积累的原因,有些代码逻辑已经不用了,或者逻辑顺序需要调整,对性能提升很有帮助;
- 接口的梳理和优化,对于同一个功能的接口可能会因为历史原因有好几个,这个时候可以统一替换成最高效的那个,某些情况下也可以进行拆分;
- 对于依赖上下游解决的问题能够进行一个数据统计,通过拿到的数据去push上下游进行改造优化;
- 对于一些TSP的任务,已经失效的可以进行清理;
- 堆栈信息缺失,导致定位问题困难或者无从定位;
期待达到的状态:
如果只是针对ERROR日志进行处理的话,我们能达到的状态是持续的投入解决问题,来降低ERROR日志的数量,另外一个角度要将已经出现的问题进行总结,定期和组内研发/测试同学分享,避免问题重复出现,从根本上减少问题的发生,形成一个良性的循环状态。 最终达到目标:每一次告警,都是有效问题需要介入处理,缩短故障的影响时间和影响面,规范的日志内容提高了排查的效率;
带来的其他价值:
- 做好系统稳定性的一个很好的切入点;
- 帮助我们了解系统在线上的一个状态,存在的问题,还能通过定位问题,了解相关的系统;
- 通过对ERROR日志的治理,减少不必要的告警,提升告警的敏感度;
- 提升测试在开发团队的影响力;
- 推动告警配置的完善;
- 遇到的问题类型:
- 逻辑需要优化、告警级别需要调整、依赖方的问题、环境问题、历史脏数据问题、上下游发布导致、接口超时、索引问题、mysql问题、tsp定时任务问题
取得的成果
近一年绝大部分线上问题都是监控告警首先感知,监控告警的敏感度有了极大的提升,在线上问题升级故障前就发现,有效减少了线上故障。 生产ERROR日志的产生类型也极大的减少,从原来每天上百种类型到目前的个位数,数量从之前的最高峰值上万到现在的平均每天100条左右;
“有这么一句话,错误日志应该做到,即使离开了代码情境,也能清晰的描述发生了什么。” 这就对了日志提出了如下的要求:
- 日志的可读性;
- 日志的性能;
- 占用的磁盘空间;
- 日志的时效性;
- 日志的级别;
- 日志的内容(打印错误日志内容的基本原则:完整、具体、直接、格式规范、多用关键字)
还有一些情况要介绍一下
我们通常知道对ERROR日志进行告警的配置,配置在单位时间内Waring达到一定数量进行告警,但是存在这样一种情况,在业务上是正常的报错(例如参数校验未通过,可能是使用姿势的问题),这个时候没有打ERROR打的是Waring,但是正常情况下这个Waring会一直处于低水位状态,如果某一天水位出现大幅上升也代表存在问题,这个时候要配置对应的水位告警,具体的水位条件需要根据各个业务的具体情况和发展进行分析和动态的调优。
除了日志级别的监控外,在一些数据统计上也可进行监控,例如我们对出金系统每天的出金数据进行统计并通知出来,每天成功,失败,异常等状态的数据会是一个比较稳定的状态,某一天如果数据出现明显的变化,就代表系统很有可能存在问题,这是另外一个维度的监控。
在与开发同学协作的过程中遇到的问题
- 同一个问题不喜欢提多个jira(需要我们将同类型的问题进行聚合,需要测试同学有定位问题的能力)
- 开发同学对jira比较敏感,习惯于第一时间处理(非紧急类型的问题可以找时间统一处理,不必第一时间处理)
- 对于下游依赖问题,认为推动解决比较困难,并且认为这不是一个问题,认为不应该处理(这一类型的问题需要记录下来,由测试同学Owner起来用数据说话推动上下游合作方进行解决,最好给出自己的解决方案)
- 对于已经习惯了的问题知道原因和影响范围不大,自动放过,不处理,缺少深入分析(有问题就一定要处理,如果不是大的问题就要打ERROR级别的日志会干扰我们监控告警的敏感度)
- 认为处理这些jira会占用开发同学的时间(首先要达成共识,这是一件长期有价值的事情,是在质量保障和长期投入成本投入的角度来讲,是划算的)