DeepLog:基于深度学习的系统日志异常检测与诊断

2022-09-14 14:21:43 浏览数 (2)

前言· DeepLog

阅读发表在ACM Conference on Computer and Communications Security (CCS'17)(CCF-A)上的论文 DeepLog : Anomaly Detection and Diagnosis from System Logs through Deep Learning,该文提出了一种基于深度学习的系统日志异常检测与诊断方法。通过阅读文章来了解一些使用深度学习进行日志异常检测的方法,期望能对我有所启发。春恋慕

Abstract

       异常检测是建立安全可靠系统的关键步骤。系统日志的主要目的是记录各种关键时刻的系统状态和重要事件,以帮助调试系统故障和执行根本原因分析。这种日志数据在几乎所有的计算机系统中都是普遍可用的。日志数据是理解系统状态和性能问题的重要而有价值的资源;因此,各种系统日志自然是在线监测和异常检测的良好信息源。我们提出DeepLog,一种利用长短期记忆(LSTM)的深度神经网络模型,将系统日志建模为自然语言序列。这允许DeepLog从正常执行中自动学习日志模式,并在日志模式偏离正常执行中从日志数据训练的模型时检测异常。[尚待斟酌]此外,我们演示了如何以在线方式增量地更新DeepLog模型,以便它能够随着时间的推移适应新的日志模式。此外,DeepLog从底层系统日志构建工作流程,这样一旦检测到异常,用户就可以有效地诊断检测到的异常并进行根本原因分析。对大量日志数据的广泛试验评估表明,DeepLog的性能优于其他基于传统数据挖掘方法的基于日志数据的异常检测方法。

1.Introduction

       异常检测是建立安全可靠的计算机系统的一项重要任务。随着系统和应用程序变得比以往任何时候都更加复杂,它们会受到更多的bug和漏洞的影响,对手可能会利用这些漏洞发起攻击。这些攻击也变得更加复杂。因此,异常检测变得更具挑战性,许多基于标准采矿方法(standard mining methodologies)的传统异常检测方法已不再有效。

系统日志记录了各种关键时刻的系统状态和重要事件,以帮助调试性能问题和故障,并进行根本原因分析。这样的日志数据在几乎所有的计算机系统中都是普遍可用的,并且是了解系统状态的宝贵资源。此外,由于系统日志记录了活跃运行进程中发生的值得注意的事件,因此它们是在线监控和异常检测的良好信息来源。

       利用系统日志数据进行异常检测的现有方法可以大致分为三组:

  1. 日志消息计数器上的基于PCA的方法(PCA based approaches over log message counters)
  2. 基于不变挖掘的方法捕获不同日志键之间的共现模式(invariant mining based methods to capture co-occurrence patterns between different log keys)
  3. 识别程序逻辑流中执行异常的工作流方法(workflow based methods to identify execution anomalies in program logic flows)。

尽管它们在某些情况下是成功的,但它们没有一个是有效的通用异常检测方法,能够以在线方式防范不同的攻击。

       这项工作提出了DeepLog,这是一种数据驱动的异常检测方法,可以利用大量的系统日志。DeepLog设计背后的关键直觉来自自然语言处理:我们将日志条目视为遵循特定模式和语法规则的序列元素。实际上,系统日志是由遵循一组严格的逻辑和控制流的程序产生的,非常像自然语言(尽管在词汇表上更有结构和限制)。为此,DeepLog是一个深度神经网络,它使用长短期记忆(LSTM)对日志条目序列进行建模。这允许DeepLog从正常执行中自动学习日志模式模型,并将正常系统执行中的偏差标记为异常。此外,由于它是一种学习驱动的方法,因此可以增量地更新DeepLog模型,以便它能够适应随着时间的推移出现的新的日志模式。

挑战.日志数据是非结构化的,并且它们的格式和语义可能因系统而异。即使知道发生了错误,使用非结构化日志诊断问题也具有挑战性;从海量的日志数据中进行在线异常检测更具挑战性。一些现有的方法使用基于规则的方法来解决这个问题,这需要特定的领域知识,比如使用“IP地址”等特性来解析日志。然而,这并不适用于一般的异常检测,因为它几乎不可能事先知道不同类型的日志中有什么有趣的特征(以及防范不同类型的攻击)。

异常检测必须及时,以便用户能够干预正在进行的攻击或系统性能问题。决策将以流媒体的方式做出。因此,需要多次传递整个日志数据的离线方法在我们的设置中不适用。我们也希望能够检测到不明类型的异常,而不是针对特定类型的异常。所以,先前的工作,使用正常的和异常的(对特定类型的异常)日志数据整个来训练一个二元分类用来异常检测,在这个背景中是不适用的。

另一个挑战来自于并发性。显然,在一个日志中日志消息的顺序为故障诊断与分析提供了重要的信息(例如,确定一个程序的执行路径)。然而,在许多系统日志中,日志消息被许多不同的线程或者并发运行任务所产生。并发性使得应用基于工作流的异常检测方法(将单个任务的工作流模型作为一个生成模型来与一个日志消息序列进行匹配)是很困难的。

最后,每个日志消息包含丰富的信息,比如一个日志key以及一个或者多个度量值,以及他的时间戳。整合和利用这些不同信息的整体方法将更有效。大多数现有的方法只分析日志消息的一个特定部分(例如,日志键),这限制了它们可以检测到的异常类型。

我们的贡献。循环神经网络(RNN)是一种人工神经网络,它使用一个环路将上一个状态的输出转发到当前输入,从而跟踪历史进行预测。长短期记忆网络(LSTM)是RNN的一个实例,能够记住序列上的长期依赖关系。LSTMs在各种任务中都取得了成功,如机器翻译、情感分析和医疗自我诊断。

我们观察到系统日志中的条目是由结构化源代码执行产生的一系列事件(因此可以被视为一种结构化语言),受此启发,我们设计了DeepLog框架,使用LSTM神经网络对系统日志进行在线异常检测。DeepLog不仅使用日志keys,也使用度量值来进行异常检测,因此,它能够捕获不同类型的异常。DeepLog仅依赖于一个小训练数据集,包括一个“normal log entries”序列。在训练阶段之后,DeepLog可以识别正常日志序列并且可以被用来在进来的日志上以流的方式进行在线异常检测。

直观上,DeepLog隐式地从与正常系统执行路径对应的训练数据中捕获日志条目之间潜在的非线性和高维依赖关系。为了帮助用户在发现异常后诊断问题,DeepLog还可以根据训练阶段的日志条目构建工作流模型。DeepLog将并发任务或线程产生的日志条目分成不同的序列,这样就可以为每个单独的任务构建工作流模型。

我们的评估表明,在之前研究过的一个大型HDFS日志数据集上,DeepLog只训练了正常系统执行的日志条目的很小一部分(不到1%),对剩下的99%的日志条目,DeepLog几乎可以达到100%的检测精度。一个大型OpenStack日志的结果也显示了类似的趋势。此外,DeepLog还可以结合实时用户反馈,在检测阶段逐步更新其权重。更具体地说,如果一个正常的日志条目被错误地归类为异常,DeepLog提供了一种用户反馈机制。DeepLog可以使用这样的反馈来在线动态调整权重,以适应新的系统执行(因此,新的日志)模式。

2.PRELIMINARIES

2.1 Log parser

我们首先将非结构化的、自由文本的日志条目解析为结构化的表示,这样我们就可以学习这种结构化数据的顺序模型。正如前面的几项工作所示,一种有效的方法是从每个日志条目中提取“日志键”(也称为“消息类型”)。日志项e的日志键指向源代码中print语句中的字符串常量k,该语句在代码执行期间打印了e。例如,日志项e(“Took 10 seconds to build instance.”)的日志key k是“Took * seconds to build instance.”,是一个来自print语句“printf("Took %f seconds to build instance",t)”。注意,参数在日志key中被抽象为星号。这些度量值反映了底层系统状态和性能状态。某些参数的值可以作为某个执行序列的标识符,例如HDFS日志中的block_id, OpenStack日志中的instance_id。这些标识符可以将日志条目分组在一起,或者将并发进程产生的日志条目整理成单独的、单线程的顺序序列。最先进的日志解析方法由Spell表示,这是一种无监督流解析器,它基于LCS(最长公共子序列)的思想以在线方式解析传入的日志条目。

过去的日志分析工作丢弃了日志条目中的时间戳和/或参数值,只使用日志键来检测异常。DeepLog存储每个日志条目e的参数值,以及e与其前一个条目之间所经过的时间,得到一个向量ve。除日志key外,DeepLog还使用这个向量。表1给出了一个示例,它展示了OpenStack中执行多轮虚拟机(VM)删除任务的一系列日志条目的解析结果。

2.2 DeepLog architecture and overview

DeepLog的架构如Figure 1所示,主要由三部分组成:日志键异常检测模型、参数值异常检测模型和用于诊断检测到的异常的工作流模型。

Training stage.DeepLog使用的训练数据是来自正常系统执行路径的日志条目。每个日志条目被解析为一个日志key以及一个参数值向量。DeepLog使用从训练日志文件中解析出的日志key序列来训练日志key异常检测模型,并构建用于诊断的系统执行工作流模型。对于每个不同的key k,DeepLog也训练和保持一个用于检测由这些度量值反映的系统性能异常的模型,通过k的参数值向量序列来训练。

Detection stage. 一个最新地到达的日志条目被解析成为一个日志key以及一个参数值向量。DeepLog首先使用日志key异常检测模型来检查新进入的日志key是否正常。如果正常,DeepLog对那个日志key使用参数值异常检测模型深入检查参数值向量。如果它的日志key或者它的参数值向量被预测为异常的,新的日志条目将被标上异常。最后,如果它被标为异常,DeepLog的工作流模型为用户提供语义信息来诊断异常。执行模式可能会随着时间的推移而改变,或者没有包含在原始的训练数据中。DeepLog也提供收集用户反馈的选项。如果用户将检测到的异常报告为假阳性,DeepLog可以使用它作为一个标记记录,以增量地更新它的模型,以合并和适应新的模式。

2.3 Threat model

DeepLog学习普通系统执行路径产生的日志条目序列中嵌入的全面和复杂的相关性和模式。因此,我们假设系统日志本身是secure and protected,对手不能攻击日志本身的完整性。我们还假设对手不能修改系统源代码来更改其日志记录行为和模式。也就是说,一般来说,我们考虑的攻击有两种类型。

(1)导致系统执行错误行为的攻击,从而导致系统日志中的异常模式。例如,Denial of Service(Dos)攻击会导致慢执行,从而反映在日志时间戳与参数值向量序列的差异上的性能异常;攻击导致重复服务器重启,比如Blind Return Oriented Programming (BROP)攻击表现在服务器重启日志key太多;以及任何可能导致任务终止的攻击,例如相应的日志序列提前结束和/或异常日志条目出现。

(2)由于系统监视服务的日志记录活动而可能在系统日志中留下跟踪的攻击。入侵检测系统(IDS)记录的可疑活动就是一个例子。

3 ANOMALY DETECTION

3.1 Execution path anomaly

我们首先描述如何使用日志key序列检测执行路径异常。由于源代码中不同print语句(打印日志条目)的总数是不变的,所以这个总数是不同日志key的总数。使用K={k1,k2,...,kn}来表示来自一个日志产生系统源代码的不同日志key的集合。

一旦日志条目被解析为日志键,日志键序列就会反映一个执行路径,该路径会导致日志打印语句的特定执行顺序。使用mi表示日志key序列中位于i位置的key值。显然,mi可能从K中获取n个可能的键,并且强烈依赖于mi之前出现的最近的键。

我们可以将日志键序列中的异常检测建模为一个多类分类问题,其中每个不同的日志键定义一个类。我们在最近的上下文中将DeepLog训练成一个多类分类器。输入是最近的日志密钥的历史记录,输出是来自K的n个日志密钥的概率分布,表示序列中的下一个日志密钥是密钥ki∈K的概率。

图2总结了分类器设置。假定t是下一个出现的日志key的序列id。分类的输入是一个w窗口,其中包含最近的h个日志键。它是,w={mt-h,...,mt-2,mt-1},其中每个mi在K中并且是来自日志条目ei的日志key。注意到同一个日志key值可能会在w中多次出现。训练阶段的输出是每个ki∈K(i = 1,…,n)的条件概率分布Pr[mt = ki |w]模型。检测阶段使用该模型进行预测,并将预测的输出与实际出现的观察到的日志键值进行比较。

Training stage. 训练阶段依赖一小部分由底层系统的正常执行产生的日志条目。对于训练数据中每个长度为h的日志序列,DeepLog更新其模型,以ki∈K作为下一个日志键值的概率分布。例如,假定正常执行产生了一个小规模日志文件,被解析成为一个日志key序列:{k22,k5,k11,k9,k11,k26}。给出一个窗口大小h=3,用于训练DeepLog的输入序列以及输出标签对将会是:{k22,k5,k11->k9},{k5,k11,k9->k11},{k11,k9,k11->k26}。

Detection stage. DeepLog在在线流媒体设置中执行异常检测。为了测试一个进来的日志key mt(被从一个进来的日志条目et解析出来)是否被认为是正常的或者不正常的,我们将w={mt-h,...,mt-1}作为DeepLog的输入。输出是一个概率分布Pr[mt|w]={k1:p1,k2:p2,...,kn:pn}来描述来自K的每个日志key作为给定历史的下一个日志键值出现的概率。

实际上,多个日志key值可以显示为mt。例如,如果系统正在企图连接一个主机,那么mt可以是‘Waiting for * to respond’ 或者‘Connected to *’;都是正常系统行为。DeepLog必须能够在训练过程中学习这些模式。我们的策略是基于日志key的概率Pr[mt|w]来为可能的日志key K排序,并将一个键值视为正常值,如果它位于排名靠前的top g个候选key中。否则,一个日志key将被标记为来自异常执行。

3.1.1 Traditional N-gram language model

给从固定词汇表中提取的单词序列赋予概率的问题是语言建模的经典问题,被自然语言处理(NLP)界广泛研究。在我们的案例中,每个日志key可以被看作是一个从词汇表K取的单词。为任意长的序列分配概率的典型语言建模方法是N-gram模型。人们的直觉是,一个特定的词在一个序列中只受其最近的前辈的影响,而不是整个历史。在我们的设定中,这个近似等于设定Pr(mt = ki|mi,…,mt-1)= Pr(mt = ki |mt-N,…,mt-1),其中N表示要考虑的近代历史的长度。

对于训练,我们可以使用来自大型语料库的相对频率计数来计算这个概率,从而给出极大似然估计。给出一个keys的长序列{m1,m2,...,mt},我们可以使用{mt-N,...,mt-1,mt=ki}相对于序列{mt-N,...,mt-1}的相对频率计数来估算观测第i个key ki的概率。换句话说,Pr(mt=ki|m1,...mt-1)=count(mt-N,...mt-1,mt=ki)/count(mt-N,...,mt-1). 注意到我们将使用一个大小为N的滑动窗口在整个key序列上计数这些频率。

为了在我们的设置上应用N-gram模型,我们简单地使用N作为历史窗口大小,例如,当使用N-gram模型时,我们在实验中设置h=N,其中h是历史滑动窗口大小,如Figure 2所示。我们使用这个作为一个baseline方法。

3.1.2 The LSTM approach

近几年,使用RNN的神经语言模型已经在多个NLP任务上展现了很好的效果。与N-gram语言模型相比,基于LSTM的模型可以对更复杂的模式进行编码,并在序列上保持长程状态。在系统日志中,复杂的模式和来自并发任务的交叉日志条目会降低传统语言模型的效率。于是,DeepLog使用LSTM神经网络对日志key序列进行异常检测。

给定一个日志key序列,训练一个LSTM网络,使训练数据序列反映的下一个日志键值为ki∈K的概率最大。换句话说,它学习到一个概率分布Pr(mt=ki|mt-h,...mt-2,mt-1),使得训练日志key序列的概率最大。

Figure 3阐述了我们的设计。figure的顶部展现了一个单独的LSTM块,它反映了LSTM的循环特性。每个LSTM块为它的输入记忆了一个状态,这个状态是一个固定维度的向量。来自之前的时间步的LSTM块的状态也喂给下一个输入,与它的(外部)数据输入一起(在这个特殊的例子中是mt-i ),来计算一个新的状态以及输出。这就是在单个LSTM块中传递和维护历史信息的方式。

一系列LSTM块在一个层中形成循环模型的展开版本,如Figure 3的中部所示。每个细胞维护一个隐藏向量Ht-i以及一个细胞状态向量Ct-i。这两个向量都被传递到下一个块来初始化它的状态。在我们的案例中,我们为输入序列w(一个包含h个日志key的窗口)中的每个日志key使用一个LSTM块。因此,一个简单的层由h个展开的LSTM块组成。

在单个LSTM块中,输入(例如mt-i)以及之前的输出(Ht-i-1)被用来决定(1)多少之前的细胞状态Ct-i-1会被保留进状态Ct-i,(2)如何使用当前的输入以及之前的输出来影响状态,以及(3)如何构造输出Ht-i. 这是通过使用一组门控函数来完成的,通过控制输入和前一个输出的信息量来确定状态动态,以及流向下一步的信息流。每个门控函数由一组待学习的权值参数化。LSTM块的表达能力由记忆体的数量(即隐藏状态向量H的维数)决定。由于篇幅限制,我们建议读者使用NLP引物来对LSTMs进行形式化表征。

训练步骤需要找到对权值的正确分配,以便LSTM序列的最终输出产生所需的标签(输出),该标签来自训练数据集中的输入。在训练过程中,每个输入/输出对递增地更新这些权重,通过梯度下降使损失最小化。在DeepLog中,一个输入由包含h个日志key的窗口w所组成,一个输出是w后紧跟的日志key值。我们使用分类交叉熵损失来进行训练。

在训练完成后,我们可以使用包括h个LSTM块的一层来为一个输入(w={mt-h,...mt-1})预测输出。w中的每个日志key流入到这个层中一个相应的LSTM块。

如果我们将多层叠加起来,使用前一层的隐藏状态作为下一层每个对应的LSTM块的输入,它就变成了一个深度LSTM神经网络,如Figure 3底部所示。为了简单起见,它省略了由标准编码-解码方案构造的输入层和输出层。输入层将来自K的n个可能的日志key编码为独热向量。也就是说,为日志key ki∈K构建一个稀疏的n维向量ui,使得ui[i]=1并且对于所有其他的j≠iui[j]=0.输出层使用标准的多项式逻辑函数来表示每个ki∈K的Pr[mt = ki|w],将最终隐藏状态转换为一个概率分布函数。

在Figure3的底部的例子显示仅有两个隐藏层的情况,但是可以使用更多的层。

3.2 Parameter value and performance anomaly(参数值以及性能异常)

日志key序列对于检测执行路径异常是很有帮助的。然而,一些异常没有显示为偏离正常的执行路径,但是是一个不规则的参数值。这些参数值向量(对于同样的日志key)形成一个参数值向量序列,并且这些来自不同日志key的序列形成一个多维特征空间,对于性能监视以及异常检测很重要。

Baseline approach. 一个简单的方法是存储所有的参数值向量序列到一个矩阵中,其中每一列是一个来自一个日志key k的参数值序列(注意到k有可能有多个列,这取决于它的参数值向量的大小)。在这个矩阵中的第i行代表一个时间实例ti

以Table1中的日志条目为例。在这个例子中,有三个不同的日志key值,并且他们参数值向量的大小分别是2,2,1。因此,在这个矩阵中的第一行代表时间实例t1,其值为[t1-t0,file1Id,null,null,null].类似地,第二行以及第三行分别为[null,null,t2-t1,0.61,null]以及[null,null,null,null,t3-t2]。

我们还可以要求每一行表示一个时间实例范围,以便每一行对应该时间范围内的多个日志消息,从而变得不那么稀疏。但当日志键值较多且/或存在较大的参数值向量时,矩阵仍然会非常稀疏。此外,该方法给异常检测过程带来了一定的延迟,并且,为每个范围的长度计算一个好的值也很困难。

给出这个矩阵,许多知名的数据驱动异常检测方法能够被应用,比如主成分分析(PCA)和自组织映射(SOM)。他们对捕获不同特征维度之间的关系很有用。然而,这种方法在日志数据上下文中的一个主要限制是,在一个特定的时间实例中出现多个日志键的可能性通常是相等的。例如,由于同时运行的任务,Table1中的k1和k2的顺序是任意的。这种现象,以及矩阵稀疏的事实,使得这些技术在我们的设置中无效。最后,他们不能对存在于参数值向量序列中的自相关(单个向量序列中随时间变化的规则模式)进行建模。

Our approach. DeepLog 通过将每个参数值向量序列(对于一个日志key)视为一个单独的时间序列,训练了一个参数值异常检测模型。

考虑Table1中的例子。k2的参数值向量序列的时间序列是:{[t2-t1,0.61],[t'2-t'1,1]}.因此,我们的问题简化为从多变量时间序列数据进行异常检测。可以再次应用基于lstm的方法。我们使用一个与Figure3中所示的相似的LSTM网络来为多变量时间序列数据建模,并做出了以下调整。注意到为每个不同的日志key值的参数值向量序列建造一个独立的LSTM网络。

Input.每个时间步的输入只是来自该时间戳的参数值向量。我们用训练数据中相同参数位置的所有值的平均值和标准差对每个向量中的值进行归一化。

Output. 输出是一个实值向量,用于根据最近历史的参数值向量序列预测下一个参数值向量。

Objective function for training.对于多变量时间序列数据,训练过程致力于调整LSTM模型的权重,目的是为了最小化预测值与观测到的参数值向量的差异。于是,均方误差被用来最小化训练过程中的误差。

Anomaly detection.一个预测值与一个观测到的参数值向量之间的差异被均方误差(MSE)所测量。我们将训练数据划分为两个子集:模型训练集和验证集,而不是以一种特别的方式设置用于异常检测目标的逻辑错误阈值。对于每个验证集中的向量v,我们应用通过训练集产生的模型来计算预测(使用验证集中v之前的向量序列)和v之间的MSE。在每个时间步,预测向量和验证集中正确的那个之间的误差被建模为一个高斯分布。

部署时,如果预测和观测值向量的误差在上述高斯分布的高置信区间内,则认为输入日志项的参数值向量是正常的,否则认为是异常的。

由于日志消息中的参数值常常记录重要的系统状态指标,这个方法能够检测多种类型的性能异常。例如,一个性能异常可能反映为“slow down(放慢速度)”。回想一下,DeepLog将连续日志条目之间的时间间隔存储在每个参数值向量中。上述的LSTM模型,通过将参数值向量建模为一个多变量时间序列,能够检测到在这个时间序列中一或多维不寻常的模式;运行时间值只是这样一个维度。

3.3 Online update of anomaly detection models

显然,训练数据可能不会涵盖所有可能的正常执行模式。系统行为可能会随着时间的推移而改变,另外还取决于工作负载和数据特征。因此,DeepLog有必要在其LSTM模型中增量更新权重,以合并和适应新的日志模式。为此,DeepLog为用户提供了一种反馈机制。这允许DeepLog使用假阳性来调整它的权重。例如,假设h = 3,最近的历史序列为{k1, k2, k3}, DeepLog预测下一个日志键为k1的概率为1,而下一个日志键值为k2,将被标记为异常。如果用户报告这是一个假阳性,DeepLog能够使用以下的输入输出对{k1, k2, k3→k2}来更新它的模型的权重来学习这个新模式。因此,下一次给定历史序列{k1, k2, k3}, DeepLog可以用更新的概率输出k1和k2。同样的更新过程也适用于参数值异常检测模型。注意,DeepLog不需要从头开始重新训练。在初始训练过程结束后,DeepLog中的模型以多个多维权重向量的形式存在。更新过程输入新的训练数据,并调整权重,使模型输出与假阳性情况下的实际观测值之间的误差最小化。

4 WORKFLOW CONSTRUCTION FROM MULTI-TASKS EXECUTION

每个日志键都是源代码中日志打印语句的执行,而像VM创建这样的任务将产生一系列日志条目。直观地说,一个任务产生的日志条目的顺序代表了完成该任务的每个函数的执行顺序。因此,我们可以构建一个工作流模型作为有限状态自动机(FSA)来捕获任何任务的执行路径。该工作流模型还可以用于检测执行路径异常,但与DeepLog的LSTM模型相比,它的效果较差,因为它无法捕获任务间的依赖关系和不确定的循环迭代。然而,工作流模型非常有用,当检测到异常时,它可以帮助用户诊断任务执行过程中发生了什么问题。

给定一个由任务重复执行产生的日志序列,已有一些研究工作探讨工作流推断的问题。CloudSeer代表了使用工作流模型进行异常检测的最新技术。CloudSeer有几个限制。首先,它能检测到的异常仅限于日志记录级别为“ERROR”的日志条目和未出现的日志条目。此外,它的工作流模型构造只需要一个重复执行单个任务的日志文件。以前关于从日志文件构建工作流的其他工作也受到这种限制。

4.1 Log entry separation from multiple tasks

一个简单的例子是多个程序并发地写入同一个日志(例如,Ubuntu的系统日志)。通常,每个日志条目都包含创建它的程序的名称。另一种简单的情况是,进程或任务id包含在日志条目中。这里,我们关注的是重复执行一个用户程序来执行程序中不同但逻辑上相关的任务的情况。一个重要的观察结果是,任务不会在时间上重叠。但是,同一个日志键可能出现在多个任务中,并且在每个任务中可以并发(例如,在一个任务中有多个线程)。

以OpenStack管理日志为例。每个虚拟机实例的生命周期包括创建虚拟机、关闭虚拟机、删除虚拟机等。这些任务不重叠,即VM创建完成后才能启动VM停止。但是,相同的日志键可能出现在不同的任务中。例如,创建虚拟机、启动虚拟机、恢复虚拟机、恢复虚拟机可能出现“虚拟机恢复(生命周期事件)”日志消息。每个任务中可能有并发运行的线程,导致与一个任务对应的日志消息的顺序不确定。例如,在VM创建过程中,两个日志消息的顺序“Took * seconds to build instance”以及“VM Resumed (Lifecycle Event)”是不确定的。

我们的目标是将日志文件中不同任务的日志条目分开,然后根据每个任务的日志键序列为其构建工作流模型。也就是说,我们的问题的输入是从一个原始日志文件解析出的整个日志键序列,输出是一组工作流模型,每个识别的任务一个。

4.2 Using DeepLog‘s anomaly detection model

4.2.1 Log key separation.

回想一下,在DeepLog的日志键异常检测模型中,输入是近期历史中长度为h的日志键序列,输出是所有可能的日志键值的概率分布。一个有趣的发现是,它的输出实际上编码了底层工作流执行路径。

直观地说,给定一个日志键序列,我们的模型根据在训练阶段观察到的执行模式预测接下来会发生什么。如果序列w在训练阶段从不后跟特定键值k,则Pr[mt = k|w] = 0。相应的,如果序列w后面总是跟着k,那么Pr[mt = k|w] = 1。例如,假设一个序列“25→54”,输出预测是“{57:1.00}”,我们知道“25→54→57”来自一个任务。更复杂的情况是,序列w后面跟着一组不同键的日志键值;这些键出现在w之后的概率合为1。

为了处理这种情况,我们使用了一个受小型不变量挖掘(small invariants mining)启发的思想。

考虑一个日志序列“54→57”,假设预测的概率分布是“{18:0.8,56:0.2}”,这意味着下一步可能是“18”或“56”。这种模糊性可能是由于使用的历史序列长度不足造成的。例如,如果两个任务共享同一个工作流段“54→57”,则第一个任务采用“18→54→57→18”的模式,执行时间为80%,第二个任务采用“31→54→57→56”的模式,执行时间为20%。这将导致一个模型预测“{18:0.8,56:0.2}”给定序列“54→57”。

我们可以通过使用不同的历史序列长度训练模型来解决这个问题,例如,在本例中使用h = 3而不是h = 2。在工作流构建过程中,我们使用了一个可以更确定预测的日志序列长度,例如,上面的例子中,“18→54→57”序列可以预测{18:1.00},“31→54→57”序列可以预测{56:1.00}。

如果我们已经排除了一个小序列是来自不同任务的共享片段(即增加用于训练和预测的序列长度并不会导致更确定的预测),现在的挑战是找出是否多键预测输出是由同一任务的并发或不同任务的开始引起的。我们称之为散度点(divergence point)。

我们观察到,如Figure 4a所示,如果发散点是由同一个任务中的并发性引起的,一个常见的模式是,预测输出中概率最高的键将一个接一个出现,并且对于以下预测的确定性(以较少键数的更高概率衡量)将会增加,因为一些并发线程的键已经出现了。当所有并发线程的键都包含在历史序列中之后,预测将最终确定。

另一方面,如果发散点是由新任务的启动引起的,如Figure 4b所示,则预测的日志key候选项(本例中的“24”和“26”)将不会依次出现。如果我们将每个这样的日志键合并到历史序列中,下一个预测是一个新的日志键的确定性预测(例如,“24→60”,“26→37”)。如果是这种情况,我们将停止当前任务的工作流模型增长(在本例中停止在键“57”处),并开始为新任务构建工作流模型。注意,图4b中的两个“新任务”也可以是一个“if-else”分支,例如,“57→if(24→60→…)else(26→37→…)”。为了处理这种情况,我们应用一个简单的启发式方法:如果“新任务”的日志键很少(例如,3),并且总是出现在一个特定的任务Tp之后,我们将它视为Tp的“if-else”分支的一部分,否则视为一个新任务。

4.4.2 Build a workflow model.

一旦我们能够区分同一任务和新任务中由并发(多线程)引起的发散点,我们就可以很容易地构建如Figure 4a和Figure 4b所示的工作流模型。需要额外注意识别循环。循环的检测实际上是相当直接的。在初始工作流模型中,循环总是表现为展开的链;参见Figure 4c中的示例。虽然这个工作流链最初是“26→37→39→40→39→40”,但我们可以将重复的片段识别为循环执行(本例中为39→40)。

4.3 Using density-based clustering approach

4.3.1 Log key separation.

另一个方法是使用一个基于密度的集群方法。直觉上,相同任务中的日志键总是一起出现,但不同任务的日志键不一定总是一起出现,因为不同任务的多次执行过程中,任务的顺序不是固定的。这允许我们基于共现模式对日志键进行集群,并在共现率较低时将键分离到不同的任务中。

在日志键序列中,任意两个日志键之间的距离d定义为它们之间的日志键数加1。例如,给定序列{k1, k2, k2}, d(k1, k2) = [1,2],d(k2, k2) = 1(注意这对(k1, k2)之间有两个距离值)。

我们构建了一个同遇矩阵,如Table 2所示,其中每个元素pd (i, j)表示两个log key ki和kj出现在输入序列中距离d内的概率。其中f (ki)为ki在输入序列中的频率,fd(ki, kj)为输入序列中(ki, kj)对在距离d内同时出现的频率。我们定义pd(i, j) =fd(ki,kj)/d·f (ki),这表明了kj对ki的重要性。

例如,当d = 1时,p1(i, j) =f1(ki,kj)/f (ki)= 1意味着对于ki的每一次出现,它后面必须有一个kj。注意,在这个定义中,分母中的f (ki)按d缩放,因为当计算d内的同出现频率时,键ki被计算d次。将f(ki)乘以d的倍数确保对于任意i,都有:

注意,我们可以为d的不同距离值建立多个共现矩阵。

对于我们建立的每个距离值d,都有一个共现矩阵,我们的目标是输出一组任务TASK=(T1,T2,...).集群的工作过程如下。首先,对于d = 1,我们检查是否有p1(i, j)大于阈值τ(假设τ = 0.9),当它大于阈值时,我们将ki, kj连接在一起,形成T1 = [ki, kj]。接下来,我们递归地检查T1是否可以从头部或尾部扩展。例如,如果存在kx∈K,使p1(ki, kx) >τ,我们进一步检验是否p2(kj, kx) >τ,即是否kj和kx在距离2内有较大的共现概率。如果是的话,T1=[kx,ki,kj],否则我们将T2=[ki,kx]加入到TASK中。

这个过程一直持续到task中没有任务T可以被进一步扩展为止。一般情况下,当要扩展的任务T有2个以上的日志key时,当检查kx是否可以被包括为新的头或尾时,我们需要检查kx与T中的每个对数键是否有大于τ的共现概率,一直到距离d',其中d'是:i) T长度的较小值,ii)我们已经为其建立了共出现矩阵的d的最大值。例如,要检查T = [k1, k2, k3]是否应该连接k4的尾巴,我们需要检查是否min(p1(k3, k4),p2(k2, k4),p3(k1, k4)) >τ。

