2017—DeepLog:通过深度学习对系统日志进行异常检测和诊断
摘要
利用长短时记忆(LSTM)的DeepLog神经网络模型,将系统日志建模为自然语言序列。允许DeepLog自动从正常执行中学习日志模式,并在日志模式偏离正常执行时根据日志数据训练的模型检测异常。此外,演示了如何以在线方式增量更新DeepLog模型,使其能够随着时间的推移适应新的日志。此外,DeepLog从底层系统日志构建工作流,以便一旦检测到异常,用户可以诊断检测到的异常并有效地执行根因分析。
1.介绍
1.1 现有日志异常检测方法
- 基于
Log信息计数的PCA聚类 - 通过获取不同的
Log keys之间的共同的模式信息 - 基于工作流的方法以识别程序逻辑流程中的执行异常
 
1.2 难点(存在问题)
- 日志是非结构化的,在海量数据中进行在线异常检测具有挑战性
 - 异常检测必须及时有效,同时还要具有普适性
 - Log信息是并发性的,由多线程或者并发产生的,所以导致没法用一个工作流去解决问题。
 
1.3 本文贡献
使用到的工具
递归神经网络(RNN):使用一个回路将上次状态的输出转发到当前输入,从而跟踪历史进行预测。
长短时记忆(LSTM):
RNN的一个实例,它能够记住序列上的长期相关性。贡献
DeepLog从对应于正常系统执行路径的训练数据中隐式地捕获日志条目之间潜在的非线性和高维依赖关系。
DeepLog将并发任务或线程产生的日志条目分成不同的序列,这样就可以为每个单独的任务构建一个工作流模型。
2.Approach(论文方法)
2.1 Log parser(日志解析器)
首先提出把半结构化编码成结构化,看下面的example
日志键=日志模板
日志条目:e=”Take 10 seconds to build instance”
日志键:k=”Take * seconds to build instance”
再来就是*号的参数值,这些度量值反映了底层系统状态和性能状态。某些参数的值可能会作为一个特定执行序列的标识符,例如HDFS日志中的block_id, OpenStack日志中的instance_id。
DeepLog将每个日志条目 $e$ 的参数值,以及 $e$ 与其前一个条目之间的时间间隔存储到一个向量 $\overrightarrow v _e$ 中。
这个模型主要用到的三个信息,key,parameters以及上一个Log到此时Log的时间差。
2.2 DeepLog体系结构和概述
训练阶段:DeepLog的训练数据是来自正常系统执行路径的日志条目。每个日志条目的解析为日志键和参数值向量。DeepLog使用从训练日志文件中解析出的日志键序列来训练日志键异常检测模型,并构建用于诊断的系统执行工作流量模型。对于每个不同的键 $k$,DeepLog还训练和维护一个模型,用于检测由这些度量值所反映的系统性能异常,并由参数值矢量序列 $k$ 训练。
检测阶段:一个新到达的日志条目被解析成一个日志键和一个参数值向量。 DeepLog首先使用日志键异常检测模型来检查传入的日志键是否正常。如果是,DeepLog 使用该日志键的参数值异常检测模型进一步检查参数值向量。如果预测其日志键或其参数值向量异常,则新条目将被标记为异常。最后,如果它被标记为异常,DeepLog 的工作流模型为用户提供语义信息以诊断异常。执行模式可能会随着时间而改变,或者未包含在原始训练数据中。 DeepLog 还提供了收集用户反馈的选项。如果用户将检测到的异常报告为误报,DeepLog 可以将其用作标记记录,以增量更新其模型以合并并适应新模式。
三个部分
log key异常检测模型
workflow诊断部分
parameter value异常检测模型

