原理概述
文本分析作业对日志中指定的文本字段进行聚类,每个日志类别由特定的日志模板标识,日志类别中所有日志的文本结构都与相应的日志模板相似。文本分析作业连续监控每个时间窗口中的日志聚类情况,检测是否有新的或者罕见的日志类别、日志类别中的日志数量是否异常变化。文本分析作业将这些异常事件汇总,并分析每个时间窗口中日志整体的健康状态。所有这些分析结果以报表的形式呈现,我们可以选择查看不同时间段中日志的状态。
算法配置
下面我们以 K8S 运行日志为例介绍如何配置文本分析作业,K8S 运行日志样例如下
{
"eventId": {
"metadata": {
"name": "fxs8k4kpprzxfm7.16c9b3e37060acb6",
"namespace": "default",
"selfLink": "/api/v1/namespaces/default/events/fxs8k4kpprzxfm7.16c9b3e37060acb6",
"uid": "5e9a03f8-7f67-4fbd-8e5a-3e5a2ac979fd",
"resourceVersion": "143303381",
"creationTimestamp": "2022-01-13T02:35:28Z"
},
"involvedObject": {
"kind": "Pod",
"namespace": "default",
"name": "fxs8k4kpprzxfm7",
"uid": "f340de16-ff1f-4e25-910f-3b238e10d800",
"apiVersion": "v1",
"resourceVersion": "7779858489"
},
"reason": "FailedMount",
"message": "Unable to mount volumes for pod",
"source": {
"component": "kuberenetes-events-generator"
},
"firstTimestamp": "2022-01-13T02:35:28Z",
"lastTimestamp": "2022-01-13T02:35:28Z",
"count": 1,
"type": "Warning",
"eventTime": null,
"reportingComponent": "",
"reportingInstance": ""
},
"__time__": 1642041328,
"hostname": "",
"__topic__": "",
"__pack_meta__": "1|MTYzMjcwMzAzOTA0NjQ2NDA2NA==|7|6",
"level": "Warning",
"__source__": "",
"pod_id": "f340de16-ff1f-4e25-910f-3b238e10d800",
"pod_name": "fxs8k4kpprzxfm7"
}
数据特征配置
在数据特征配置中,我们需要配置日志实体字段、日志文本字段和日志等级字段。
在同一个 Logstore 中可能包含不同来源产生的日志,比如 K8S 不同 namespace 中日志被采集到同一个 Logstore 中。不同 namespace 下往往部署着服务的不同模块或者不同服务,如果我们想要分析不同 namespace 中的日志情况,我们需要在日志实体字段配置的 namespace 字段帮助作业区分不同来源的日志。在日志中 namespace 在字段 "eventId.metadata.namespace" 中,我们可以从候选框中选择或者手动输入该字段
如果不同来源的日志无法通过一个字段进行区分,那么我们最多可以配置 2个日志实体字段,分析作业将根据实体字段值的不同组合区分不同来源的日志。如果不设置日志实体字段,分析作业认为所有日志来自同一个实体,不进行数据源的区分。
之后我们需要选择使用日志中的哪些字段进行聚类。由于分析作业使用文本聚类算法,进行聚类的日志字段最好是文本类型,如果是非文本类型,分析作业尝试将其转化成文本类型处理。在示例的 K8S 日志中,"eventId.reason" 和 "eventId.message" 这两个字段以文本形式反映了 K8S 的运行状态,我们选择这两个字段作为待分析字段。可以通过候选框选择或者手动输入在日志文本字段中进行配置。
分析作业在进行聚类时会将各个文本字段拼接处理。如果聚类时需要考虑更多字段,我们可以在日志文本字段中最多配置 5个字段。
最后我们可以配置日志中的日志等级字段,帮助分析作业感知日志的风险等级,在对日志进行异常检测时会同时考虑日志的风险等级,日志日志中没有日志等级字段,统一将日志等级设置为 unknown。在示例的 K8S 日志中 "level" 字段标识了日志的风险等级。
算法配置
在算法配置中我们需要设置算法运行的一般参数,目前文本分析算法只提供日志异常分析算法。文本分析作业以时间窗口为单位连续检测不同时间窗口中的日志状态。我们可以配置时间窗口长度,默认时间窗口长度为 900秒(15分钟)。分析作业会在当前时间窗口内的日志全部采集完成后再进行分析处理,可以根据自身对于实时性的要求选择不同的时间窗口长度。值得注意的是,需要保证当前时间窗口内日志的聚类分析可以在下一个时间窗口日志采集完成前完成,这样可以使分析作业的延迟收敛在一个时间窗口时长之内。目前分析作业每分钟可以处理 30万条日志数据,如果 Logstore 中日志的产生速度超过了 30w/min,分析作业可能会有较高的延迟,甚至延迟无法收敛。
分析作业在分析每个时间窗口日志的整体健康状态时会综合出现的异常事件的数量、异常事件的严重性等因素。少量的异常事件可能是由于系统的正常抖动产生的,而大量的异常事件才能更准确的反映系统的异常。因此我们可以配置异常总数阈值,当异常事件数量接近会超过该阈值时,分析作业会逐渐提高日志整体异常状态的严重性。异常总数阈值可以配置为绝对值,默认的阈值为 5;当无法确定多少个异常事件真正反映了系统异常,异常总数阈值也可以配置为相对值,可选值 0.1~0.5 之间的小数。
调度配置
我们可以在调度配置中选择分析从哪个时间开始的日志数据。分析任务处理完从开始时间到当前时间之间的日志、再到最终实时分析日志所需要的时间与日志的产生速率有关。如果每分钟产生的日志量在 1万以内,可以选择较早的开始时间;如果每分钟产生的日志量超过 10万,建议开始时间选择最近 3天以内。
高级配置
我们通过高级配置项进一步影响分析作业的运行行为,如果对于如果配置这些配置项还不确定,建议保留默认配置。高级配置项包括初始化窗口数量、最大静默窗口数、数据过滤配置和通识字段配置。
- 初始化窗口数量:默认值是 24,表示分析作业在开始运行后的 24个时间窗口内只进行算法模型的训练,不输出异常事件,在后续的时间窗口中使用训练的算法模型对日志数据进行分析处理(算法仍然会在后续的时间窗口中持续训练)。
- 最大静默窗口数:默认值是 672,表示如果一个日志类别出现后的 672个时间窗口内这个日志类别没有在此出现,那么将认为这个日志类别已经消失。之后如果再次遇到该日志类别,将会产生新日志类别异常。由于分析作业同时会检测罕见日志类别异常,同样也会对于这类低频出现的日志类别进行提示,因此我们可以设置较大的最大静默窗口数。
- 数据过滤配置:如果我们只对特对日志等级的日志感兴趣,那么可以针对日志等级配置白名单和黑名单,分析作业运行时只会处理满足过滤条件的日志。
- 通识字段配置:日志内容中的值可能满足特定的格式,比如时间、IP 和数字等等,我们可以针对这些特定的格式配置正则模板,分析作业运行时会使用正则模板(模板表达式)匹配日志内容,将满足模板的部分替换成统一的名称(模板名称)。默认提供 IP、日期、时间和数字的模板,可以根据日志内容的特定,配置其他正则模板。如果配置的模板太多,会影响分析作业的运行效率,建议总的模板数量在 5个以内。模板配置完成后可以通过下方的测试框进行测试,检查配置的正则模板是否符合预期。
上述的配置全部完成后,点击下方的 “完成” 按钮完成文本分析作业创建。
结果介绍
在文本分析作业创建完成后,我们可以通过 智能异常分析 APP -> 文本分析 -> 作业标识 进入创建的作业中,查看作业的分析结果。
结果页面的上半部分如下图所示
- A:选择不同的实体字段组合,查看不同 namespace 产生的日志分析结果,上图选择 default namespace
- B:显示在所选时间范围内异常分数最高的 10个日志类别
- C:可以点击选择不同的时间范围
- D:显示所选时间范围内每个时间窗口中日志数量的变化情况,以及数量异常变化时的异常分数
- E:显示所选时间范围内每个时间窗口中日志整体的异常情况,分数越高,异常情况越严重,分数在 0 ~ 1
- F:显示所选时间范围内每个时间窗口中每个日志类别的异常情况,分数越高,异常情况越严重,分数在 0 ~ 1
结果页面的下半部分如下图所示
其中显示在所选时间范围内所有的异常事件,包括异常事件涉及的日志类别、日志等级、异常类型、异常分数和异常出现的时间窗口。可以通过左上方的过滤框选择不同异常类型或者不同日志等级的异常事件。另外,可以点击上方 E, F 部分中的色块,异常事件列表会自动聚焦到色块所表示的时间窗口内的异常事件(如果点击 F 部分的色块,还会进一步聚焦到对应日志类别的异常事件)。
我们可以点击每个异常事件左侧的 “+” 查看异常详情,如下图所示
异常事件详情中显示了涉及的日志类别的模板、日志类别内的日志数量、日志样例,以及日志类别中日志数量在不同时间窗口中的变化情况,其中显示了日志类别 57 出现数量异常时的数量以及周围时间窗口的日志数量。
异常定位
通过日志异常色块图,我们发现在 "01-11 23:15" 时日志的整体健康状态较差,异常分数是 1。那么我们可以单击该色块,查看该时间窗口内出现的异常事件
异常事件显示如下
可以看到异常事件列表已经汇总了所有发生在选中时间窗口的异常事件。查看这些异常事件我们可以看到有大量的 warning 类型的日志类别出现数量异常,查看其中某个异常事件详情如下
根据日志模板可以看到异常似乎与 K8S ReplicaSet 资源创建失败有关,再通过与其他异常事件的日志模板相互印证,比如:
- Failed Error failed to start container sleep Error response from daemon OCI runtime create failed container_linux.go <NUM> starting container process caused process_linux.go <NUM> container init caused read init-p connection reset by peer unknown
- MinimumReplicasUnavailable Deployment does not have minimum availability.
- ProgressDeadlineExceeded Deployment mock has timed out progressing
通过分析这些事件我们可以知道日志整体异常可能是由于 ReplicaSet 在扩缩容时节点间网络连接失败导致的扩容失败造成的。这些事件有助于我们进一步定位 K8S 环境的异常。