上面的过程为每个任务连接顺序日志key。当任务T1 = [ki, kj]不能被扩展到包含任何单个键时,我们检查T1是否可以被两个日志键扩展,即是否存在kx, ky∈K,使p1(ki, kx) p1(ki, ky) >τ,或p1(kj, kx) p1(kj, ky) >τ。假设后一种情况是正确的,接下来要检查的是kx和ky是否是任务T1中并发线程产生的日志键。如果是,pd(kj, kx)总是随着d值的增大而增大,即p2(kj, kx) >P1 (kj, kx),这很直观,因为并发线程的key的出现顺序是不确定的。否则kx和ky不属于T1,因此我们将T2 = [kj, kx]和T3 = [kj, ky]加入到TASK中。

最后,对于task中的每个任务T,如果T的序列作为子序列包含在另一个任务中,我们就消去T。

4.3.2 Build workflow model.

一旦为每个任务分离并确定了日志键序列,任务的工作流模型构建遵循第4.2.2节的相同讨论。

4.4 Using the workflow model

4.4.1 Set parameters for DeepLog model.

在3.1节中,我们已经展示了DeepLog需要几个输入参数,特别是,它需要历史序列窗口的长度h(用于训练和检测),以及被概率分布函数认为是正常的预测输出中top g日志key的数量。

