摘要
日志在软件系统的开发和维护过程中被广泛使用,收集运行时事件并允许跟踪代码执行,从而支持各种关键任务,如故障排除和故障检测。大型软件系统会生成大量的半结构化日志记录,这对自动化分析提出了重大挑战。将带有自由形式文本日志消息的半结构化记录解析为结构化模板是支持进一步分析至关重要的一步。现有的方法依赖于特定于日志的启发式方法或手动规则提取,通常专门用于解析某些日志类型,因此限制了性能分数和泛化。
本文提出了一种新的解析技术,NuLog,利用自监督学习模型,并将解析任务描述为屏蔽语言建模(MLM)。在解析过程中,该模型以向量嵌入的形式从日志中提取摘要。将MLM作为预训练与下游异常检测任务耦合。
在10个真实日志数据集上评估了NuLog的解析性能,并将结果与12种解析技术进行了比较,NuLog的解析精度平均可达99%,且与真实值模板的编辑距离最小。通过两个案例研究,验证了该方法在有监督和无监督情况下对基于日志的异常检测的能力。结果表明,NuLog可以成功地用于支持故障排除任务。
介绍
当前的IT系统是复杂的多层软件和硬件的组合。它们使应用程序的复杂性和系统多样性不断增加,其中使用了许多技术,如物联网(IoT)、分布式处理框架、数据库和操作系统。系统的复杂性和多样性导致运营商的管理和维护费用很高他们不再足以全面地操作和管理这些系统。因此,服务提供商正在部署各种措施,为IT生态系统引入额外的异常检测、错误分析和恢复人工智能解决方案。这些数据驱动的故障排除解决方案的基础是提供描述系统状态的数据。各种各样的技术导致不同的数据,迫使所开发的方法在不同的应用程序、操作系统或云基础设施管理工具上很好地泛化。一个特定的数据源(日志)通常用于检查IT系统的行为。它们表示数据、文件、服务或应用程序之间的交互,通常由开发人员、DevOps团队和AI方法来理解系统行为,以检测、定位和解决可能出现的问题。理解日志信息及其用于进一步自动化分析的第一步是解析它们。日志记录的内容是由软件开发人员编写的非结构化的自由文本,这使得它难以结构化。它是常量字符串模板和变量值的组合。模板是生成日志消息的日志记录指令(例如print(), log.info())。记录特定的系统事件。
日志解析器的一般目标是将非结构化的自由文本转换为结构化的日志模板和相关的变量列表。例如,模板“试图声明:内存(*)MB,磁盘(*)GB, vcpu (*) CPU”与变量列表["2048","20,"1"]相关联。这里,(*)表示每个变量的位置,并与列表中值的位置相关联。如果模板不包含变量部分,变量列表可以为空。
传统的日志解析技术依赖于正则表达式。由不同的软件和硬件组件组成的大型系统使维护这种手工工作变得复杂。频繁的软件更新需要不断地检查和调整这些语句,这是一项乏味且容易出错的任务。相关的日志解析方法依赖于解析树、启发式和领域知识。要么专门用于处理来自特定系统的日志,要么可以使用种类不多的独特模板可靠地解析数据。在各种不同的系统上分析现有日志解析方法的性能,可以发现它们缺乏产生一致的良好解析结果的健壮性。这意味着需要为手头的应用程序或系统选择一种解析方法,并结合领域特定的知识。大型IT基础设施的运营商最终将不得不为其组件管理不同的解析方法,其中每一种方法都需要得到相应的理解。日志解析方法必须准确地处理来自各种系统的日志数据,从移动操作系统上的单个应用程序到最少人工干预的云基础设施管理平台。
贡献
本文提出了一种自监督的日志解析方法NuLog,利用transformer架构,是一种无监督学习,其中部分数据提供监督。为了构建模型,学习任务的表述是这样的:日志消息中某个单词在特定位置上的存在取决于它的上下文。解析的关键是正确预测掩码词意味着该词是日志模板的一部分,否则是日志的一个参数。
这样可以产生日志模板和数值向量总结,而不需要领域知识。该模型是稳健的,并在不同的数据集泛化良好。有监督的和无监督的,以及模型与下游任务(如异常检测)耦合和微调,在日志解析阶段的屏蔽语言建模中获得的知识作为下游任务的良好先验知识是有用的。
相关工作
自动日志解析非常重要,其与软件系统的维护和故障排除有实际关联。在工业界和学术界已经发表了大量关于自动日志解析方法的研究和开发。解析技术可以从技术、操作方式、预处理等方面进行区分。
聚类
假设是消息类型在相似的组中重合。采用了各种具有适当字符串匹配距离的聚类方法。LKE使用加权编辑距离和层次聚类来进行日志键提取,并使用组分割策略来微调获得的日志组。
LogSig是一种基于消息签名的算法,它搜索最具代表性的消息签名,大量利用领域知识来确定集群的数量。
SHISO正在使用从日志消息生成的节点创建一个结构化的树,当与先前存在的日志模板匹配失败时,可以实时更新日志消息。
LenMa利用了一种基于日志中出现的单词长度序列的聚类方法。
LogMine 创建日志模板层次结构,允许用户选择感兴趣的描述级别。
频繁模式挖掘
假设消息类型是一组频繁出现在整个日志中的令牌。这些过程包括创建频繁集、对日志消息进行分组和提取消息类型。这一组的代表性解析器是SLCT、LFA和LogCluster。
进化
MoLFI使用一种进化的方法来寻找帕累托最优的消息模板集。
对数结构启发式方法
在不同采用的技术中产生了最好的结果。它们通常利用来自日志结构的不同属性。最先进的Drain假设在日志的开头,单词没有太大的变化。它使用这个假设来创建一个固定深度的树,可以很容易地针对新的组进行修改。该组中的其他解析方法是IPLoM和AEL
最长公共子序列
使用最长公共子序列算法从传入的日志中动态提取日志模式。这里最具代表性的解析器是spell。
本文方法涉及到日志解析方法分类中的一个新的神经类别。与目前最先进的基于启发式的方法不同,不需要任何领域知识。结果表明该模型是稳健的,适用于不同系统的一系列日志类型。
神经网络日志解析
3.1 预备知识
将日志定义为时序有序的非结构化文本消息序列L= (L: i = 1,2,…),每条记录由软件源代码中的日志记录指令生成,i为序列中的位置索引。日志消息由一个常量和一个可选的可变部分组成,分别称为日志模板和变量。
将日志模板和变量定义为元组EV = ((e,v): e ∈ E, i = 1,2,…),e是所有日志事件模板的有限集,K=|E|是所有唯一模板的数量,v是分别关联模板的变量列表。通过位置索引i与原始日志消息相关联。
日志消息中最小的不可分割的单例对象是令牌(token)。每个日志消息由一个有界的标记序列组成,ti = (tj: t∈T,j=1,2,..,|ti|),T是所有令牌的集合,j是某个令牌在日志消息li中的位置索引,|ti|是l中令牌的总数,对于不同的l, |ti|可以不同。根据具体的标记方法,t可以是单词、单词块或字符。
标记定义为一个变换函数T: li→ti, Vi。在本文提出的日志解析方法中,引入了上下文和嵌入向量的概念。给定一个标记t,它的上下文由前面和后面的标记序列定义,即序列元组:C(tj) = ((ta,ta+1,…,tj-1), (tj+1, tj+2, .,tb)),其中a <j < b。嵌入向量是标记或日志消息的d维实值向量表示s∈Rd。本文方法建立了一个需求和一个属性:
需求1:给定一个时间有序的日志消息序列L,由一个未知的不同日志模板集E生成,日志解析方法提供映射函数fi:L→EV。
属性1:日志模板提取器的理想特性。将每个日志模板映射到一个有限的值集,受唯一日志模板数量的限制,但允许日志的向量表示,为处理各种下游任务提供了可能性。
生成的向量表示应该是属于相同日志模板的日志消息的较近嵌入向量和属于不同日志模板的日志消息的较远嵌入向量。例如,“花了10秒创建一个虚拟机”和“花了9秒创建一个虚拟机”的嵌入向量应该有一个小的距离,而“花了9秒创建一个虚拟机”和“失败创建虚拟机3”的嵌入向量应该有一个遥远的距离。该方法的目标是模拟操作员对日志的理解。对于识别日志中所有事件模板的任务,合理的方法是密切关注经常出现的部分,忽略在特定上下文中频繁更改的部分(例如,每个日志消息)。这可以被建模为每个标记的概率分布,即P(t;IC(t;))。这样的概率分布可以区分常数和变化符号。
生成日志嵌入向量自然可在下游任务中进行微调。此外,这种表示是通过关注日志消息的常量部分获得的,更可预测,为属性1提供了必要的泛化。
3.2 NuLog:使用transformer的自注意神经解析
NuLog由预处理、建模和模板提取三部分组成。
总体架构如下图,日志预处理器将日志消息转换为适合模型的格式。分为:标记和掩蔽。在执行标记前,将剥离来自日志框架的元信息,并将有效负载(即print语句)用作标记步骤的输入。
标记,将每个日志消息转换为标记序列。使用简单的基于过滤器的分割准则来执行字符串分割操作。下图描述了日志消息“Deleting instance /var/lib/nova/instances/4b2ab87e23b4de”的标记化。如果分割条件匹配空格,则日志消息被标记为三个标记的列表["Deleting", "instance", "/var/lib/nova/instances/4b2ab87e23b4de"],不使用正则表达式来解析任何参数。正则容易出错,且要手动调整,甚至需要在同一系统中更新。
掩蔽,通过分析日志数据中出现的标记学习日志数据的一般语义表示,即上下文。使用自然语言(NLP)研究中的通用方法,MLM。
屏蔽模块将标记步骤的输出作为输入,即日志消息的标记序列。从序列中随机选择一个令牌并用特殊< MASK >令牌替换。掩码令牌序列用作模型的输入,而掩码令牌用作预测目标。为了表示日志消息的开始和结束,添加特殊<CLS>,使用<SPEC>填充。每条日志消息的填充令牌数量由M - |ti|给出,其中M = max(|ti|) + 1, 是日志数据集中所有日志消息中的最大令牌数量,|ti|是第i条日志中的令牌数量,添加的令牌将确保每个日志消息至少由一个<SPEC>填充。
模型,有离线和在线两种操作模式。离线阶段,使用日志消息通过反向传播优化所有模型参数,并选择最优超参数。在线阶段,每个日志都通过模型向前传递。为每个日志生成各自的日志模板和嵌入向量。
完整架构如下图;该模型对输入令牌向量应用了两个操作:令牌向量化和位置编码。随后的编码器结构将结果作为输入。由两部分组成:自注意力层和前馈层。最后一个模型组件是softmax层。
由于模型输入为数值型,将标记转为随机初始化的数值向量x∈Rd。向量被称为标记嵌入,是训练过程的一部分,训练期间被调整,表示标记的语义,取决于上下文。这些数字标记嵌入被传递给位置编码块。与循环结构相反,基于注意力的模型不包含任何输入顺序的概念。因此需要显式地对该信息进行编码,并与输入向量合并,以考虑它们在日志消息中的位置。获得位置向量p∈Rd,表示基于正弦和余弦函数的标记的相对位置。
k = 0,1,…, d - 1为p中各元素的下标,j = 0,1,…, M是每个令牌的位置索引。参数k描述了向量p的每个值之间的指数关系。正弦和余弦函数可互换应用。这两个函数都允许在特定的p向量内更好地区分各自的值。两个函数都对位置参数j有近似线性依赖,假设这是为了使模型更容易关注各自的位置。两个向量可以合并为x' = x+ p。
模型的编码器从一个多头注意力元素开始,计算了令牌嵌入最大分布。描述了每个嵌入向量对于目标屏蔽令牌预测的重要性。将所有标记嵌入向量总结为矩阵X'的行,并应用以下公式
L为注意力头数,w = d/L, d mod L= 0。参数Q、K、V为矩阵,分别对应图3中的查询元素、键元素、值元素,由输入X'与对应的可学习权重矩阵WQ、WK、WY进行矩阵相乘得到:
其中WQ, WK, WY。除以√w可以在训练过程中稳定梯度,应用softmax函数,缩放每个令牌嵌入向量:X = X×Z。将缩放后的矩阵X连接到大小为M X d的单个矩阵X"。如图3所示,输入令牌矩阵X'与其对应的注意力转换X"之间存在残差连接,后面是归一化层范数。通过解决学习过程中遇到的不同潜在问题,如小梯度和协变量移位现象,来提高模型的性能。在此基础上,原始输入由注意力转换的等效值更新为X' =范数(X' + X")。
编码器的最后一个元素由两个前馈线性层组成,中间有一个ReLU激活。它单独应用于X'的每一行。对每一行都使用相同的权重,这可以被描述为对每个核大小为1的注意转换矩阵行进行卷积。此步骤可作为嵌入的额外信息丰富。同样,在输入矩阵和两个层的输出之间使用了一个剩余连接,然后是一个归一化层。这个模型元素保留了维度X'。
模型的最后一个元素由一个单一的线性层组成。接收编码器结果X'并提取<CLS>令牌的令牌嵌入向量。由于每个日志消息令牌序列都是由这个特殊令牌预填充的,因此它是矩阵的第一行。线性层将大小为d的向量映射到一个大小对应于数据集中令牌总数[T]的向量。softmax用于计算t的每个元素的概率分布。
在训练中,将掩码令牌作为要预测的目标。由于<CLS>令牌的最后一个向量嵌入用于预测,其汇总日志消息。否则,它将无法在所有令牌之间很好地解决掩码令牌预测任务。
假设当日志消息属于同一模板时,日志模板的常量部分将约束模型学习相似的<CLS>令牌嵌入。日志消息映射到的向量表示,可用于不同的下游任务,如异常检测。这个日志消息嵌入向量满足提出的属性1。
3.3日志模板提取
模型训练后,在线执行日志数据集中所有日志模板的提取。将每个日志消息作为输入传递,并配置屏蔽模块,使每个令牌都连续屏蔽,一次一个。衡量模型预测每个令牌的能力,决定令牌是常数还是变量。
令牌预测的高置信度表示模板的常量部分,而小置信度被解释为变量。
如果一个特定token的预测在前e个预测中,认为它是模板常量部分的一部分,否则是一个变量。对于所有变量用<*>替代。
结论
为解决日志解析问题,采用掩码词预测学习任务。让单词出现在日志条目的固定位置意味着它们的正确预测直接生成日志消息类型。不正确的令牌预测反映了日志的各个部分及其参数。该方法还生成日志消息上下文的数值表示,主要用于解析。这使得模型可以在下游任务(如异常检测)中使用。
为了评估NuLog的有效性,在10个真实的日志数据集上进行了实验,并与12个日志解析器进行了评估。通过添加新的度量来增强评估协议,以证明生成的模板和真实日志消息类型的偏移量。实验结果表明,NuLog在精度、编辑距离和鲁棒性方面都优于现有的日志解析器。
对现实世界中有监督和无监督异常检测任务进行了案例研究。结果表明,在有监督和无监督场景下,该模型和屏蔽语言建模过程中学习到的表示方法都有利于区分正常和异常日志。本文方法表明,日志解析可以用深度语言建模来执行。这意味着在日志解析和异常检测方面的未来研究应该更多地集中在跨领域的泛化、知识的转移和有意义的日志表示的学习上,这些可以进一步改进对IT系统操作至关重要的故障排除任务。
参考:
[2003.07905] Self-Supervised Log Parsing (arxiv.org)
GitHub - nulog/nulog: "Self-supervised Log Parsing" submitted for review at ECML-PKDD 2020