公司之前一直是自己拼凑的一套监控,Prometheus 抓指标、ELK 看日志、报警靠人肉盯 Grafana,三个系统数据不互通,出问题的时候经常是日志里查到一半又要跳到另一个系统去看指标,体验很割裂。后来老板拍板换 Datadog,我负责给几个核心服务接入,用了小半年,记点感受,不算教程,就是随手写写踩到的东西。
接入本身没什么难度,dd-trace 往应用里一塞,环境变量配一下 DD_ENV、DD_SERVICE、DD_VERSION,agent 用 sidecar 或者 daemonset 跑起来,APM 面板马上就有数据了,这点确实比自己搭 Jaeger 省心太多。真正花时间的是后面的调优和踩坑。
第一个坑是默认的 trace 采样率。刚接进去的时候用的是默认配置,流量大一点的服务一个月账单直接吓人,才反应过来 Datadog 是按 trace 数量和保留时长计费的,不是免费的开源方案。后来手动配了 ingestion 的采样规则,对健康的、状态码 200 的请求做低采样,对报错和慢请求(> 1s)做高采样甚至全量保留:
1 | DD_TRACE_SAMPLE_RATE: "0.1" |
再配合 APM 里的 retention filter,把 error 和高延迟的 trace 单独设一条 100% 保留的规则,这样既能控制成本,出问题的时候关键 trace 也不会被采样掉。这个坑网上其实有人写过,但自己不踩一遍是不会真的重视的,账单来了才叫人肉痛。
第二个是日志和 trace 关联这块,一开始死活关联不上,APM 里点进一个 trace 想看对应的日志,永远是空的。查了半天才发现是日志格式里没塞 dd.trace_id 和 dd.span_id,Datadog 靠这两个字段做的关联,得在日志的 formatter 里手动注入:
1 | import logging |
Python 用 ddtrace-run 起服务的话其实有自动注入的选项(DD_LOGS_INJECTION=true),但我们服务是手动初始化 tracer 的,自动注入没生效,只能自己写这层 filter。之前光顾着看文档里”开箱即用”那部分,没意识到手动初始化的场景是另一套逻辑,白白花了一下午。
Dashboard 这块用下来感觉比自建 Grafana 舒服的地方是模板变量和 APM 数据能联动,比如按 service 和 env 切换过滤条件的时候,日志、指标、trace 面板会一起跟着变,不用挨个手动改。但也有别扭的地方,Datadog 的 monitor(也就是报警规则)配置起来心智负担比 Prometheus 的 alerting rule 重不少,各种 evaluation window、recovery threshold、notification 的组合方式一开始很容易配错,我们就出过一次报警规则设的 evaluation window 太短,服务重启的正常波动都能触发一次误报,搞得凌晨群里炸了一条没意义的报警,后来把窗口从 1 分钟拉到 5 分钟,又加了个 for 之类的持续时间条件才消停。
还有一点是 APM 的 service map,理论上能自动画出服务之间调用关系的拓扑图,实际用起来对内部服务之间用消息队列异步通信的部分基本画不出来,只能覆盖同步 HTTP/RPC 调用链路。指望它自动生成一份完整架构图不现实,异步这块还是得自己在文档里补。
整体来说换 Datadog 之后排查问题确实快了,不用在三个系统之间来回跳,一个 trace 点进去日志指标全有。就是这东西真的贵,采样策略不提前规划好,账单能把人吓一跳,接入之前最好先跟负责账单的同事对齐一下预期。