为h和g设置一个合适的值是与问题相关的。一般来说,较大的h值会提高预测精度,因为LSTM中利用了更多的历史信息,直到到达一个点,在这个点上,历史上较远的键不能帮助预测出现的键。此时继续增加h并不会影响LSTM的预测精度,因为LSTM能够知道在一个长序列中只有最近的历史是重要的,因此忽略了长尾。但是,较大的h值确实会对性能产生影响。训练和预测需要更多的计算(和层),这降低了DeepLog的性能。另一方面,g的值调节了真阳性(异常检测率)和假阳性(误报率)之间的权衡。

工作流模型提供了为h和g设置适当值的指导。直观地说,h需要足够大,以纳入必要的依赖关系,以便进行良好的预测,因此我们可以将h设置为最短工作流的长度。可能的执行路径的数量代表g的一个很好的值,因此,我们将g设为所有任务工作流的所有发散点上分支的最大数量。

4.4.2 Using workflow to diagnose detected anomalies.

每当DeepLog检测到异常时,就可以使用工作流模型来帮助诊断该异常,并了解其发生的方式和原因。图5显示了一个示例。使用一个历史序列[26,37,38],DeepLog的顶部预测是log key 39(假设g = 1),但是实际出现的log key是67,这是一个异常。借助该任务的工作流模型,用户可以很容易地识别出对应工作流中的当前执行点,并进一步发现该错误发生在“实例销毁成功”之后,“删除实例文件*”之前,这意味着该错误发生在销毁虚拟机后的清理过程中。

