19

对智能化运维中日志聚类分析的一些思考(201227)

 3 years ago
source link: http://blog.sina.com.cn/s/blog_493a84550102zawh.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

日志聚类分析可以理解为AIOps智能化运维的一个子内容,对于日志本身也分为了操作系统日志,数据库和中间件日志,业务系统本身自定义错误日志等。

今天只分析对业务系统错误日志聚类分析。

日志聚类分析背景

我们实施ESB服务总线项目,因此拿ESB总线或SOA集成平台来举例。

在SOA集成平台实施过程中,由于注册和接入了大量的业务系统和接口服务,因此每天都产生大量的接口调用错误日志信息,峰值期间一天的错误日志量也达到好几万条。

那么面对这么多的错误日志,如何快速的定位究竟是中间件本身错误还是业务类异常,如果是业务类异常本身又主要是由哪些接口,哪些服务消费方引起的就成为一个关键内容。

比如我们对最近1个小时的错误日志快速聚类分析,可以发80%错误都来源于CRM系统调用预算系统接口服务的时候出现预算校验不通过引起的。

是否能够直接Group By?

对于错误日志信息,一般来讲很难直接Group by进行分类汇总,因为业务系统在产生错误日志的时候往往会依赖于错误日志模板,模板中参数变量信息,导致最终输出的日志并不同。

比如前面预算校验,实际模板可能是:

BIZ001:(Param1):预算校验不通过。申请(Param2),实际剩余(Param3)

因此实际上你无法简单的做汇总处理。

问题转化

经过基本分析,你会发现日志聚类本质还是文本相似度比较,基于文本串的相似度进行聚类。文本传的相似度可以两两比较,只要相似的即可聚类到一起。

比如下面的错误日志信息:

1.BIZ0465:要释放的单据信息不存在, 单据编号:54004541 单据类型:BZ_WHTBZ
2.BIZ0465:要释放的单据信息不存在, 单据编号:54027476 单据类型:BZ_YHTBZ
3.BIZ0465:要释放的单据信息不存在, 单据编号:54164614 单据类型:BZ_WHTBZ
4.BIZ0270:按照维度组合查找相关成本费用预算的可用资金(88909.83元) 小于 本次金额(280000元)
5.BIZ0270:按照维度组合查找相关成本费用预算的可用资金(897.92元) 小于 本次金额(8668元)
6.BIZ0270:按照维度组合查找相关成本费用预算的可用资金(9.27元) 小于 本次金额(18.3元)

经过肉眼观察,我们也很容易发现实际应该聚为两类错误信息。1-3是一类,4-6是一类。如果从上面的信息我们也很容易抽象出后端对应的错误日志模板。

//BIZ0465:要释放的单据信息不存在, 单据编号:@param1 单据类型:@param1
//BIZ0270:按照维度组合查找相关成本费用预算的可用资金(@param1) 小于 本次金额(@param2)

把以上思考清楚后,可以看到日志聚类不能简单的照搬当前已有的文本聚类方法,而是应该在当前文本相似度比较,分词技术上进行优化,给出最佳的一种日志聚类算法。

在这里还是从文本预处理,分词,相似度计算几个方面来进行总结。

文本预处理

对于文本预处理,经常谈到的是去除停用词,比如常见的,你,我,他,的,啊等词语,这些词出现频繁,实际上本身没有太大的作用。

我们可以构建一个停用词的词库,对出现的停用词进行预处理。

其次,当我们观察大量的日志输出后,可以看到文本预处理的另外一个重点是对标点符号的处理,对基于模板填写内容的识别。

标点符号处理

对于经常出现的冒号,逗号,等于号等都是日志里面最常见的。这些标点符号本身就应该是后续分词的分割点。比如:

单据编号:54004541 单据类型:BZ_WHTBZ

这个直接基于空格和标点符号分词,应该拆分为:

单据编号

54004541

单据类型

BZ_WHTBZ

模板参数内容分析

经过对日志分析,你会发现类似(),类似[]或【】等都是最容器在里面填写参数化内容的。对于这种情况我们完全可以进行识别。

当发现这些特殊标点符号后,可以考虑直接对里面的内容进行去除处理,即将日志中分析可能是参数化的差异内容去除掉。

比如前面谈到的:

BIZ0270:按照维度组合查找相关成本费用预算的可用资金(88909.83元) 小于 本次金额(280000元)
BIZ0270:按照维度组合查找相关成本费用预算的可用资金(897.92元) 小于 本次金额(8668元)
BIZ0270:按照维度组合查找相关成本费用预算的可用资金(9.27元) 小于 本次金额(18.3元)

服务业务处理不通过[158605363]
服务业务处理不通过[158605364]
服务业务处理不通过[158605365]

这个在去除掉括号内容后,本身就变成了完全相同的文本。

进行SQL Group By处理

在前面做完预处理后,实际完全可以先进行一次Group By操作,基于文本进行汇总,这个时候往往已经可以汇总出一下日志完全相同的异常日志。

比如我们可以取一个Top10数据,将这Top10的日志数据直接移出日志列表。后续的文本相似度分析完全没有必要再对这些数据进行分析。一个10万条的错误日志数据列表,经过上述处理后最终待分析剩余日志往往不会超过50%。

分词

对于分词,当前主要有两种算法,一种是基于已有的词典库,一种是基于统计的机器学习。

