基于模板频率或模板顺序建模,选择决定能检测到的故障类型;会话分组和时间窗口分组各有适用场景,组合使用效果更佳。
问题的形态
原始日志行并不是一个特征向量。将它们转换为特征向量的流水线包含三个阶段,跳过任何一个阶段都是通用异常评分在日志上表现不佳的原因。首先,模板提取为每一行分配一个 ID。其次,分组将行收集为你要评分的单元——可以是固定时间窗口、滑动窗口,或者按照块 ID、请求 ID 或追踪 ID 等标识符键控的会话。第三,编码将每个组转换为模板 ID 上的计数向量或有序序列。
分组的选择并非细节问题。会话分组检测单个对象生命周期中的故障;时间分组检测系统行为中的故障。一个本应复制三次却只复制了两次的块,在繁忙集群的每分钟计数中是不可见的,但在逐块会话中却显而易见。集群范围的延迟回归则相反。大多数生产系统两者都需要,用不同的键并行运行。
计数向量与 PCA 方法
计数向量编码为每个组赋予一个长度等于已知模板数量的向量,记录每个模板触发的次数。假设分布式文件系统中一个健康块会话如下:
templates T1 T2 T3 T4 T5 (allocate, receive,
healthy session 1 3 3 1 0 packet-ack, delete, exception)
degraded session 1 2 2 1 0
error session 1 3 3 0 2
降级会话是其中有趣的那个。它里面没有任何错误——没有模板不该触发却触发了——但 T1 和 T2 之间的比例从 1:3 变为 1:2,对于复制因子为三的系统来说,这意味着一个副本未能落地。阈值计数看不到这一点。但一个计数间相关性的模型可以。
这正是 Wei Xu 及其同事在 SOSP 2009 年发表的"Detecting Large-Scale System Problems by Mining Console Logs"中的方法。将 PCA 拟合到正常会话的计数向量上,保留前 k 个分量作为"正常子空间",然后通过投影后残差的平方长度来评分新会话——即正常子空间无法解释的向量部分。计数遵循通常比例的会话无论其绝对大小如何都有小的残差;违反比例的会话则不然。投影步骤的一般性处理在主成分分析中,更广泛的家族在异常检测中有涉及。
需要做对的两件事是 k 的选择和归一化。跨模板的计数相差数个数量级——心跳在每个会话中触发数千次,关机只触发一次——所以未归一化的 PCA 建模心跳而忽略其他。词频加权,或者简单地log缩放计数,才能使稀有模板在拟合中可见。
计数向量丢弃了顺序,而顺序携带真实信息:一个在写入之前就关闭文件的会话是异常的,即使其计数与健康会话完全相同。序列方法将模板 ID 流视为一种语言,并从之前的 h 学习预测下一个 ID。DeepLog 由 Min Du、Feifei Li、Guineng Zheng 和 Vivek Srikumar 在 CCS 2017 年发表("DeepLog: Anomaly Detection and Diagnosis from System Logs through Deep Learning"),它使用 LSTM 并应用了一条值得精确陈述的规则:模型输出下一个模板 ID 上的概率分布,如果观察到的 ID 不在 top g 最可能的候选中,则被标记为异常。
这条 top-g 规则是整个调优表面。小的 g 意味着高召回率,而假阳性率跟踪日志中包含的合法并发量;大的 g 意味着几乎没有什么会被标记。并发点值得强调:在多线程服务中,交织意味着"正确的"下一个 ID 实际上是非确定性的,而在交织流上训练的序列模型同时在学习调度器以及程序。序列模型在逐实体会话上效果最好,因为交织已经被键控撤销了。
一阶马尔可夫链在模板 ID 上以一小部分成本获得了相同收益的惊人部分,而且它是可检查的——你可以读取转移矩阵并看到哪个转移是 improbable。同样的构建应用于用户行为在点击流序列建模中有详细阐述。
在没有标签的情况下评估
你几乎没有带标签的异常。你拥有的是一个你认为健康的时期和少数已知的事件。这种不对称性决定了评估方式。
在健康时期训练,并留出一个较晚的健康时期作为保留集。保留健康数据上的告警率就是你的假阳性率,这是决定任何人是否保持检测器开启的数字。如果一个评分一分钟窗口的检测器有 1% 的告警率,那就是每天每条流 14 次告警,这不是检测器,这是寻呼机疲劳制造机。从 on-call 人员能容忍的量反推——每周几次——然后在那里设置阈值,然后问在已知事件上召回率还剩多少。如果答案是"没有",那说明编码是错的,而不是阈值。
稀有正类的精确率由基本率而非模型主导,这在安全事件日志异常检测中有数字推导。一般的指标定义在分类指标中。
生产环境中失败的四种方式
模板集不是平稳的。每次部署都可能添加、删除或更改日志语句的措辞。输入维度为"已知模板数量"的模型必须处理在运行时出现的维度,通常的答案——保留一个"未见过模板"桶并将其峰值作为自己的信号——比在恐慌中重新训练要好。
音量变化与行为变化相混淆。计数随流量伸缩。除非编码按组大小或请求数归一化,否则营销活动和重试风暴看起来是一样的。
健康训练窗口包含了问题。缓慢降级被学习为正常。这是一种让人不信任整个方法的失败,唯一防御是定期用更早时期拟合的模型对训练窗口进行评分。
沉默才是异常。最严重的事件通常会减少日志量:本来会记录的那个组件已死亡,或者日志发送器才是坏了的东西。只对到达的内容评分的检测器看不到缺席。将其与每个源的明确心跳期望配对,这是整个领域中最便宜的高价值检测器,几乎从来不是人们第一个构建的。

Detecting Anomalous Patterns in Security Event Logs
Detecting a Burst of Events in a Stream