4.5 Discussion

以前的工作集中于从一个任务的多次执行构建工作流。他们的方法的基本思想如下3个步骤:1)挖掘每对日志密钥的时间依赖性;2)利用步骤1中确定的两两不变量构建基本工作流;3)使用输入的日志键序列细化工作流程模型。一个主要的限制是,它们不能处理包含多个任务或一个任务中并发线程的日志序列,这在我们的研究中得到了解决。我们的任务分离方法还为每个任务的工作流构建提供了有用的见解。

5 EVALUATION

DeepLog是使用Keras和TensorFlow作为后端来实现的。在本节中,我们将对DeepLog的每个组件和整体性能进行评估,以展示其从大型系统日志数据中发现异常的有效性。

5.1 Execution path anomaly detection

本节主要对DeepLog中的日志密钥异常检测模型进行评估。我们首先将其与之前的方法在大型系统日志上的有效性进行比较,然后研究DeepLog中不同参数的影响。

5.1.1 Previous methods.

以前关于通用日志异常检测的工作遵循类似的过程:他们首先从每个日志消息中提取一个日志键,然后对日志键序列执行异常检测。

主成分分析(PCA)方法假设日志文件中有不同的“会话”,可以通过附加到每个日志条目的会话id轻松地识别。它首先按会话对日志键进行分组,然后计算每个日志键值在每个会话中的出现次数。会话向量的大小为n,表示K中每个log key在会话中的出现次数。矩阵中其中每一列是一个日志键,每一行是一个会话向量。PCA通过测量变换后的坐标系在剩余子空间上的投影长度来检测异常向量(会话)。该方法比在线PCA方法更有效,特别是在减少假阳性方面,但这显然是一种离线方法,不能用于在线异常检测。该实现是由[17]开放源码的。

