使用改进后的Drain3进行中英文日志解析

简介

转载于:使用改进后的Drain3进行中英文日志解析

首先介绍了Drain及Drain3的背景;然后从原理上和算法实现方案的角度,介绍了Drain3是如何进行日志解析的。针对Drain3在解析纯中文或中英文混杂日志时出现的问题,提出了改进方案,并且对中英文混杂日志的解析效果进行举例说明。最后附上了GitHub源码链接:https://link.zhihu.com/?target=https%3A//github.com/dongdong9/log_parser。

Drain及Drain3背景介绍

Drain是2017年《Drain: An Online Log Parsing Approach with Fixed Depth Tree》中提出的日志解析方法,源码是Python2版本的。

Drain3将Drain进行了改造,使其可以在Python3下使用,并适用于实际生产环境,其GitHub链接为:GitHub - logpai/Drain3: Drain log template miner in Python3

Drain3日志解析的原理

Drain3的核心思想与Drain一致,都是基于一个假设:同一个日志模板产生的日志经过分词得到的词的个数是相同的。在词假设前提下,建立一个由日志长度、前缀单词和日志模板组成的Parse Tree。

2.1 Parse Tree的结构

其结构如下图所示:

在Parse Tree第一层是root node;第二层是分词后词的个数,也就是日志的长度Length;第三层及以下是日志模板中的前缀单词;最底层的Log Groups是一批具有相同前缀单词的日志模板。上图中Depth=3,只能保存一层前缀单词,即Send、Receive、Starting等。只有一层前缀单词,可能不方便理解,下图展示了Depth=4的Parse Tree,有两层前缀单词,具体如下:

上图中展示了Depth=4的Parse Tree,长度Length=3的日志模板分别有”Send block \ “ 和” Receive * bytes “ ,且它们的前缀单词分别为“Send block ““ Receive * “,故Send和Receive在Parse Tree的第三层,block和在第四层。

2.2 Parse Tree的构建与更新

2.2.1 对输入的日志进行预处理:子串替换

事先配置一些正则表达式,用于匹配IP、数字、邮箱等,然后将匹配的字符串用特定符号替代。例如将“connected to 192.168.0.1”替换为”connected to * “。

2.2.2 更新Parse Tree

  1. 对前一步得到的日志内容进行分词,得到token_list,有Length=len(token_list)。
  2. 判断当前Length是否在Parse Tree中,如果存在,则将token_list更新到前缀单词组成的字典中;如果不存在,则需要将当前Length和token_list都加入到Parse Tree中。

上图展示了Depth=4的Parse Tree是如何更新的。左边是由第一条日志“Send block 44”构建的Parse Tree,当来了一条新日志“Receive 120 bytes”时,将数字”120”替换为”“,分词后的token_list为[“Receive”, ““, “bytes”],由于Depth=4,Root和Length:3已经分别占据了前两层,故token_list中只有前两个词”Receive”和”“能加入到Parse Tree中。在Parse Tree中,以”Receive”和”“为前缀词的Log Event为”Receive 120 bytes”,对应的Log IDs为[2]。

2.3 从Parse Tree中获取最匹配的日志模板

如图1所示,在Parse Tree中,每个叶子节点下可能关联着多个Log Group。当来了一条新日志时,需要从这多个Log Group中选择一个最合适的作为模板。假设新日志经过分词后的序列为seq1,某个Log Group中Log Event经过分词后的序列为seq2,可以计算seq1与seq2的相似度simSeq,计算公式如下所示:

上式中,n表示seq1中单词的个数,因为seq1与seq2单词个数相同,可以比较相同索引处的单词t1与t2是否相同,如果相同,则equ(t1,t2)取值为1,否则取值为0。

从多个simSeq中选择值最大的,如果该最大值不小于阈值sim_th,则将其对应的Log Group当作是与新日志最匹配日志模板。

2.4 Drain3实现日志模板解析的流程

上面从各个角度介绍了Drain3,其实现日志模板解析的流程如下所示:

上图中使用了方法self.tree_search()来获取匹配的日志模板,这个方法内部的流程如下图所示:

三、Drain3存在的问题及改进方案

3.1 Drain3存在的问题

经测试,Drain3能很好的处理不包含中文的日志,但是对纯中文或中英文混杂的日志,解析效果不好。原因在于中文词语之间没有空格分隔,导致不能很好的构建Parse Tree。

3.2 改进方案

对Drain3中的分词方法进行改进,使其兼容纯中文或中英文混杂的情况。具体方案如下:

解析效果举例说明:

四、代码链接

整体方案代码链接为:https://github.com/dongdong9/log_parser, 可以从输入的日志中学习到日志模板,构建Parse Tree。并且通过Parse Tree可以对实时输入的日志进行解析,得到日志中的参数。

一分一毛,也是心意。