1. 为什么需要日志异常检测?
通信网络中部署的大规模设备在运行过程中产生海量日志。如图 1 所示,日志是一种时序文本数据,由时间戳和文本消息组成,实时记录了业务的运行状态。通过收集并分析日志,可以发现或预知网络中已发生或潜在的故障。
图 1 windows 公开数据集中的部分日志样例[1]
目前日志规范不统一。如图 2 所示,不同类型的设备打印出的日志格式也不同,且日志数据呈现出非结构化的特点。主要体现在日志时间格式不统一,日志记录的级别不统一,不同厂家自定义的专业词汇或缩略语不统一。这些问题增加了日志分析的难度。
图 2 四种不同规范的日志样例数据[1]
此外,现代网络系统规模庞大,每小时打印日志约 50Gb(约 1.2 亿~ 2 亿行)的量级[2],若依靠人工分析日志数据来识别网络中是否发生了故障则效率低下,因此有必要引入 AI 算法进行日志异常检测,以达到降低运维成本,显著提升业务体验的目的。
自 2017 年 Min Du 等人提出 DeepLog 以来[3],基于序列的深度学习建模逐渐成为近年来研究的热点。原始的 DeepLog 主要包括两个部分:模板序列异常检测模型(Log key anomaly detection model)和参数值异常检测模型(Parameter value anomaly detection model)。模板序列异常检测模型通过学习正常日志打印对应的工作流,然后对测试数据进行推理,以检测出是否存在违背工作流的异常日志。参数值异常检测模型则是对每一个模板(Log key 或 Template)构建一个模型,用推理出的参数值与实际参数值作对比,对比结果在置信区间内则认为是正常,否则为异常。模板序列异常检测模型的缺点在于对模板使用 one-hot 向量编码,无法学习出不同模板之间的语义相似性。参数值异常检测模型的缺点在于建模的数量太多,有多少个模板就要建立多少个模型,实现起来工作量较大。针对上述问题,2019 年与 2020 年 Weibin Meng 等人先后提出 Template2Vec 和 Log2Vec 方法[4,5],可以学习出模板之间的语义相似性,并且能够解决新模板的在线学习问题。
2. 日志异常检测是如何实现的?
日志异常检测的核心是借助 AI 算法自动分析网络设备日志来发现并定位故障,根据送入检测模型的数据格式,日志异常检测算法模型分为序列模型和频率模型,其中序列模型又可以分为深度模型和聚类模型。本期主要分享近年来研究的热点:深度模型。
2.1 日志解析
非结构化的日志数据直接处理非常困难。通常的做法是通过日志解析得到日志的模板,然后再对模板进行异常检测。模板相当于日志的“摘要”,日志可以视作模板加参数得到。例如,模板 Send Bytes to ,加上参数 size=120, block=blk4612,使用打印函数 print()可以得到一条具体的日志 Send 120 Bytes to blk4612。改变参数值 size=256, block=blk3768,可以得到另一条日志 Send 256 Bytes to blk3768。日志解析相当于日志打印的逆过程,由日志反向处理得到模板。以 Pinjia He 等人提出的 Drain 方法为例[6],简单说明日志解析的过程。Drain 认为具有相同长度的(即模板中 token 个数)日志,其业务含义具有相似性,因此长度是模板提取的一个重要判据。此外,特定的关键字也代表了特定的业务含义。变量一般认为是纯数字或者数字与字母等其他符号的组合。日志解析如图 3 所示,首先将变量 token 转换为,然后根据长度区分类别,最后根据关键字区分类别,最终得到一个模板。例如 Receive from node blk_3587 经过处理后得到模板 Receive from node 。提取完模板内容后,会分配一个唯一的 ID。
图 3 模板与日志的关系以及日志解析原理图
2.2 异常检测
2.2.1 DeepLog 模型
以 DeepLog 的 Log key anomaly detection model 为例,网络结构如图 3 所示,其中 LSTM 原理可以参看文献[3]。输入 为 one-hot 编码形式(备注:此处不用 one-hot 编码也是可以的,直接输入从 0 开始编码的模板 ID 即可),h 为窗口长度,即 x 为 t 时刻之前的 h 个模板组成的序列。 表示第 t 个时刻出现的模板,假设模板 ID 的集合为{0,1, …,M},则 ,DeepLog 采用两层 LSTM,之后接全连接网络(FC),经过 softmax 函数处理后,输出各个模板的概率分布 ,其中_n_为模板的个数。
图 4 DeepLog 网络结构图
在训练态,收集设备正常运行时产生的日志获取训练集,具体步骤如下:
Step1: 取设备正常运行时打印的日志,通过日志解析得到模板序列;
Step2: 按 task_id(或线程号、任务号)提取模板序列;
Step4: 使用训练数据和梯度下降法等算法训练神经网络。
从上述收集训练数据的过程中可以发现,整个过程只要求训练数据来自于系统正常运行或故障占比很小的日志。数据标签不需要人工标注,因此该模型可以认为是一个无监督的深度学习模型。
图 5 训练态收集训练数据
图 6 推理态示意图
推理态步骤如下:
Step1: 取待检测的推理日志,通过日志解析得到模板序列;
Step2: 按 task_id(或线程号、任务号)提取模板序列;
Step3: 加载训练后的模型,对各个 task_id 对应的序列滑动窗口依次检测;
DeepLog 输入数据的编码方式为 one-hot,所以无法学习出两个模板之间的语义相似度,例如,假如模板数据库的表中共有 3 个模板,如表 1 所示。从模板 ID 或者 one-hot 编码无法学习出 1 号模板与 2 号模板业务意义相反,也学不到 1 号模板与 3 号模板业务意义相近。因此,原始的 DeepLog 的学习能力是有局限性的。
表 1 模板的 one-hot 编码示例
2.2.2 Template2Vec 模型
为了学习出模板的业务含义或语义,Weibin Meng 等人在使用 DeepLog 之前,设计了一个 Template2Vec 向量编码。核心思想是参照 Word2Vec[7]的设计思路,提出了模板向量 Template2Vec。Template2Vec 将模板编码成语义向量,以代替原始 DeepLog 中的模板索引或 one-hot 编码。对于新出现的模板,则将其转换为一个最接近的已有模板。Template2Vec 原理如图 7 所示:
图 7 Template2Vec 原理
具体步骤如下:
Step 1 : 在 WordNet[8]中对模板内容中的自然语言单词进行同义词和反义词搜索(如图 7 中的 down 和 up),之后,运维人员再对具有业务知识的词汇识别同义词和反义词(如图中的 Interface 和 Vlan-Interface),并将其转化为正常的自然语言词汇。
Step 2: 应用 dLCE [9]生成模板中单词的词向量,如图 7 中的 Word vectors。
Step 3: 模板向量是模板中单词的词向量的加权平均值。如图中的 Templates vectors
Template2Vec 结合了运维人员的专业领域知识和自然语言处理中的 dLCE 模型,以便准确生成模板向量。例如对模板 Receiving blk src dest 的 Template2Vec 求解过程如下。
图 8 Template2Vec 计算过程示意图
借助 Template2Vec 将模板序列转换为语义向量序列,之后送入 DeepLog 即可进行日志异常检测。
2.2.3 Log2Vec 模型
Template2Vec 存在一个较大的问题:不能在运行态或推理态处理日志中词汇表外(OOV)的新词汇。为了解决这一问题,提出了 Log2Vec 方法。Log2Vec 主要包含两部分:日志专用的词嵌入(log-specific word embedding, LSWE)和新词处理器(OOV Word processor).
LSWE 可以看作在 Template2Vec 的基础上,加入了关系三元组,即增加了关联信息。具体做法是:(1) 对于通用的关系三元组采用 Dependence Trees[10]方法进行语义向量转化,(2) 对于业务领域范围内的三元组,加入专家经验来识别处理。
新词处理器则采用 MIMICK [11] 来处理运行中出现的 OOV 单词。使用方法如图 9 所示。首先,在已有的词汇数据集上训练出可用的 MIMICK 模型。然后,使用该模型在 OOV 单词上将其转换为一个唯一的向量。
图 9 新词处理器原理图
3. AIops 中的日志异常检测效果展示
NAIE 的 AIOps 中的日子异常检测模型服务,能够实时监控日志,识别并推荐根因异常。内置多种类型算法,无需定制即可支持不同网元日志的异常检测;具备在线学习能力,持续提升检测精度,辅助运维人员定位故障根因,提升运维效率。
例如,对某个网元的某个计算节点的日志监控过程中,如图 10 所示,实时统计出现的异常量,给出各个异常对应的关键日志。若算法报出的结果存在误报,如图 11 所示,用户可以加入业务反馈,反馈的误报异常点将会被在以后的检测中被过滤掉。由于日志包含了丰富的领域业务知识,如图 12 所示,每条关键日志都会给出上下文,辅助运维人员定位具体的异常内容。
图 10 异常检测与关键日志推荐
图 11 可以加入用户反馈
图 12 异常日志上下文
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/301883.html