不变挖掘(IM)[22]构造与PCA方法相同的矩阵。IM首先挖掘大多数向量能够满足的小不变量,然后将那些不满足这些不变量的向量视为异常执行会话。这种方法被证明比早期使用工作流自动机的工作[11]更有效。该实现是由[17]开放源码的。

TFIDF是在[44]中开发的。虽然它的目标是IT系统故障预测,但不同于[39]所示的异常检测。尽管如此,我们仍然在评估中包括这种方法,因为它也使用基于lstm的方法。有几个关键的区别。TFIDF按时间窗口对日志键进行分组(每个时间窗口由一个用户参数定义),然后使用TF-IDF(术语频率,逆文档频率)向量对每个时间窗口(称为“epoch”)进行建模。它使用的拉普拉斯平滑过程需要时间窗口总数的知识(因此需要整个日志文件)。TFIDF构造一个LSTM模型作为二值分类器,该模型需要带标记的正常和异常数据进行训练。不仅异常日志条目难以获取,而且训练数据中未包含的新类型异常可能无法检测到。相比之下,DeepLog将其LSTM模型训练为多类分类器,只需要正常数据进行训练。

CloudSeer是专为多用户OpenStack日志[42]设计的一种方法。它为每个与OpenStack虚拟机相关的任务建立一个工作流模型,并使用该工作流进行异常检测。虽然它在OpenStack日志上获得了可以接受的性能(在论文中报告的精度为83.08%,召回率为90.00%),但这种方法不适用于其他类型的日志(例如HDFS日志),因为日志键的模式要不规则得多。例如,CloudSeer只建模在每个会话中“出现相同次数”的日志键。在HDFS的日志中,29个日志键中只有3个满足这个条件。此外,这种方法不能将一个日志中不同任务的日志条目分离到单独的序列中。它依赖于多个标识符来实现这一点,这对于通用日志来说并不总是可能的。因此,这里不进行比较。