3.异常检测
3.1 执行路径异常
设 $K={k_1,k_2,…,k_n}$ 是日志生成系统源代码中不同日志键的集合。 $m_i$ 表示日志键序列中位于 $i$ 个位置的键的值。显然 $m_i$ 可能从 $K$ 中获取 $n$ 个可能的键之一,并且强烈依赖于 $m_i$ 之前出现最近的键。
将日志键序列中的异常检测建模为一个多分类问题,其中每个不同的日志键定义一个类。输入是最近的日志键的历史记录,输出是来自 $K$ 的 $n$ 个日志键的概率分布,表示序列中下一个日志键是键 $k_i \in K$ 的概率。
图2总结了分类设置。假设 $t$ 是将要出现的下一个日志键的序列id。 用于分类的输入是一个窗口w的h最近日志键。 也就是说,$w={m_{t-h},…,m_{t-2},m_{t-1}}$,每个 $m_i$ 都在 $k$ 中,是日志条目 $e_i$ 的日志键。注意,相同的日志键值可能会在 $w$ 中出现几次。 训练阶段的输出是一个条件概率分布的模型,对于每个 $k_i \in K(i=1,…,n),P_r[m_t=k_i|w]$ 。检测阶段使用此模型进行预测,并将预测的输出与实际出现的观察到的日志键值进行比较。
训练阶段。对于训练数据中每个长度为 $h$ 的日志序列,DeepLog更新其模型,以 $k_i \in K$ 作为下一个日志键的概率分布。例如,假设一个正常执行的小日志文件被解析为一个日志键序列: ${k_{22}, k_5, k_{11}, k_9, k_{11}, k_{26}}$。给定窗口大小 $h=3$,用来训练DeepLog的输入序列和输出标签对将是: ${k_{22}, k_5, k_{11} \rightarrow k_9}, {k_5, k_{11}, k_9 \rightarrow k_{11}}, {k_{11}, k_9, k_{11} \rightarrow k_{26}}$。
检测阶段。为了测试传入的日志键 $m_t$ (从传入的日志条目 $e_t$ 解析)是正常还是异常,我们发送 $w={m_{t-h},…,m_{t-1}}$ 到DeepLog作为它的输入。输出是一个概率分布 $P_r[m_t|w]={k_1:p_1, k_2:p_2,…, k_n:p_n}$ 描述来自 $K$ 的每个日志键作为给定历史的下一个日志键出现的概率。
3.1.1 传统N-gram语言模型
从固定词汇表中提取的单词序列分配概率的问题是语言建模的经典问题。在本文中,每个日志键都可以看作是 k 词汇表中的一个单词。为任意长的序列分配概率的典型语言建模方法是 N-gram 模型。人们的直觉是,一个特定的词在一个序列中只受其最近的前辈的影响,而不是整个历史。在我们的设定中,这个近似等于设定$P_r(m_t=k|m_1,…,m_{t-1})=P_r(m_t=k_i|m_{t-N},…,m_{t-1})$,其中 N 表示要考虑的最近历史的长度。
对于训练,我们可以使用来自大型语料库的相对频率计数来计算这个概率,从而给出最大似然估计。给定一长串键${m_1,m_2,…,m_t}$,我们可以利用${m_{t-N},…,m_{t-1},m_t=k_i}$相对于${m_{t-N,…,m_{t-1}}}$的相对频率计数来估算观测第 i 个键 $k_i$ 的概率。换句话说,$P_r(m_t=k_i|m_1,…m_{t-1})=count(m_{t-N},…m_{t-1},m_t=k_i)/count(m_{t-N},…,m_{t-1})$. 注意到我们将使用一个大小为 N 的滑动窗口在整个键序列上计算这些频率。
使用 N 作为历史窗口的大小,实验中使用N-gram模型时,设置h = N,其中 h 为历史滑动窗口的大小。
3.1.2 LSTM方法
给定一个日志键序列,训练一个LSTM网络,使训练数据序列反映的下一个日志键值为 $k_i∈K$ 的概率最大。换句话说,它学习到一个概率分布 $P_r(m_t=k_i|m_{t-h},…m_{t-2},m_{t-1})$,使训练日志键序列的概率最大化。
图3。图的顶部显示了一个单独的LSTM块,它体现了LSTM的循环性质。每个LSTM块将其输入的状态作为一个固定维向量来记忆。上一个时间步的LSTM块的状态也被喂进到它的下一个输入,连同它的(外部)数据输入(在这个特殊的例子中是$m_{t-1}$),以计算一个新的状态和输出。这就是在单个LSTM块中传递和维护历史信息的方式。
一系列LSTM块在一个层中形成循环模型的展开版本,如图3的中心所示。每个cell维持一个隐藏向量 $H_{t-i}$ 和一个cell状态向量 。它们都被传递给下一个块来初始化它的状态。在我们的例子中,我们为来自一个输入序列 $w$ (一个包含 $h$ 个日志键的窗口)的每个日志键使用一个LSTM块。因此,一层由 $h$ 个展开的LSTM块组成。
在单个LSTM块中,输入(例如 $m_{t-i}$ ) 和之前的输出($H_{t-i-1}$)被用来决定
训练步骤需要对 weights 进行适当的分配,以便 LSTM 序列的最终输出产生所需的标签(输出),该标签来自训练数据集中的输入。在训练过程中,每个输入/输出对通过梯度下降最小化损失来增量地更新这些权值。在DeepLog中,输入由 h 个 日志键的窗口 w 组成,输出是 正好是w后 右边的日志键值,正好是w。我们使用分类交叉熵损失进行训练。
训练完成后,我们可以对输入$(w=m_{t-h},…,m_{t-1})$使用一层 h LSTM 块来预测输出。w中的每个日志键提要到该层中相应的LSTM块。
如果我们将多层叠加起来,使用前一层的隐藏状态作为下一层每个对应的LSTM块的输入,它就变成了一个深度LSTM神经网络,如图3的底部所示。为了简单起见,它省略了由标准编码-解码方案构造的输入层和输出层。输入层将K中的n个可能的日志键编码为one-hot向量。
3.2 参数值和性能异常
日志键序列对于检测执行路径异常非常有用。然而,一些异常并不是显示为偏离正常的执行路径,而是显示为不规则的参数值。这些参数值向量(对于相同的日志键)形成一个参数值向量序列,这些来自不同日志键的序列形成一个多维特征空间,对于性能监控和异常检测非常重要。
基线方法。一种简单的方法是将所有参数值向量序列存储到一个矩阵中,其中每一列都是来自一个日志键 k 的参数值序列(注意,根据参数值向量的大小,k可以有多个列)。这个矩阵的第 i 行表示一个时间实例 $t_i$。
DeepLog通过将每个参数值向量序列(对于一个日志键)作为一个单独的时间序列来训练一个参数值异常检测模型。为每个不同的日志键的参数值向量序列构建了一个单独的LSTM网络。
输入****。每个时间步的输入只是来自该时间戳的参数值向量。**我们用训练数据中相同参数位置的所有值的平均值和标准差对每个向量中的值进行归一化。
输出。输出是一个实值向量,用于根据最近历史的参数值向量序列预测下一个参数值向量。
训练目标函数。对于多变量时间序列数据,训练过程试图调整其LSTM模型的权值,以最小化预测和观测参数值向量之间的误差。我们利用均方损失来减小训练过程中的误差。
异常检测。预测和观测参数值向量之间的差异由均方误差(MSE)来测量。我们将训练数据划分为两个子集:模型训练集和验证集,而不是以一种特别的方式为异常检测提供一个神奇的错误阈值。对于验证集中的每个向量,我们应用训练集产生的模型来计算预测(使用验证集中之前的向量序列)和 之间的MSE。在每一个时间步,验证集的预测向量与实际向量之间的误差均建模为高斯分布。
部署时,如果预测值与观测值向量的误差在上述高斯分布的高可信区间内,则认为输入日志项的参数值向量是正常的,否则认为异常。
3.3 异常检测模型的在线更新
DeepLog有必要在其LSTM模型中增量更新权重,以合并和适应新的日志模式。
DeepLog为用户提供了一种反馈机制。允许DeepLog使用假阳性来调整权重。
例如,假设h = 3,最近的历史序列为 ${k_1, k_2,k_3}$, DeepLog预测下一个日志键为$k_1$的概率为1,而下一个日志键值为$k_2$,将被标记为异常。如果用户报告这是一个假阳性,DeepLog能够使用以下的输入输出对 ${k_1, k_2, k_3 \rightarrow k_2}$ 来更新它的模型的权重来学习这个新的参数。因此,下一次给定历史序列${k_1, k_2, k_3}$, DeepLog可以用更新的概率输出$k_1$和$k_2$。同样的更新过程也适用于参数值异常检测模型。注意,DeepLog不需要从头开始重新训练。在初始训练过程中,DeepLog中的模型以多个多维权重向量的形式存在。更新过程输入新的训练数据,并调整权重,使模型输出与假阳性情况下的实际观测值之间的误差最小化。
4.多任务执行的工作流构造
4.1 日志条目与多个任务分离
- 任务在时间上不会重叠。
 - 相同的日志键可能出现在多个任务中,并且在每个任务中都有可能并发。
 
