找回密码
 会员注册
查看: 9|回复: 0

基于NLP的日志智能分析技术_UTF_8

[复制链接]

2万

主题

0

回帖

7万

积分

超级版主

积分
74102
发表于 2024-9-30 20:43:52 | 显示全部楼层 |阅读模式
背景动态监控 SDK 对于客户端上敏感权限 API (安卓端约79个,IOS端约50个)会进行调用的监控。对于不合规的调用会透过自定义异常将当下发生的端上信息记录成日志并回传 Slardar 落库。NvWa 平台致力于将这些报警日志以全自动化的方式做收集、处理、归因、消费。针对有合规疑虑的业务场景通知 POC、RD 整改,并记录其过程,达成完整的动态监控生产消费链,确保隐私合规安全。动态监控的音视频业务场景下,端上往往因为各种原因导致监控异常引发日志报警,例如:API 只调用一次导致未关闭音视频实例、业务代码 bug、线程关闭异常...等等。传统归因方法通过正则匹配、人工插入日志等方法能够对一部分异常进行归因,但是难以发现公共特征,导致大量报警数据无法消费,形成潜在风险。关键结论Highlights凭借模板提取技术以及AI模型,挖掘服务端&客户端日志中的语义、序列特征,根据已有业务数据,自动学习不同特征权重。能够克服日志数据量大、内容复杂的问题,准确、快速地完成异常事件的问题定位与归因工作。归因流程自动化,可处理大规模日志数据,不用担心放量大,数据处理不及时。通过模型完成问题筛选,提升问题解决效率,降低分析日志的人力成本。项目难点这里有两个关键的时间节点:event_start_time和crash_time,两个时间节点的概念如图:根据业务方提供的背景信息,在event_start_time之前两个小时到crash_time之后半个小时之间的日志,都可能存在关键信息,因此这个时间段(大于两个半小时)内的日志都将被用来进行分析,寻找归因。Alog 模板 可以看作 6 个子部分:[时间] [Process ID: Thread ID] [日志类型] [日志 tag] [文件资讯] 日志内容随机选取一起报警的部分ALog日志展示如下:从图中可以看出,端上记录的ALog包含多个tag,内容和形式十分复杂,此外,根据统计,ALog量级非常,根据业务方的要求,选取两个半小时以上时间跨度来讲,一般日志数量会达到几万条甚至更多,这为模型分析带来极大困难。效果展示与结论模型名称特征模型结构准确率model_11仅采用监控sdk记录的日志进行归因,不使用业务方日志,通用性大大提升75%model_10强相关&弱相关tag模板和变量,分别用0-1处理,拼接成log feature84%model_9强相关tag的模板和变量,分别用0-1处理,拼接成log feature,每个tag使用一个lstm模型处理输入序列输出后做拼接,通过两层linear层得到输出71%model_8全量强相关tag的模板和变量,分别用0-1处理,拼接成log feature每个tag使用一个lstm模型处理输入序列输出后做拼接,通过两层linear层得到输出65%model_73种tag的模板和变量,分别用0-1处理,拼接成log feature每个tag使用一个lstm模型处理输入序列输出后做拼接,通过两层linear层得到输出58%model_61种tag的模板和变量,分别用0-1处理,拼接成log feature使用一个lstm模型处理输入序列输出后做拼接,通过两层linear层得到输出52%model_5全量tag的模板,采用0-1处理,作为log feature每个tag使用一个lstm模型处理输入序列输出后做拼接,通过两层linear层得到输出38%model_43种tag的模板,采用0-1处理,作为log feature每个tag使用一个lstm模型处理输入序列输出后做拼接,通过两层linear层得到输出51%model_31种tag的模板和变量,分别用0-1处理,求和形成统计特征xgboost51%model_21种tag的模板和变量,分别用0-1处理,求和形成统计特征,随后与extra_info特征拼接xgboost57%model_1使用event_start_time到crash_time之间2500条日志,长度截取为20,使用预训练的word2vec词向量进行嵌入Deep log模型57%归因模型的部分实验效果如表中所示,从实验结果中能够看出,基于模板构建特征的模型能够取得比较明显的效果提升。通过在tag数量以及variable数量的不同尝试,能够很明显的看出,tag数量的增加能够帮助模型更好的进行归因,而不添加variable的几组实验效果很差,表明variable直接决定了构建的特征能否体现原log数据的关键信息。此外,从model_1的效果中能够看出,对于数量级过大的日志预料,使用传统NLP方法从词向量级别特征开始处理的建模方式效果极差,无法达到归因目的。到目前为止,采用业务方强相关&弱相关tag,通过10次交叉验证取平均效果,平均准确率能够达到84%。总的来说,通过采用基于模板提取的特征构建思路,我们能够极大的降低数据噪声、提升数据可用性,并基于相关序列模型在预测归因方面取得比较明显的效果提升。接下来我们将从模板质量、变量质量、更多tag引入、数据量扩充以及更多序列模型引入等方面,进一步优化模型,取得更好的归因效果。传统算法尝试我们首先尝试使用传统的NLP分类模型进行归因,分别构建了DeepLog模型和fasttext模型。DeepLog由于本次分析使用的数据结构较为特殊,每起报警的日志数量非常多,难以直接将日志文本输入模型进行分析。为此,重新设计了深度学习模型,介绍如下:日志级别编码使用bi-LSTM+attention结构,构造日志级别的编码器,模型将每条日志作为输入,结合注意力机制,将每条日志编码成向量。报警级别编码对于一起报警,在获得其全部日志的编码后,现在需要将这些日志向量进行融合,得到一个能够包含本次报警信息的报警向量。此处我们采用textCNN结构,使用一位卷积,并结合(2,3,4,5)四种卷积核对日志向量进行卷积,目的是为了获取相邻log间的局部关系,随后通过最大池化处理与向量拼接,得到每起报警的报警向量。输出层得到报警向量后,经过两层线性层,结合dropout和激活函数,最终得到每个标签的分数,完成预测。结构示意图基本参数(业务相关)日志平均长度:20每起报警的日志数量:首先采用android_event_start_time前后各1250条的方式(大概能覆盖2s左右),随后跟业务方同学沟通后,采用android_event_start_time到crash_time之间的日志,选取前2500条,但是对结果影响不大。效果&分析测试集准确率:57%模型效果很差,原因分析如下:每条数据的日志量太多,经过统计,业务同学反馈的有效时间段即android_event_start_time到crash_time之间的日志,平均时长为为90s,包含的日志数量可能有几万条,我们在处理模型时极大的收缩了日志量,但仍达到几千条的级别。这些日志量太大,噪声过多,使得模型很难直接关注到有效信息,此外,由于日志量级的问题,我们被迫设计了上述二级编码的模型结构,这也使得有效信息很容易丢失。为此,本周提出构建alog有效性模型的思路,见下文。每起报警的问题日志出现范围不明确,目前选用android_event_start_time到crash_time之间的日志,根据业务方同学反馈,这两个时间点前后的日志同样可能存在有效信息,此外,模型的输入形状必须是固定的,例如,每条数据的输入日志数量必须为5000条,多了的要砍掉,不够的要补全,而在实际场景中,有些报警的相关日志数量只有一两千条,而有些则达到上万条。fasttext除了二级编码的深度学习模型,我们还基于简单的词袋模型构建了分析模型,使用了传统的fasttext算法。具体来说,我们采用android_event_start_time到crash_time之间的日志,选取前5000条进行训练。训练结果如下:可以看出,模型的结果依旧较差,低于deep log模型,原因与deep log一致。模板提取日志数据特点与常规自然语言数据完全非结构化不同,日志数据最大的特点在于半结构化。每条日志都有一部分固定内容,以及一部分在程序运行过程中实时产生的变化内容。换一种解释方法,我们在代码中记录日志时,logger.info("something happens, value=%v", v),这段代码中研发同学事先写好的“something happens, value=”就是固定的内容,而v则是根据程序的运行状态,实时生成的变化的内容。我们将日志中固定的内容称为模板(template),将实时产生的变化的内容成为变量(variable)。com.ss.android.ugc.aweme.main.MainActivity@e643b52 onResumed hashcode=241449810com.ss.android.ugc.aweme.main.MainActivity@e643b52 onActivitySaveInstanceState hashcode=241449810com.ss.android.ugc.aweme.shortvideo.ui.VideoRecordNewActivity@43b173c onDestroyed hashcode=70981436com.ss.android.ugc.aweme.shortvideo.ui.VideoRecordNewActivity@43b173c onResumed hashcode=70981436com.ss.android.ugc.aweme.main.MainActivity@e643b52 onResumed hashcode=241449810com.ss.android.ugc.aweme.shortvideo.ui.VideoRecordNewActivity@43b173c onStopped hashcode=70981436com.ss.android.ugc.aweme.shortvideo.ui.VideoRecordNewActivity@43b173c onCreated hashcode=70981436com.ss.android.ugc.aweme.main.MainActivity@e643b52 onStopped hashcode=241449810com.ss.android.ugc.aweme.main.MainActivity@e643b52 onPaused hashcode=241449810com.ss.android.ugc.aweme.shortvideo.ui.VideoRecordNewActivity@43b173c onPaused hashcode=70981436com.ss.android.ugc.aweme.main.MainActivity@e643b52 onStarted hashcode=241449810com.ss.android.ugc.aweme.shortvideo.ui.VideoRecordNewActivity@43b173c onStarted hashcode=70981436com.ss.android.ugc.aweme.main.MainActivity@e643b52onPausedhashcode=241449810模板提取算法原理与示例经过大量实验和结果比对,我们采用SPELL算法作为最终的模板提取算法。该算法通过寻找不同日志之间的最长公共子序列(LCS),确定日志的模板和变量。com.ss.android.ugc.aweme.main.Activity1 onStarted hashcode=111com.ss.android.ugc.aweme.main.Activity2 onStarted hashcode=222例如对于以上两条日志,SPELL算法提取出的模板为* onStarted hascode=*,模板中的两个 *则分别代表activity变量和hashcode变量。SPELL基于LCS(longest common subsequence)算法构建的日志模板提取算法Basic workflow每个log entry e进入系统时,为其分配一个lineId,并讲起分词为一个token序列。随后,构造LCS Object结构保存当前处理的LCS 序列。每个LCS Object中包括一个LSC Seq和一个lineId列表,列表中是包含这个LSC Seq的log entry的lineId。最终,将所有LCS Object保存到一个LCS Map结构中。当有新log到来时,将其与LCS Map中所有的LCS Object比较,要么将其line id加入到某一个LCS Object的lineId列表中,要么构造一个新的LCS Object。当一个新log s到来时,将其与现有的所有LSC Object做比较,分别记录LCS(qi, s)的长度li,最终,记录最大的li以及相关联的LCS Object,如果该长度大于|s| / 2,则认为s与该LCS Object拥有共同的log message type。随后,使用backtracking生成一个新的LCS seq,代表这个LCS Object中所有log的message type。在做backtracking时,当两个序列不同时,用*代替,作为parameter的占位符,如果有连续的*出现,则合并为一个,源码中似乎没有实现这一点。如果现有的LCS Object中没有能够超过1/2长度的,那么新建一个LCS Object并将LCS Seq设为s本身。性能到目前为止,当一个新的log到来时,设定log平均长度为n,现有的LCS Seq数量为m,则复杂度为O(m·n·n)。考虑到绝大多数log到来时,其message type已经存在,本文采用了一个pre-filter方法,替代与所有LCS Object比较。Simple loop approach: 双指针法,依次比较token,相同则两个指针共进一步,否则只前进一个Prefix tree approach:通过前缀树,将所有候选str加入到一棵树中,能够实现大量的剪枝,这种情况最优复杂度为O(n)但是这种算法不能保证返回的一定是最大长度,例如新来的log是DAPBC,strs = {DA, ABC},但是在实际情况中,这种影响不大,因为parameter一般出现在log的尾部。最终,SPELL的pre filter方法是,对于一个新来的log e,首先使用prefix tree找到message type,如果没找到,则使用simple loop lookup。经过论文中的性能证明,结合实际数据中的分析,最终的实际性能为O(n)。如何使用模板构建特征首先通过一些人工构造的简单日志,展示如何使用模板做特征构建。如表中所示,我们构造了两个tag的部分日志,示范如何进行特征构建。对于每个tag,我们分别统计该tag中所有模板数量和变量数量,并基于统计情况构造0-1向量。随后,对每条日志,根据日志所属模板及包含的变量情况,将向量对应位置置为1,并将两部分向量拼接,得到日志的特征向量。为何要提取模板向量形式基于传统词向量构建特征日志特征向量形状为1 * len * embed_dim,其中len是每条日志的长度,embed_dim为预训练得到的词向量维度基于模板构建特征日志特征向量形状为1 * n,即n维0-1向量,n由tag中的模板和变量情况决定数据层面现有的词向量算法难以准确体现不同词汇的准确含义,存在信息损失对日志中的关键变量,词向量算法能否准确表达,尤其是对一些数值型、方法型变量,如果表达不准确对结果影响很大总结,能用0-1向量准确表示的东西,没必要使用上百维的向量加模型编码层去表示模型层面基于传统词向量构建特征模型需要两层编码器,第一层处理每条日志的词序列,得到log-level vector,此时由于上述原因,已经存在部分信息缺失;随后第二层编码器对连续的日志序列进行编码,得到event-level vector,完成预测基于模板构建特征模型可以直接得到准确的log-level feature,因此只需要一层编码直接处理日志序列,得到event-level vector完成最终预测即可,极大的降低了信息损失为何要区分tag提取模板ALog的模板提取从最初的统一提取到后来的分tag提取主要出于以下几点:ALog中的日志分为很多tag,每个tag的内容形式各不相同,最初对所有日志混在一起做模板提取,由于日志内容形式太复杂,模板种类过多,导致效果差,难以优化;经过业务方同学讲解,发现相同tag中的日志表达内容和表达形式都十分接近,此外,业务方同学归因时,也会分别针对不同的tag分别去做分析,而不是混在一起,因此对不同tag分别提取,分别构建特征,即能提升模板质量,也与人工归因思路保持了一致;通过业务方同学对tag进行人工标注,发现有一部分tag是可以被标成与归因不相关的,通过删掉这部分tag,进一步减少了无关噪声;通过tag划分日志分别处理后,使得对提取算法的优化变得可能,这里提到的优化方法主要包括以下两方面:数据清洗:按照tag划分后,能够对每个tag的日志实现针对性的清洗、排序等预处理工作,极大提升模板质量;算法参数:同一批日志,采用不同的算法参数,提取效果也完全不同,这主要是一个泛化能力的体现。按照tag划分之前,日志过于杂乱,很难找到一种参数组合能够适应所有日志,而划分之后,由于日志种类少了很多,使得这种优化得以实现。模板提取结果展示&提升空间日志提取的相关结论以及每个tag的一些配置细节则体现在代码中,在此不进行展示。通过与业务方同学对模板提取结果的观察与比对,主观判断质量有很大提升,由于量化的评估需要很高的人力标注成本,因此暂时没有相关效果指标,最终模板质量还是要靠归因效果体现。在模板优化方面,仍然存在一些日志由于内容杂乱等原因,难以实现优化,这部分之后可以更多依赖人工进行校正。归因算法特征构建对于一起报警(event),特征构建方法如下,对每个tag下的所有日志构建特征(见上文),随后对tag中的日志序列做补全(99分位数,本次为500),即得到该起报警的初始特征:n个形状为500*的vector,其中n代表tag数量,代表第i个tag中的特征向量维度。建模方法对一起进行特征构建后,相当于得到了n个tag的日志序列,由于日志出现的先后顺序显然是有着重要意义的,因此我们需要对其按照序列进行建模,以下使用的统计建模方式,仅作为baseline进行比较。统计我们将报警中所有log-level vector相加后求平均,作为该报警的统计特征,随后使用xgboost模型进行训练,并得到预测结果。序列序列建模是我们的重点,目前仅使用LSTM模型完成了基本的建模和预测,接下来会尝试更多时序模型(参考优化方案)。LSTM由于每个tag的特征维度不一致,我们为报警中的每个tag分别设置了一个LSTM模型用于处理该tag下的日志序列,在得到输出后,直接将所有输出进行拼接,通过全连接层得到预测结果,如图:业务实践该项目目前与nvwa业务合作,帮助对客户端发生的异常报警进行智能归因。具体来说,当nvwa将端上发生的异常报警全部存入消息队列,归因模块从队列中消费异常报警信息,自动化完成日志下载、数据清洗与特征构建、模型预测等全部归因流程,随后将以RPC形式将归因标签及置信度分数等结果信息通知到nvwa业务方,并将相关日志数据、中间特征向量等进行保存,便于之后模型的优化与无监督聚类。目前服务已经上线,效果持续验证中。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-14 04:03 , Processed in 0.508840 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表