5.1.2 Log data sets and set up.

HDFS log data set.它是通过在200多个Amazon EC2节点上运行基于Hadoop的map-reduce作业生成的,并由Hadoop领域专家标记。收集到的1197954条日志中,异常事件约占2.9%,包括“写异常”等事件。这是基于PCA的离线[39]方法首先使用的主要数据集,随后被在线PCA[38]和基于im的[22]方法等其他工作使用。该数据集的详细信息可以在[38,39]中找到。

OpenStack log data set.我们在CloudLab[30]上部署了一个OpenStack实验(Mitaka版本),其中包括一个控制节点、一个网络节点和8个计算节点。在收集到的1335318条日志中,约7%的日志异常。脚本在运行中不断执行虚拟机相关的任务,包括创建/删除虚拟机、停止/启动虚拟机、暂停/恢复虚拟机、挂起/恢复虚拟机。VM任务使用正则表达式的模式调度:Create (Stop Start) {0,3} (Pause Unpause) {0,3} (Suspend Resume) {0,3} Delete) 。虚拟机的生命周期以“创建虚拟机”开始,以“删除虚拟机”结束,而“停止-启动”、“暂停-恢复”、“挂起-恢复”等任务对可能在一个生命周期内随机出现0 ~ 3次。收集nova-api、nova-scheduler和nova-compute的INFO级别日志,并使用Elastic Stack[33]进行分析。在不同的执行点注入了三种类型的异常:1)创建VM时的中子超时;2) 销毁虚拟机时libvirt error;3)销毁虚拟机清理过程中libvirt error。