目标是将日志文件中不同任务的日志条目分开,然后根据每个任务的日志键序列为其构建工作流模型。也就是说,我们的问题的输入是从一个原始日志文件解析出的整个日志键序列,输出是一组工作流模型,每个识别的任务一个。
4.2 Using DeepLog’s anomaly detection model
5. 评价
5.1 执行路径异常检测
本节重点评估DeepLog中的日志键异常检测模型。我们首先将其在大型系统上测试的有效性与以前的方法进行比较,然后研究不同参数对DeepLog的影响
5.2 参数值和性能异常
 为了评估DeepLog在检测参数值和性能(包括日志条目之间的运行时间)异常方面的有效性,我们使用了OpenStack VM创建任务中的系统日志。此数据集包括两种类型的异常:性能异常(日志项延迟到达)和参数值异常(VM创建时间比其他日志项长得多的日志项)。
5.3 DeepLog在线更新和培训
通过使用增量更新和不增量更新的检测结果的差异来证明有效性和科学性。
5.5 安全日志案例研究
5.6 任务分离,工作流构造
6.相关工作
7.总结
本文介绍了DeepLog,这是一个使用基于深度神经网络的方法在线检测和诊断日志异常的通用框架。DeepLog学习并编码整个日志消息,包括时间戳、日志密钥和参数值。它在每个日志条目级别执行异常检测,而不是在每个会话级别执行异常检测,因为以前的许多方法仅限于此。DeepLog可以从日志文件中分离出不同的任务,并使用深度学习(LSTM)和经典挖掘(密度聚类)方法为每个任务构建工作流模型。这可以实现有效的异常诊断。通过整合用户反馈,DeepLog支持对其LSTM模型进行在线更新/培训,因此能够整合并适应新的执行模式。对大型系统测井的广泛评估清楚地表明,与以前的方法相比,DeepLog具有更高的有效性。
未来的工作包括但不限于将其他类型的RNN(递归神经网络)合并到DeepLog中,以测试其效率,并整合来自不同应用和系统的日志数据,以执行更全面的系统诊断(例如,MySQL数据库的故障可能由单独的系统日志中记录的磁盘故障引起)