当前位置: 首页 > 科技观察

本次日志智能分析设计一旦完成,大小故障无处遁形

时间:2023-03-18 21:10:44 科技观察

1.背景随着系统越来越复杂,产生的日志海量。当故障发生时,人工从大量错误日志中定位异常的成本非常高。主要原因是:日志格式较多,难以依靠人工划分,而传统的日志规则分类需要复杂的规则和规则的配置,难以一概而论;日志量级别大,告警多,很难定位需要关注的异常,一些无关的错误日志很容易掩盖真正的问题。日志智能分类算法可以根据日志的相似性自动对日志进行聚类,提取关键信息——日志模板,可以有效避免相似日志的无效查看,大大节省排查时间。而日志异常检测可以从海量日志中发现潜在的异常日志模式,帮助程序快速定位异常。二、日志智能分类1、设计方案初始日志分类服务在具体算法选择上选择Drain算法提取日志模板。随着业务经验的积累,为了提高日志分类的准确性,采用二层模型对日志进行流分类,生成日志模板。其中一次分类相当于预分类,然后将预分类结果进行二次分类,将预分类中未分类的日志进行融合,形成最终符合预期的分类结果。2.一次一个分类使用改进的前缀树。从根节点开始,第一层是长度层。相同长度的日志进入同一个节点,根据token判断下一个节点。只有匹配相同token的日志才会被划分到相应的路径中。此外,还将设置一个阈值。当叶子节点达到阈值时,将添加一个<*>节点来匹配所有匹配不成功的日志。由于树的深度是预先设置好的,一般设置的比较小,所以匹配速度会很快。整个树的生成和匹配过程其实就是在长度层上加了一个前缀树。算法流程如下:预处理,将log以分隔符/空格为单位划分为token;到第二层(每个节点对应一个长度)根据logtoken的长度找到对应的节点,比如Receivefromnode4match节点对应的logtoken的长度为4;按照logtoken的顺序拆分,这里受限于深度,拆分树的深度为depth-2(去掉root和length层);分裂到叶节点后,计算log与每个模板的相似度simSeq,返回simSeq大于阈值st且相似度最高的模板;updateParsetree,当log在叶子节点匹配到template,有的token不一样,用<*>替换;当没有匹配到模板时,替换为新日志作为新模板添加到叶节点的模板列表中。3.二级分类二级分类使用基于最长公共子序列匹配的算法。一个分类的第一层会有长度匹配,不同长度的日志不会归为一类;并且一个分类按照token的顺序一个一个匹配,相似度的计算也是顺序计算的。两者是很相似的log,如果只是中间的一些token划分不能对齐,就会导致无法归入同一类。为了克服上述问题,引入了基于最长公共子序列的匹配算法,对第一次分类得到的模板进行两次合并,得到聚类效果较好的模板。同时,由于最长公共子序列的时间复杂度较高,设计了前缀树和简单循环两种预匹配方法,减少了部分LCS的匹配,提高了算法的整体效率。算法流程如下:1)预处理,将日志以分隔符/空格为单位划分为token。2)前缀树是预匹配的,如果可以匹配,则返回匹配的类别和模板;如果未找到匹配项,则转到(3)。3)简单循环匹配,如果能找到匹配,则返回匹配的类别和模板;如果没有找到匹配项,则转到(4)。4)计算最长公共子序列,进行LCS匹配。如果可以匹配,则返回匹配的分类和模板,计算更新后的模板,用<*>替换差值;如果不匹配,则添加新的分类和模板。4、Traceback日志处理Traceback日志不同于普通日志。普通的错误日志用分隔符/空格来划分token比较合适,但是traceback错误日志有trace结构,更适合按行查看,所以traceback日志的每一行作为一个token,这样可以对trace相似的错误进行分组在一起,更容易发现问题。5.解决冷启动问题。日志智能分类算法会将日志和模板进行比较,保留相同部分(常量),将不同部分(变量)填充为<*>,更新模板,自然具备提取共同部分的能力日志。但是,如果直接将原始日志输入到算法中,需要很长时间才能完成模板的收敛;并且收敛的模板与输入顺序关系很大,无法得到稳健的结果。这样会导致新接入的项目无法很好的应用日志智能分类。但是,如果能够提前识别变量并提前填充<*>,则可以大大提高日志模板的收敛速度,也可以获得更健壮的日志模板。通过正则化,预先用<*>填充数字、base64编码、地址编码,大大提高了模板的收敛速度。过去需要一周时间才能稳定可用的模板,现在访问后立即可用。三、日志异常检测1、设计方案目前,业界对日志异常检测的研究较多。总结起来主要分为以下几类:我们的日志异常检测算法主要是基于统计+无监督日志模板异常检测算法,完全没有人工标注成本,计算简单,可解释性好。目前日志异常检测算法需要依赖于日志智能分类算法。获取实时日志分类模板后,需要根据各模板日志量的历史数据进行异常判断,从而发现异常模式,并向用户发送相应告警。.2、具体算法日志异常检测算法设计为1分钟粒度:1)根据机器维度获取机器的日志模板和对应日志量的历史数据。2)不同模板的日志量历史数据采用卡方分布进行聚合。3)对聚合数据进行异常检测。当发现异常时,(4)被触发。如果没有发现异常,则返回结果正常。4)对每个日志模板对应的日志量的历史数据进行异常检测,根据异常程度返回Top5异常模板。5)如果没有返回异常模板,则本次检测返回结果正常;如果返回异常模板,则本次检测返回结果异常,并对异常结果和异常模板进行告警。这里的异常检测分两步设计主要是因为:每台机器的日志生成的模板数量较多,日志量对应的历史数据也比较嘈杂。直接对模板进行异常检测,很可能会产生更多的无效告警;templates数量大,全量1min粒度的异常检测计算量大,可能1min内检测不完。因此,考虑从全局的角度设计一个噪声较小的指标,首先对该指标进行异常检测。当异常检测结果异常时,再下钻到具体的模板进行异常检测,找到异常模板,可以减少错误。它还可以降低CPU压力。设计平方和作为具有全局代表性的指标,采用卡方分布进行数据聚合。假设n个模板的频率特征符合标准正态分布,模板的特征平方和以此为基础构建。该特性满足卡方分布。当它较大时,卡方分布可以近似为正态分布,可以用3sigma方法进行异常检测。日志异常检测中使用的异常检测算法除了3sigma方法外,还使用了boxplot方法,将两者的结果转化为异常分数再进行融合。3、减少周期性误报周期性异常是指昨天或上周发生的相同异常,此类告警为周期性误报。这时,昨天或上周相应时间点的异常分数也会很高,可以利用这个历史分数来压制当前分数,达到消除周期性误报的效果。但是异常发生的时间点可能会有一定的偏移量,所以需要对昨天和上周某个时间窗口内的score进行一次centerrolling_max操作,然后用当前的异常score减去较大的score从昨天或上周开始。得到被压制的分数。4、新的日志类别告警在某些情况下,希望在出现新的日志模板类时,对新的日志类别进行告警。但是,当日志智能分类结果还不稳定时,经常会出现新的日志类别,可能会产生很多误报。我们设计了一种自适应的新日志类别警报。当一天内新增日志类别超过一定阈值时,抑制新增日志类别告警;当低于某个阈值时,发出新的日志类别告警。4.应用效果当日志异常检测检测到异常日志时,会通知用户异常模板。进入日志统计页面,可以看到当前时刻确实有异常的日志激增。