Set up. 为了执行基于pca和基于im的方法,我们通过一个标识符字段将日志条目分组到不同的会话中,标识符字段在HDFS中是block_id, 在OpenStack中是instance_id。每个会话组分别是一个块或一个虚拟机实例的生命周期。DeepLog可以直接应用于日志键,训练其权重,随后用于检测异常,而其他方法则需要更多的步骤。他们需要计算每个会话中每个不同的日志键出现的次数,并构建一个矩阵,其中每一列都是一个不同的日志键(因此将有n列),每一行表示一个会话向量,矩阵中一个单元Vij的值表示第i个会话中日志键kj的计数。

DeepLog需要一小部分正常的日志条目来训练它的模型。在HDFS日志中,只有不到1%的正常会话(从前100000个日志条目解析4855个会话,而总共11197954个会话)用于训练。请注意,DeepLog可以精确地指出哪个日志条目(与其对应的日志键)是异常的,但为了使用与竞争方法相同的措施来比较,我们使用“会话”作为异常检测的粒度,即,只要存在至少一个来自C的日志键被检测到异常,会话C就被认为是异常会话。

表3总结了这两个数据集。请注意,PCA和IM是无监督的离线方法,不需要训练数据,而DeepLog只需要正常系统执行产生的训练数据,而TFIDF需要正常和异常数据进行训练。

除了假阳性(FP)和假阴性(FN)的数量,我们还使用了标准指标,如精确度、召回率和f测量。Precision表示在所有检测到的异常中真实异常的百分比;召回率是在数据集中(假设我们知道基本事实)检测到的异常的百分比;F-measure=2·Precision·Recall/(Precision Recall)是两者的调和平均值。

默认情况下,我们对DeepLog使用以下参数值:g = 9, h = 10, L = 2, α = 64,并在我们的实验中研究它们的影响。Recall g决定预测输出中的截止值被认为是正常的(即top-g概率下一个出现的g log键值被认为是正常的),h是用于训练和检测的窗口大小。L和α分别表示DeepLog中的层数和一个LSTM块中的存储单元数。对于所有其他方法,我们探索了它们的参数空间并报告了它们的最佳结果。当使用N-gram方法时,除非另有说明,否则我们设置N = 1,因为这显示了N-gram方法的最佳性能。

5.1.3 Comparision.

表4显示了HDFS数据上每种方法的假阳性和假阴性的数量。PCA实现了最少的假阳性,但以更多的假阴性为代价。图6a使用召回率、精度和F-measure进行了更深入的比较。注意,由于空间有限和相对性能非常差,TFIDF在图中被省略了。

显然,DeepLog取得了最佳的整体表现,其f值为96%。当历史长度为1时,我们的基线解决方案N-gram也获得了良好的性能。但是,随着历史窗口变长,它的性能会急剧下降。相比之下,基于lstm的方法更稳定,如5.1.4节所示。

图6b调查了DeepLog预测算法使用的top-g方法。设Dt为DeepLog在t时刻预测的top-g log key值的集合,mt为t时刻数据中实际出现的log key值。为了看到这种策略的影响,我们研究了Pr[mt∈Dt]对于不同g值的CDF。在超过11,000,000个日志键(标记为正常)预测中,DeepLog的顶级预测有88.9%与mt的精确匹配;96.1%的mt's在DeepLog的前两名预测范围之内。当g = 5时,99.8%的正常mt在Dt内,同时异常检出率为99.994%(只有一个异常会话未检测到)。

OpenStack数据集的性能如图7a所示。PCA方法在该数据集上表现出了合理的性能,但精度较低(只有77%),而IM在这种情况下实现了完美的召回,但精度非常差,只有2%(几乎所有VM实例都被检测为异常执行)。这是因为OpenStack的日志是随机生成的,如5.1.2所示。请注意,像(停止启动)这样的日志键在VM(由一对创建和删除定义)的生命周期中出现的次数是不确定的。这使得IM很难找到用于异常检测的“稳定小不变量”。

为了测试这个假设,我们生成了第二个数据集,它具有确定性模式,比如(Create Delete) ,总共执行了5,544次正常VM执行和170次异常VM执行。我们将这个数据集表示为OpenStack II,结果如图7b所示。IM在这个具有更规则模式的数据集上表现得非常好。然而,在这种情况下,PCA方法的召回率下降到只有2%,因为数据中的正常模式过于规则,呈现通过方差检测异常的PCA方法不起作用。

另一方面,DeepLog在两个OpenStack日志上都表现出色,F-measure分别为98%和97%。最后,还需要注意的是,PCA和IM是离线方法,它们不能用于对每个日志条目执行异常检测。它们只能在会话级别检测异常,但是会话的概念可能在许多系统日志中都不存在。

5.1.4 Analysis of DeepLog.

我们研究了DeepLog中各种参数的性能影响,包括g、h、L和α。结果如图8所示。在每个实验中,我们改变一个参数的值,而对其他参数使用默认值。一般来说,对于不同的值,DeepLog的性能是相当稳定的,也就是说,它对这些参数值的任何一个或组合的调整不是很敏感。这使得DeepLog在实践中很容易部署和使用。结果也很容易理解。如图8c所示,g值越大,准确率越高,召回率越低。因此,可以通过调整g来实现更高的真阳性率或更低的假阳性率。最后,在我们的标准工作站上,DeepLog每个日志条目的预测成本仅为1毫秒左右,这可以通过更好的硬件(如使用GPU)进一步提高。

5.2 Parameter value and performance anomaly.

为了评估DeepLog检测参数值和性能(包括日志条目之间的运行时间)异常的有效性,我们使用了来自OpenStack VM创建任务的系统日志。该数据集包括两种类型的异常:性能异常(日志条目延迟到达)和参数值异常(创建VM时间比其他日志条目长得多的日志条目)。