基于词典的分词算法分为以下几种:正向最大匹配法、逆向最大匹配法和双向匹配分词法等。基于词典的分词算法是应用最广泛、分词速度最快的。基于统计的机器学习算法法是HMM、CRF、SVM、深度学习等算法,比如stanford、Hanlp分词工具是基于CRF算法。

常见的分词器都是使用机器学习算法和词典相结合,一方面能够提高分词准确率,另一方面能够改善领域适应性。

日志内容的分词

在前面我给出了前提,即重点对业务系统定义的业务错误日志,系统日志分析。这些日志大部分都是基于参数化模板来产生。我们还是举前面的例子来说明:

在基于标点符号和空格进行分词拆分后,得到:

要释放的单据信息不存在
单据编号

这个信息实际上再进行分词拆分本身对于日志聚类分析并没有太大的意义。上面的这个提示本身就已经是一个整体,没有必要再进行拆分。

其次,对于业务系统的词典库本身也是一个细分的领域,如果用当前主流的词典库来对日志文本进行分词,往往并不会得到很好的结果。

即使要进行分词,最好的方法也是需要对大量日志进行机器学习训练,加上人工修正,最好得到一个适用于日志分析的分词库。

日志文本相似度分析

在进行完日志预处理后,我们对剩余的日志列表进行分词处理。在进行完分词后,得到一个完整的分词列表。

词频向量构建

对完整的日志列表进行分词后,可以看到最终形成的分词列表接近上万,那么显然不可能都用做词频向量的构建。因此在分词完成后,我们需要对分词的词频进行分析,仅仅对词频达到某一个基准值的才用于后续构建词频向量使用。

比如前面分词会得到:

单据编号 | 54004541 | 单据类型 | 54004541 |

但是实际基于词频分析,最终用于构建词频向量的仅仅只有 单据编号和单据类型。

在经过上面分析后,我们会得到一个完整的用于构建词频向量的集合,类似如下:

[预算,单据编号,单据类型,异常,不通过,BIZ0270,金额,.......]

注意这个词频向量是一个全集。

构建词频向量子集

在前面工作完成后,可以开始对日志数据进行遍历,基于发现的日志文本,我们可以构建一个词频向量的子集。

该日志文本也进行分词处理,这个时候处理后的分词如下:

[预算,订单编号,0001, 订单类型,X03675,金额, 22131]

基于和高频分词列表库进行对比,找到一个子集如下:

[预算,单据,订单编号,订单类型,金额]

接着对日志列表数据进行文本相似度对比分析,采用上面的词频列表来构建词频向量。

TF-IDF算法

TF-IDF(Term Frequency-inverse Document Frequency)是一种针对关键词的统计分析方法,用于评估一个词对一个文件集或者一个语料库的重要程度。一个词的重要程度跟它在文章中出现的次数成正比,跟它在语料库出现的次数成反比。这种计算方式能有效避免常用词对关键词的影响,提高了关键词与文章之间的相关性。

其中TF指的是某词在文章中出现的总次数,该指标通常会被归一化定义为TF=(某词在文档中出现的次数/文档的总词量),这样可以防止结果偏向过长的文档(同一个词语在长文档里通常会具有比短文档更高的词频)。

IDF逆向文档频率,包含某词语的文档越少,IDF值越大,说明该词语具有很强的区分能力,IDF=loge(语料库中文档总数/包含该词的文档数+1),+1的原因是避免分母为0。TFIDF=TFxIDF,TFIDF值越大表示该特征词对这个文本的重要性越大。

实际上对于日志文本的相似度分析,采用TF词频基本就已经满足需求,并没有必要再去计算IDF值。比如对于两条日志信息,经过计算后为:

日志文本1:[1,0,1,1,1]
日志文本2:[1,1,1,1,1]

在得到词向量后,我们直接进行余弦相似度比较即可。

余弦值越接近1,就表明夹角越接近0度,也就是两个向量越相似,这就叫"余弦相似性"。这个时候将余弦相似度大于某个百分比的日志文本归于一类。

基于余弦相似度进行聚类

当然,在计算完余弦相似度后可以基于常用的k-means聚类算法进行聚类分析。

K-means算法是非常经典的聚类算法。是一种简单实用的聚类算法,k均值算法(k-means),由Stuart Lloyd于1957年提出。该算法虽然无法保证一定能够得到最优聚类结果,但实践效果非常好。

其算法思路如下:

先选K个初始聚类点作为初始中心点,然后计算其他所有点到K个聚类点的距离做聚类,将点分到最近的聚类,聚完类后中心点发生变化了,于是更新中心点。然后再计算其他所有点到这K个中心点的距离重新聚类,中心点又会发生变化,如此迭代下去。

聚类精度

经过近5万条数据的聚类分析,K-Means的聚类精度基本可以达到80%以上,基本可以满足当前日志聚类分析的需求。

简单总结

基于前面分析可以看到整个日志聚类分析可以分为如下几个关键步骤:

 1.进行日志文本预处理
 2.进行分词
 3.词频统计,文本转向量
 4.计算余弦相似度
 5.基于聚类算法进行聚类

在聚类结果如果无法满足需求的情况下,还需要提供人工修正的功能,其中人工修正包括了高频词的定义,停用词定义,词权重的定义等。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK