如何分析 Datakit Bug Report¶
Bug Report 介绍¶
由于 Datakit 一般部署在用户环境,为了排查问题,需要获取各种现场数据,Bug Report(后面简称 BR) 就是用来收集这些信息,同时避免现场支持工程师或用户执行太多操作,降低沟通成本。
通过 BR,我们能获取各种 Datakit 在运行阶段的现场数据,按照 BR 下面的数据目录:
- basic:机器基本环境信息
- config:各种采集相关的配置
- data:中心的配置拉取情况
- external:主要是 eBPF 采集器有关的日志和 Profile 数据 Version-1.33.0
- log:Datakit 自身的程序日志
- metrics:Datakit 自身暴露的 Prometheus 指标
- profile:Datakit 自身 Profile 数据
- pipeline:Pipeline 脚本 Version-1.33.0
下面就以上各个方面,分别说明如何通过这些已有的信息,来排查遇到的具体问题。
基本信息查看¶
BR 文件名形式一般为 info-<timestamp-ms>.zip
,通过这个时间戳(单位毫秒),我们即可得知该 BR 的导出时间,这对后续的指标排查是有意义的。
在 info 文件中,会收集当前机器的操作系统信息,包括内核版本、发行版本、硬件架构等等。这些可以辅助我们排查问题。
除此之外,如果 Datakit 是容器安装的,还会收集一堆用户侧的环境变量配置情况,所有以 ENV_
开头的环境变量都是针对 Datakit 主配置或采集器配置。
查看采集配置¶
在 config 目录下,收集了所有采集器的配置以及 Datakit 主配置,所有文件都以 .conf.copy
作为后缀。在排查数据问题时,这里的配置情况非常有帮助。
查看中心同步数据¶
在 data 目录下,有一个 .pull 的隐藏文件(较新的版本这个文件名为 pull,不再隐藏了),里面还有几类从中心拉取下来的配置信息:
结果是一个 JSON,如:
{
"dataways": null,
"filters": { # <--- 这里是黑名单列表
"logging": [
"{ ... }"
],
"rum": [
"{ ... }"
],
"tracing": [
"{ ... }",
]
},
"pull_interval": 10000000000,
"remote_pipelines": null
}
有时候,用户会反馈数据缺失,很有可能是其配置的黑名单将数据丢弃了。这里的黑名单规则可以辅助我们排查这种数据丢失的情况。
日志分析¶
在 log 目录下,有两个文件:
- log:这是 Datakit 的程序运行日志。里面的信息可能不完整,因为 Datakit 会定期(默认 32MB)丢弃老的日志
在 log 文件中,我们可以搜索一下 run ID
,自此以后,才是一个重新启动的运行日志。当然,可能搜索不到,这时候可以判断日志被 Rotate 掉了。
- gin.log:这是 Datakit 作为 HTTP 服务所记录的 access log
在接入了 DDTrace 等这类采集器的时候,分析 gin.log 有利于排查 DDTrace 数据采集的情况。
其它日志排查方式,参见这里。
指标分析¶
指标分析是 BR 分析的重点,Datakit 自己暴露了非常多的自身指标,通过分析指标,我们能推断出 Datakit 各种行为。
以下各种指标都有各自不同的标签(label/tag),综合这些标签,能更好的定位问题。
数据采集指标¶
采集有关的指标有几个关键指标:
datakit_inputs_instance
:可知开启了哪些采集器datakit_io_last_feed_timestamp_seconds
:各个采集器上次采集到数据的时间datakit_inputs_crash_total
:采集器崩溃次数datakit_io_feed_cost_seconds
:feed 阻塞时长,如果这个值较大,表明网络上传可能较慢,阻塞了采集器正常采集datakit_io_feed_drop_point_total
:feed 时丢弃的数据点数(目前默认只有时序指标在阻塞时会丢弃)
综合分析上面这些指标,大概能还原各个采集器的运行情况。
黑名单/Pipeline 执行指标¶
黑名单/Pipeline 是用户自定义的数据处理模块,这部分对数据的采集有重要影响:
- 黑名单主要用来丢弃数据,用户编写的规则可能会误杀一些数据,导致数据不完整
- Pipeline 除了处理数据之外,也可以丢弃数据(
drop()
函数)。在处理数据的过程中,可能其 Pipeline 脚本消耗很大(比如复杂的正则表达式匹配),使得采集来不及,进而导致像日志跳档1这样的问题。
主要涉及的指标如下2:
pipeline_drop_point_total
:Pipeline 丢弃的 point 数pipeline_cost_seconds
:Pipeline 处理 point 的耗时,如果耗时较长(ms 级别),则可能导致采集阻塞datakit_filter_point_dropped_total
:黑名单丢弃的 point 数
数据上传指标¶
数据上传指标主要指 Dataway 上报模块的一些 HTTP 有关的指标。
datakit_io_dataway_point_total
:上传总点数(不一定全部上传成功)datakit_io_dataway_http_drop_point_total
:上传过程中,重传后仍失败,Datakit 会丢弃这些数据点datakit_io_dataway_api_latency_seconds
:调用 Dataway API 的耗时。如果耗时较大,会阻塞采集器的运行datakit_io_http_retry_total
:retry 数如果较多,表明网络质量不太好,也可能中心的压力很大
基础指标¶
基础指标主要指 Datakit 运行期间一些业务指标,它们包括:
datakit_cpu_usage
:CPU 消耗datakit_heap_alloc_bytes/datakit_sys_alloc_bytes
:Golang 运行时 heap/sys 两种内存指标。如果出现 OOM,一般是后者的内存超过了内存限制datakit_uptime_seconds
:Datakit 启动时长。启动时长是一个重要辅助指标datakit_data_overuse
:如果工作空间欠费,Datakit 上报数据会失败,这个指标的值就是 1,否则为 0datakit_goroutine_crashed_total
:崩溃的 Goroutine 计数。如果一些关键 Goroutine 崩溃,会影响 Datakit 的正常运行
Monitor 查看¶
Datakit 内置的 monitor 命令能播放 BR 中的一些关键指标,相当于一种可视化方式,相比查看苍白的数字,它显得更加友好一点:
由于默认 BR 会收集三份 metrics(每份数据相差 10s 左右),monitor 播放的时候,会有实时的数据更新。
指标无效问题¶
BR 在分析问题时能提供非常多的帮助,但是很多时候,用户发现问题的时候,会重启 Datakit 进而丢失现场,导致 BR 收集到的数据无效。
此时我们可以通过 Datakit 内置的 dk
采集器 来采集其自身数据(建议将其添加到默认启动的采集器中,较新的 Datakit 版本 Version-1.11.0已经这么做了),上报给用户的空间,这相当于将 Datakit 自身的指标存档了。而在 dk
采集器中,可以更进一步开启所有自身指标采集(这会消耗更多时间线)
- Kubernetes 中安装时,通过
ENV_INPUT_DK_ENABLE_ALL_METRICS
来开启所有 Datakit 自身指标上报 - 主机安装,修改
dk.conf
,在metric_name_filter
中,打开第一个指标注释(# ".*"
),相当于放行所有指标采集
这样会将 Datakit 暴露的所有指标都采集一份到用户的工作空间。在工作空间中,通过「内置视图」中搜索 datakit
(选择「Datakit(New)」),即可看到这些指标的可视化效果。
Pipeline 查看¶
如果用户配置了 Pipeline,在 pipeline 目录下会复制一份 Pipeline 拷贝。通过查看这些 Pipeline 我们可以定位一些数据字段切割问题;如果某些 Pipeline 耗时较大,我们也能提供一些优化建议,降低 Pipeline 脚本的消耗。
External 信息¶
在 external 目录下,一些外部采集器(目前主要是 eBPF 采集器)的日志和调试信息都会收集起来,以便于排查跟这些外部采集器有关的问题。
Profile 分析¶
Profile 分析主要面向开发者,通过 BR 中的 profile,我们能分析出在 BR 收集那一刻 Datakit 的内存/CPU 开销热点,透过这些 profile 分析,能指导我们更好的优化现有的代码,或者发现一些潜在的 bug。
在 profile 目录下,有如下一些文件:
- allocs:自 Datakit 启动一来的内存分配总量。通过这个文件我们能得知内存分配的重头在何处。有些地方可能没必要分配那么多内存
- heap:当前(收集 BR 那一刻)内存占用的分布。如果存在内存泄漏,这里大概率能看出来(内存泄漏一般发生在不需要那么多内存的模块,基本很容易看出来)
- profile:查看当前 Datakit 进程的 CPU 消耗。一些不必要的模块可能消耗了太多了 CPU(比如高频的 JSON 解析操作)
其它几个文件(block/goroutine/mutex)目前尚未用于问题排查。
通过如下命令,我们可以在浏览器中查看这些 profile 数据(建议用 Golang 1.20 以上的版本,它的可视化效果更好):
我们可以在 shell 中做一个 alias,便于操作:
# /your/path/to/bashrc
__gtp() {
port=$(shuf -i 40000-50000 -n 1) # 随机一个 40000 ~ 50000 之间的端口
go tool pprof -http=0.0.0.0:${port} ${1}
}
alias gtp='__gtp'
直接用如下命令即可:
总结¶
虽然 BR 不一定能解决所有问题,但能避免很多沟通上的信息差以及误导,还是建议大家在反馈问题的时候,提供对应的 BR。同时现有的 BR 也会不断改进,通过暴露更多的指标,收集更多其它方面的环境信息(比如 Tracing 有关的客户端信息等),进一步优化问题排查的体验。