Experiment setup. 与之前一样,我们在CloudLab上部署了一个OpenStack实验,并编写了一个脚本来模拟多个用户不断请求创建和删除VM。在创建OpenStack虚拟机时,一个重要的步骤是将需要的镜像从控制节点复制到将要创建虚拟机的计算节点。为了模拟可能由DoS攻击引起的性能异常,我们在两个不同的点限制控制器到计算节点的网络速度,看看DeepLog是否能检测到这些异常。

Anomaly detection. 如3.2节所述,我们将日志条目分成两个集合,一个集合用于模型训练,另一个集合(称为验证集)用于应用模型生成MSEs((均方误差))的高斯分布。在随后的在线检测阶段,对于每一个传入的参数值向量v, DeepLog检查v和其模型的预测输出(也是一个向量)之间的MSE是否在验证集中MSE的高斯分布的可接受的置信区间内。

图9显示了不同日志键参数值向量的检测结果,其中x轴表示正在创建的VM的id(即不同的VM创建实例),y轴表示参数值向量与DeepLog预测输出向量之间的MSE。每个图中的水平线是对应的MSE高斯分布的置信区间阈值。图9a和9b表示两个日志键,它们的参数值向量在整个时间内都是正常的。图9c和9d表明,密钥53和56的参数值向量在我们限制网络速度的两个时间实例(即注入异常)被成功检测到异常。

对于检测到的每个异常参数值向量,我们识别出与预测差异最大的值,以识别异常列(特征)。我们发现键53的两个异常参数值向量是由于异常大的运行时间值。另一方面,键56是“Took * seconds to build instance”,毫不奇怪,它的两个异常参数值向量是由异常大的值(秒)引起的。

5.3 Online update and training of DeepLog

章节5.1已经证明了DeepLog只需要很小的训练集(不到整个日志的1%),并且在训练阶段不需要用户反馈。但也有可能在检测阶段出现新的系统执行路径,这也是正常的,但由于没有在训练数据中反映出来,所以被检测为异常。为了解决这个问题,本节将评估DeepLog在线更新和培训模块的有效性,如3.3节所述。我们通过在有效性和效率方面使用增量更新和不使用增量更新的检测结果的差异来演示这一点。

5.3.1 Log data set.

本节使用的日志数据集为Blue Gene/L超级计算机系统日志,共有4,747,963条日志记录,其中有348,460条记录被标记为异常。我们选择这个数据集是因为一个重要的特性:许多日志键只在特定的时间段内出现。这意味着训练数据集可能不包含所有可能的正常日志键,更不用说所有可能的正常执行模式了。

5.3.2 Evaluation results.

我们进行了两个实验,一个使用前1%的正常日志条目作为训练数据,另一个使用前10%的日志条目进行训练。在这两个设置中,剩余的99%或90%的表项用于异常检测。设L = 1 α = 256 g = 6 h = 3。

图10显示了没有在线培训和有在线培训两种实验的结果。在“没有在线培训”的情况下,我们运行DeepLog来测试传入的日志条目,没有任何增量更新。而对于“在线培训”的情况,我们假设有一个最终用户,如果检测到的异常是假阳性,他会报告。如果是这样,DeepLog就会使用这个样本(现在是一个带标签的记录)来更新它的模型来学习这个新模式。图10显示,如果没有在线训练,只有1%的离线训练数据,这将导致许多假阳性(因此精度非常低)。虽然将训练数据增加到10%会略微提高精度,但性能仍然不理想。另一方面,通过在线培训,DeepLog显著提高了精度,因此f测量分数。在两种设置下,真实阳性率均为100%(完美回忆),在线训练将1%训练数据的假阳性率从40.1%降低到1.7%,将10%训练数据的假阳性率从38.2%降低到1.1%。

表5显示了检查每个日志条目的平摊成本。对于在线培训案例,我们报告了检测和在线更新(如果触发更新)所需的时间。结果表明,在线更新和训练确实增加了每个日志条目的平摊成本,但仅略有增加。这是因为许多日志条目不会触发更新。注意在线更新和在线检测可以并行执行;当模型使用当前的权值继续进行检测时,会进行更新。

5.4 Security log case studies

具有从未在用于训练的正常日志中出现的日志键的异常(例如,“ERROR”或“exception”日志消息)很容易检测。DeepLog可以有效地检测更微妙的情况。例如,在HDFS的日志中,“Namenode not updated after deleting block”的异常显示为会话中缺少日志键;和“Redundant addStoredBlock”异常显示为一个额外的日志键。这意味着对于任何可能导致系统行为改变的攻击(通过日志反映),都可以检测到。接下来,我们将调查包含真实攻击的系统日志,以证明DeepLog的有效性。

5.4.1 Network security log.

网络安全至关重要。防火墙和入侵检测系统(IDS)都可以生成日志,用于在线异常检测。

为了测试DeepLog在网络安全日志上的性能,我们使用了VAST Challenge 2011数据集,特别是Mini Challenge 2 -计算机网络操作[1]。这个挑战是通过可视化技术手工寻找可疑的活动。它是异常活动的基本事实。对于地面真实值中的所有异常,表6显示了DeepLog的结果。唯一没有被检测到的可疑活动是第一次出现未注册的计算机IP地址。

唯一的误报是由于DeepLog报告了一条日志消息,该日志消息作为异常在短时间内重复出现多次。这是由于一个事件突然变得突发,并在短时间内多次打印相同的日志消息。这并没有被VAST挑战认定为可疑活动。

5.4.2 BROP attack detection.

面向盲返回编程攻击[5]利用了一个事实,即许多服务器应用程序在崩溃后重新启动,以确保服务的可靠性。这种攻击是强大而实用的,因为攻击者既不依赖于对源代码的访问,也不依赖于对二进制代码的访问。如果存在导致服务器崩溃的堆栈缓冲区溢出漏洞,就足以实施这种攻击。在BROP利用中,攻击者使用服务器崩溃作为一个信号来帮助完成ROP攻击,从而实现执行shellcode。然而,重复的服务器重启活动在内核日志中留下了许多非典型的日志消息,如下所示,这很容易被DeepLog检测到。

5.5 Task separation and workflow construction

我们实现了第4节中提出的方法,并通过各种与OpenStack vm相关的任务在日志上进行了评估。LSTM方法和基于密度的聚类方法都可以成功地分离所有任务。第一种方法需要LSTM;它是一种有监督的方法,需要提供训练数据。第二种方法是对一定距离阈值内的日志键的共现进行聚类,这是一种无监督的方法。因此,它不需要训练,但需要参数τ作为距离阈值。

具体来说,对于基于密度的聚类方法,当阈值τ∈[0.85,0.95]足够大时,所有任务都有明确的分离。注意,τ的值不能太大(例如,设置τ = 1),因为后台过程可能会在随机位置产生日志项,从而将同一任务的日志项分开。

未完待续...

0 人点赞