尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

LogDNA Agent日志采集代理部署与排障实战

LogDNA Agent日志采集代理部署与排障实战 1. 日志采集代理到底解决了什么问题凌晨两点被告警电话叫醒爬起来 SSH 登进机器grep一个订单号结果日志散在三台应用机、两台网关机和几个早已销毁的容器里——这个场景几乎是每个后端工程师的成人礼。日志采集代理log agent / log shipper存在的全部理由就是终结这个循环它常驻在日志产生的那台机器上把分散的、以文件或 stdout 形式存在的原始日志转换成有序的、带元数据的事件流持续推送出去最终汇入统一的实时日志管理平台。标题里提到的LogDNA Agent就是这条路线上的一个典型代表单二进制、配置声明式、自带容器元数据富化、资源占用控制得比较克制。这篇内容不打算复述官方文档里那几行安装命令而是想把这套东西从架构决策、容量估算、配置细节到排障路径完整拆一遍适合正在评估日志方案的技术负责人也适合第一次接手日志管道的运维同学。1.1 从单机tail -f到集中式日志管道中间差了什么单机时代日志是一份事后可查的文件排查靠的是记忆力和耐心你知道大概几点出事知道哪个应用登上去less一把梭。机器一多事情就变味了。三台机器的时间戳对齐要靠肉眼看容器化之后更离谱——Pod 一旦重建写入节点本地磁盘的日志跟着一起进垃圾桶故障现场就这么被销毁了。到了这个阶段日志的性质已经发生变化它不再是文件而是一条需要被持续搬运的数据流。采集代理干的第一件事就是把这条数据流接管过来。它记住自己读到了文件的哪个位置offset / inode文件被logrotate切割或者 rename 之后仍然能跟住新的写入点主机重启之后从断点继续读而不是从头再来一遍。第二件事是给每条日志贴上上下文主机名、采集时间、文件路径、应用标签容器环境下还有 namespace、pod、container 这些编排层元数据。第三件事是可靠投递——本地缓冲、失败重试、断连后回补。这三件事听起来都很朴素但真正把它们同时做稳才是采集代理和写个脚本tail -F | nc之间的天壤之别。我见过太多团队前期用一个 while 循环凑合等到日志量涨到每天几十 GB丢日志丢到无法定位问题再回头补课的成本要高得多。1.2 采集代理在可观测性链路里的位置决定了它的天花板一条完整的日志链路大概是这样产生应用 / 系统 / 中间件→ 采集agent→ 传输与聚合可选→ 存储与索引后端→ 查询与告警前端。采集代理站在最靠左的位置是唯一直接接触数据源头的一环。这个位置有点像小区水表——后面管网再宽、水厂再大水表读不准或者漏读后面全是错的。很多团队在排查日志查不到时本能地怀疑后端索引或者查询语法实际上问题往往出在最左边文件根本没被 agent 匹配到、多行日志被拆成几十条、容器重启后 inode 变了没跟住。采集侧的问题在链路上游下游无论怎么优化都补不回来。理解这一点才能解释为什么采集代理的配置值得花时间细抠。反过来看采集代理也不该被赋予太多职责。它不该承担复杂的字段富化和跨源关联——那些属于第二层聚合器或者后端处理。代理的定位是稳、轻、准把数据原样、带足上下文、不丢不乱地送出去就是满分。1.3 什么规模、什么类型的团队真正需要它经常有人问我们只有几台机器用得着上采集代理吗我的判断标准是下面这张表。判断维度典型现状是否建议引入代理主机数量3 台以上或机器会动态增减建议从第一天就上部署形态容器化Pod 会重建、会漂移强烈建议容器日志基本离不开故障定位方式需要多人协作、跨机器串联时间线建议不然排查全靠吼合规与审计要求需要留存操作日志、访问日志必须本地日志容易被清理单机日志量每天 1 GB 以内且只有单机排查需求可以先不上但要注意留好扩展位机器少所以不用这个逻辑有个隐藏前提机器数量不会增长。现实中这个前提几乎从不成立。更务实的做法是哪怕只有三台机器也把代理装上配置写进镜像或者配置管理里。等到第十台机器加进来的时候你不需要额外做任何事。2. 选型思路为什么走轻量代理这条路线日志采集这块的生态相当热闹从老牌的 syslog 系rsyslog、syslog-ng到通用采集器Fluent Bit、Filebeat 这一类再到自带完整平台的方案选择面很宽。标题里推荐的这类轻量代理路线背后的取舍值得说清楚。2.1 三种部署形态的取舍宿主机、DaemonSet、Sidecar同一个代理落地形态完全不一样选错了后面全是麻烦。形态资源开销隔离性覆盖面运维成本适用场景宿主机常驻进程最低每机一份共享宿主互相影响系统日志 容器日志都能读中需要配置管理下发物理机 / 虚拟机为主混合环境Kubernetes DaemonSet低每节点一份与业务 Pod 隔离通过 hostPath 读取节点上的容器日志低随集群声明式管理标准容器集群Sidecar 边车高每个 Pod 一份最强与业务同生命周期只覆盖本 Pod 的 stdout高Pod 数量直接放大资源消耗多租户、需要强隔离或自定义处理Sidecar 的坑在于资源乘数效应一个 50 MB 内存的代理配上 300 个 Pod就是 15 GB 的纯开销而且每个边车都要走一遍网络出口。除非确实有租户隔离、独立凭证或者必须对特定应用做定制解析的需求否则 DaemonSet 或者宿主机常驻是更划算的默认选项。我自己的经验是能用 DaemonSet 就别用 Sidecar能用一份配置覆盖全集群就别给每个应用单独定制。2.2 什么时候需要再加一层聚合什么时候直连就够采集代理能不能直接怼到后端大多数情况下可以。但有一个经验阈值单集群日志峰值超过 20 MB/s或者需要做多源路由、字段富化、脱敏改写、跨集群汇聚的时候就该考虑在代理和后端之间插一层聚合器。聚合器aggregator的角色是缓冲区加路由器。它带来的好处很实在后端维护或者限流的时候聚合器本地磁盘扛住峰值多个集群、多种日志格式可以在这一层统一清洗和打标后端地址变更只需要改一处。代价是多一个组件要运维、多一跳延迟、多一个可能出问题的环节。判断方式其实很简单——如果你发现代理配置里出现了大量重复的路由规则和字段改写逻辑那就是该加聚合层的信号。规则应该跟着数据走而不是散落在几百台机器上。2.3 关键能力清单按重要性排序评估任何一款采集代理我都会拿这张表过一遍权重按实际踩坑频率排能力重要性说明文件轮转跟踪必须靠 inode offset切割后能自动跟到新文件不丢不重多行合并必须堆栈日志不合并后端基本没法看一条异常变五十条背压与本地缓冲必须后端不可用时不能阻塞业务也不能无限吃内存磁盘缓冲与断点续传重要内存缓冲顶不住长时间断连重启后要能续传容器元数据富化重要pod / namespace / node 这些标签是容器排查的命脉资源占用上限重要有明确的 CPU / 内存水位配置避免被 OOM 或者抢占业务配置热加载加分改规则不用重启滚动更新时少一次抖动内置解析插件加分JSON、nginx、apache 这类常见格式能省掉大量正则这张表里前四项如果有一项不达标基本可以直接排除。后面几项属于锦上添花缺了能用但用起来会难受。3. 部署前的准备容量、权限与系统参数代理装上去之前有几件事必须先算清楚不然跑起来之后要么被限流要么被 OOM要么把宿主机的文件句柄吃干净。3.1 容量估算把日志量算成带宽、内存和磁盘估算这件事不需要多精确但必须做。我一般按下面的步骤走以 200 台主机、每台每天 500 MB 原始日志为例第一步算总日志量与平均速率。200 × 500 MB 100 GB/天。换算成平均写入速率100 GB ÷ 86400 s ≈ 1.19 MB/s。这个数字很小说明平均带宽压力可以忽略。第二步算峰值。日志写入从来不是均匀的业务高峰期常见 5 倍于均值按 5 倍算就是约 6 MB/s。再往上加一层安全余量按 10 MB/s 规划出口带宽折合 80 Mbps——对绝大多数内网环境毫无压力。第三步算行数用来评估 CPU。假设平均每行 200 字节100 GB ÷ 200 B 5 亿行/天折合平均约 5800 行/秒峰值按 5 倍算约 29000 行/秒。这个量级对单核来说不算轻松但分布在 200 台机器上每台实际只有约 145 行/秒的峰值任何一个像样的代理都能轻松处理。关键在于把总量摊到每台机器上再判断而不是拿集群总量吓自己。第四步算内存缓冲。内存缓冲的作用是吸收短时抖动。按峰值 10 MB/s、希望扛住 60 秒的断连来算缓冲区需要约 600 MB——这明显超出合理范围。实际做法是内存缓冲设小比如每台机器 32~64 MB扛 5~10 秒的毛刺更长时间的断连交给磁盘缓冲。第五步算磁盘缓冲。按每台机器峰值 50 KB/s、希望扛住 30 分钟断连来算50 KB/s × 1800 s ≈ 90 MB。给到 500 MB 到 1 GB 的磁盘配额就非常宽裕了。注意这个值要配合缓冲满了之后怎么办的策略一起看后面会讲。提示以上计算中的日志量、行长度、峰值倍数都是常见经验值实际取值必须用你们自己的历史数据校准。有历史数据就用历史数据的 P95 和 P99没有就先用经验值上线跑一周后再回来修正。几个系统层面的参数也顺手检查一遍# 检查单个进程可打开的文件句柄上限 ulimit -n # 统计需要监控的文件数量句柄需求约为 文件数 x 1.5 find /var/log -type f | wc -l # 检查文件系统剩余空间给磁盘缓冲留余量 df -h /var/lib # 确认时间同步状态日志时间戳错乱的根源往往在这里 timedatectl status文件句柄这一项特别容易被忽略。容器环境下/var/log/containers里的软链接数量会随着 Pod 数量增长几百个 Pod 就是几百个文件句柄默认的 1024 在很多发行版上根本不够。建议在 systemd unit 里显式设置LimitNOFILE65536。3.2 网络、凭证与最小权限采集代理的连接方向是出站这一点对防火墙策略很友好只需要放行到后端采集端点的 HTTPS 出站不需要开任何入站端口。如果走代理或者专线记得同步配置HTTPS_PROXY之类的环境变量很多日志发不出去的案例最后都追到这一条上。凭证管理是安全审计的重点。密钥绝对不能明文写在配置文件里再提交到 Git——这件事每年都在不同的团队重演。正确姿势是环境变量注入或者容器 Secret 挂载# 通过环境变量注入采集密钥配置文件里只引用变量名 export AGENT_INGEST_KEY由密钥管理系统下发的值# 配置文件中只写变量引用不落明文 output: endpoint: https://logs.internal.example/ingest api_key: ${AGENT_INGEST_KEY}运行身份上给最小权限就够了建一个专用的logagent用户加入adm或者systemd-journal组以读取系统日志日志目录给只读权限。代理不需要 root也不需要写业务目录的权限。这个习惯一旦养成安全评审会省很多口舌。3.3 系统层调优三个容易被忽略的细节第一个是inotify 上限。代理监听文件变化通常依赖 inotify容器节点上文件数量爆炸时会撞到max_user_watches上限表现是新 Pod 的日志采不到。调整方式# 查看当前上限 cat /proc/sys/fs/inotify/max_user_watches # 临时调整写入 /etc/sysctl.d/ 持久化 sysctl -w fs.inotify.max_user_watches524288第二个是时钟同步。日志的价值很大程度上建立在时间线上如果某台机器的时钟偏了 30 秒跨机器串联排查会直接失效。确保所有节点跑着 NTP 或者 chrony并且定期核验偏移量。这一条没有任何技术含量但它是很多日志顺序莫名其妙问题的真凶。第三个是日志文件的写入方式。如果业务侧用的是追加写O_APPEND代理的跟踪会非常稳如果某些应用会重写整个文件或者频繁 truncate跟踪逻辑就容易断。遇到这类应用优先在应用侧改成滚动切割而不是在代理侧硬扛。4. 配置实操从最小可用到生产可用配置这块我习惯分三步走先跑通最小可用确认数据能到再补多行合并和标签让日志可读可查最后加缓冲、重试和资源限制让它扛得住异常。4.1 最小可用配置先让一条日志出现在平台上最小配置只要能回答三个问题读什么、打什么标签、发到哪里。下面是这类采集代理常见的配置结构字段名各家略有差异逻辑是相通的# agent.yaml —— 最小可用配置 sources: - name: syslog paths: - /var/log/syslog - /var/log/auth.log tags: - host-syslog - name: nginx-access paths: - /var/log/nginx/access.log tags: - nginx-access format: nginx output: endpoint: https://logs.internal.example/ingest api_key: ${AGENT_INGEST_KEY}部署之后第一件事不是看平台上的图表而是主动制造一条日志验证全链路# 写入一条带唯一标记的测试日志 logger logagent-selftest-$(date %s) markerverify # 在采集端确认本地已经读到不同实现方式不同可查代理自身日志 tail -n 5 /var/log/syslog如果本地读到了、平台上没有问题在传输侧如果本地也没读到问题在文件匹配或者权限。这个二分法能省掉大量瞎猜时间。4.2 多行合并优先级最高的一项配置多行合并是我认为最值得花时间的一项配置。一段 Java 堆栈如果不合并会被拆成几十条独立事件后端按时间排序之后完全没法读而且索引量凭空翻好几倍。配置的核心是两条规则什么样的行算新事件的开头什么样的行算上一条的延续。常见做法是用正则匹配开头模式sources: - name: app-java paths: - /var/log/app/*.log multiline: # 匹配到这些模式说明是新的日志事件开头 start_pattern: ^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}:\d{2} # 超过这个时间没有新行强制结束当前事件防止卡住 flush_timeout: 2s # 单条事件最大字节数防止异常情况下无限拼接 max_bytes: 256kb tags: - app-javaflush_timeout这个参数特别关键很多日志延迟很高的问题就出在这里。如果一段堆栈的最后几行一直等不到新事件开头事件会一直挂着不发送表现为日志慢半拍。设成 2 秒左右是个比较稳的折中既能等到完整的堆栈尾部又不会让日志明显滞后。注意正则不要写得太贪婪。^.*这种模式会把每一行都判定为新事件开头多行合并等于没配。写完一定要拿真实日志做一次回放验证而不是靠肉眼读正则。还有一个常见误区以为多行合并可以覆盖所有场景。实际上 Ruby、Python、Go 的堆栈格式各不相同同一个集群里如果有多种语言的应用要么写多条规则按路径区分要么就在应用侧统一日志格式。后者才是根治方案但改造成本高代理侧兜底是更现实的过渡手段。4.3 标签、元数据与路由让日志可被找到日志查不到八成是因为标签没打对。一条只有正文的日志在几百个服务的集群里基本等于不可检索。标签规划建议遵循三个必打两个选打标签类别示例必要性说明环境env: prod/env: staging必打防止测试日志污染生产视图服务名service: order-api必打最核心的检索维度主机标识host: node-07必打定位到具体机器版本version: v2.3.1选打灰度期间的价值极高编排元数据pod/namespace/node容器环境必打容器排查的生命线容器环境下元数据富化最好交给采集代理自动完成而不是让应用自己在日志正文里拼字符串。代理读取节点上的容器运行时信息自动补上 pod、namespace、node、镜像名这些字段应用侧只需要老老实实往 stdout 打印内容就行。这个分工清晰也避免了业务代码耦合日志基础设施。4.4 缓冲、重试与背压后端挂了怎么办这是最考验采集代理设计的一块。核心问题只有一个后端不可用或者限流的时候日志去哪。三个选项各有代价策略行为优点风险内存缓冲写入内存队列满了丢弃最旧不影响业务无磁盘 IO进程重启全丢缓冲小则丢得多磁盘缓冲落盘队列恢复后按序回放扛得住长断连和重启磁盘 IO 增加、占用空间、回放可能造成突发阻塞读取不读新日志等后端恢复完全不丢文件增长可能打满磁盘影响业务生产环境的常见组合是内存缓冲做主缓冲磁盘缓冲做溢出兜底两者都有明确上限超限之后丢弃并记录丢弃计数。丢弃这件事必须可观测——如果代理默默丢日志你会得到一个看起来一切正常但就是查不到的诡异状态。output: endpoint: https://logs.internal.example/ingest buffer: memory_max: 64mb disk_max: 1gb disk_path: /var/lib/logagent/buffer # 缓冲满时的行为drop_oldest 或 block on_full: drop_oldest retry: initial_backoff: 1s max_backoff: 60s # 只对 5xx 和网络错误重试4xx 直接丢弃避免无效重试 retry_on: [5xx, network]重试策略里有个细节值得强调只重试可恢复的错误。如果后端返回的是凭证无效或者请求格式错误4xx重试一万次也没用反而会把本地缓冲撑爆、把出口带宽占满掩盖真正的问题。把 4xx 直接丢弃并打错误日志是更负责任的做法。4.5 容器环境DaemonSet 部署的关键挂载点Kubernetes 环境下的标准做法是 DaemonSet通过 hostPath 把节点上的日志目录挂进容器。几个挂载点不能少apiVersion: apps/v1 kind: DaemonSet metadata: name: log-agent namespace: observability spec: selector: matchLabels: app: log-agent template: metadata: labels: app: log-agent spec: serviceAccountName: log-agent tolerations: # 关键让代理也能跑在带污点的节点上否则这些节点的日志永远采不到 - operator: Exists containers: - name: agent image: log-agent:latest env: - name: NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName - name: AGENT_INGEST_KEY valueFrom: secretKeyRef: name: log-agent-secret key: ingest-key resources: requests: cpu: 50m memory: 64Mi limits: cpu: 300m memory: 256Mi volumeMounts: - name: varlog mountPath: /var/log readOnly: true - name: containers mountPath: /var/log/containers readOnly: true - name: dockercontainers mountPath: /var/lib/docker/containers readOnly: true - name: buffer mountPath: /var/lib/logagent volumes: - name: varlog hostPath: path: /var/log - name: containers hostPath: path: /var/log/containers - name: dockercontainers hostPath: path: /var/lib/docker/containers - name: buffer hostPath: path: /var/lib/logagent type: DirectoryOrCreate这里有两个坑值得单独拎出来。一是 tolerations默认 DaemonSet 不会调度到带污点的节点如果不加operator: Exists那些专门跑批处理或者特殊负载的节点日志永远是盲区。二是 buffer 目录必须挂 hostPath如果放在容器内Pod 一重启缓冲就没了磁盘缓冲等于白配。/var/log/containers里其实是软链接指向/var/lib/docker/containers或者对应的容器运行时目录containerd 环境下是/var/log/pods。两个路径都要挂否则要么软链接断掉要么读到的是空文件。这个坑我第一次踩的时候排查了整整一下午。5. 常见问题与排查实录下面这些是真实运维中反复出现的场景按出现频率排。5.1 日志丢失五个高频原因逐个排除第一文件轮转后没跟上。代理靠 inode 跟踪文件logrotate如果用的是copytruncate复制后清空原文件inode 不变但内容被清空代理的读取位置可能就错位了。优先用create模式切割让新文件拿到新 inode。第二容器重启导致路径变化。Pod 重建后容器 ID 变了日志文件路径跟着变。软链接的方案能自动适应但如果直接用容器 ID 拼路径写死在配置里必然丢。第三缓冲溢出静默丢弃。这是最隐蔽的一种。表现为平时都有就是高峰那几分钟没有。查代理自身的指标看丢弃计数是不是在涨。第四采集规则不匹配。通配符写错、目录层级不对、文件权限不足读不到。先用ls -l和sudo -u logagent cat验证代理身份能读到文件。第五多行合并吞掉了内容。一个没有flush_timeout的多行配置会把后面所有不符合开头模式的行全部拼进上一条事件直到下一条匹配开头模式的日志出现。表现是日志数量对不上但内容看起来都在。5.2 日志重复与乱序理解投递语义几乎所有采集代理走的都是**至少一次at-least-once**语义确认收到之前不删本地缓冲网络抖动或者超时重传就会产生重复。想要严格的不重不丢代价极高绝大多数场景不值得。务实的做法是在查询和告警侧做去重。日志正文里带一个唯一的请求 ID 或者 trace ID后端按这个字段去重比在采集侧追求精确一次要便宜得多。乱序的成因更多是时间戳来源不一致。有的代理用采集时间有的用日志正文里解析出的时间两者混用就会出现后写的日志排在前面。统一策略排查用日志时间摄入用采集时间两个字段都保留。查询时按日志时间排序需要看摄入延迟时切到采集时间。5.3 CPU 或内存飙高从配置里找原因代理吃资源八成跑不出这四个原因现象常见原因排查方向CPU 持续偏高正则过于复杂或对大文件全量 JSON 解析逐个 source 关掉做二分简化正则避免嵌套量词CPU 周期性尖刺大量小文件同时被扫描拉长扫描间隔检查是否有文件数量异常增长内存持续上涨缓冲无上限或事件队列积压检查 buffer 配置是否有 max看后端是否在限流内存瞬间打满多行合并的max_bytes设得太大降到 256kb 以下确认没有单条超大日志正则回溯是 CPU 杀手里的头号选手。像(.*)这种写法在长行上会触发指数级回溯一行几十 KB 的日志能把一个核跑满。写完正则拿最长的那条真实日志跑一遍看耗时这个习惯能省掉很多麻烦。5.4 采集延迟四段定位法日志到了但慢了几分钟是另一类高频问题。我习惯把链路切成四段依次确认本地是否已读代理的自身日志或者指标里最后读取位置是否已经追上文件末尾。缓冲是否堆积内存队列和磁盘队列的深度是否在持续增长增长说明下游有瓶颈。出口是否限流出口带宽是否打满是否有代理网关在限速。服务端是否限速后端是否有摄入速率上限返回 429 这类状态。大部分情况下卡在第 2 段。堆栈没配flush_timeout、缓冲满了在反复重试、后端在限流——这三个原因覆盖了我遇到的七八成延迟问题。5.5 问题速查表症状优先检查快速验证方式完全查不到日志文件匹配规则、读取权限用代理运行身份cat目标文件只有部分机器缺日志DaemonSet 调度、tolerations看目标节点上是否有代理 Pod容器日志缺hostPath 挂载路径进容器ls /var/log/containers日志被拆成多条多行合并配置拿真实堆栈跑一次解析回放日志延迟数分钟flush_timeout、缓冲深度看代理指标队列深度趋势高峰时段丢日志缓冲上限、丢弃计数对比后端接收量与本地写入量重复日志重试策略、确认机制统计同一 trace ID 的出现次数6. 成本与长期运维容易被忽略的那笔账采集代理装上去只是开始真正决定长期体验的是日志量治理。有个残酷的现实日志存储成本的增长曲线几乎永远比业务量增长得陡。6.1 日志量膨胀的五个隐形来源DEBUG 级别没关。一个高频循环里的log.debug能让日志量翻十倍。上线前过一遍日志级别配置这一条几乎每次都能捡到便宜。访问日志和业务日志双写。网关打一份访问日志应用自己又打一份请求日志内容高度重叠。多行展开。没配多行合并时一段堆栈占几十条事件索引开销比合并后高出数倍。心跳和健康检查日志。探针每几秒一次一年下来是相当可观的量。这类日志单独打标设为短保留期或者直接丢弃。异常刷屏。某个依赖挂了应用在循环里疯狂打错误日志几分钟就能刷出几个 GB。这类日志需要限流或者按指纹去重。6.2 脱敏、采样与分层保留脱敏必须在采集侧做不能依赖后端。手机号、身份证、令牌这些字段一旦进了存储再想清理就是一场灾难。代理配置里加一条正则替换成本极低transforms: - type: replace pattern: (?(phone|mobile|id_card|token)?\s*[:]\s*?)([^,}\s]) replacement: $1***采样只适合特定类型的日志——比如高频的 debug 或者访问明细按 10% 采样保留趋势。错误日志和审计日志绝对不能采样漏掉的那一条往往就是关键证据。分层保留是成本控制的最后一招热数据 7 天可全文检索、温数据 30 天可按时间范围检索、冷数据 90 天仅归档出事后按需恢复。这套策略落地之后存储成本通常能压到原来的三分之一左右。最后分享一个我自己踩过的坑。早期部署采集代理的时候我给所有机器的配置用了同一份模板里面写死了service: app这个标签。跑了三个月之后团队反馈按服务名查日志完全没用因为几百个服务的日志全都叫app。改成从环境变量或者容器元数据自动注入之后检索体验立刻不一样了。这件事让我记住一个教训标签体系要在第一台机器上线之前就想清楚改起来的成本比配置本身高一个数量级。现在我的做法是任何采集配置落地前先拿三个真实的排查场景走一遍——某笔订单报错、某个接口变慢、某台机器异常——如果这三个场景都能靠标签在几分钟内定位标签设计就算及格了。
返回列表