ELK日志平台架构详解:从集中采集到TraceID关联的实践指南 📅 发布时间:2026/9/3 11:29:09 👁 浏览次数: 在真实的分布式项目里日志是最容易启动又最难做好的基础设施之一。机器少的时候登录服务器执行tail -f就能定位问题机器一旦超过几十台业务日志、中间件日志、监控日志散落在不同目录定位一次接口超时可能要翻七八台机器效率非常低。这几年我在团队内部持续维护一套日志采集与分析平台项目代号叫“雾山实录”当前版本迭代到了 29.7。这一版本的重点是把日志从应用产生到 Kibana 可检索的时间控制在分钟级同时让异常堆栈、调用链 TraceID 和业务字段都能被结构化解析。本文以这个项目为线索完整记录设计和落地过程包括架构选型、关键配置、运行验证以及上线后最容易踩的坑。1. 先想清楚日志散落的时候问题到底出在哪1.1 一套日志系统要解决的不只是“看日志”先看一个典型场景。线上商品服务报了一个“库存扣减失败”但库存服务在另一批机器上订单服务在第三批机器上网关日志又在单独的目录里。要定位这个问题通常需要这样操作登录订单服务机器搜订单号。登录库存服务机器搜商品 ID 和扣减流水。登录网关机器看入口请求参数。查看数据库慢日志确认是不是 SQL 执行超时。最后把时间点对齐人工拼接整个调用过程。这个过程的第一个问题是慢。第二个问题是容易漏因为不同服务日志格式不统一有的打印 JSON有的打印一行无规则文本有的把堆栈折成多行导致grep很不方便。如果把各服务日志集中到一个平台上再按时间、服务名、TraceID 做索引定位过程就可以从“登录很多台机器”压缩成“在一个查询框里输入关键字”。从这张对比表能看出统一日志平台解决的是排查效率问题而不仅是日志存储问题能力点分散日志统一日志平台日志查找逐台登录服务器一个搜索入口跨服务关联人工拼接TraceID 串联异常分析看单行文本结构化字段聚合历史回溯覆盖或丢失按索引长期保存告警能力脚本轮询文件按规则实时触发1.2 统一日志平台的核心职责“雾山实录”v29.7 在职责划分上很明确它只做五件事采集从应用日志文件、标准输出、中间件日志中读取日志。缓冲把日志写入 Kafka避免应用直接依赖 Elasticsearch防止 ES 抖动时拖垮业务。清洗用 Logstash 解析日志内容补全字段删除无用字段统一时区。存储与检索写入 Elasticsearch建立索引提供服务端全文检索和聚合能力。可视化与告警通过 Kibana 展示日志通过查询规则触发异常告警。这里最容易被忽略的是“缓冲”这一层。很多团队刚开始只做 Filebeat 到 ES日志量小的时候没问题一旦突发流量导致 ES 写入变慢Filebeat 会积压应用日志目录会膨胀甚至触发磁盘报警。加一层 Kafka等于给日志生产和日志消费之间加了一个削峰填谷的缓冲生产端不用关心消费端是否健康。1.3 方案选型什么时候用 ELK什么时候用 Loki什么时候用 ClickHouse“雾山实录”当前版本使用的是 Filebeat Kafka Logstash Elasticsearch Kibana 这套组合业内一般称为 ELK 技术栈。选型之前也对比过其他方案核心结论是没有最好的技术栈只有适合当前场景的技术栈。方案擅长场景主要短板落地成本ELK 技术栈全文检索、复杂查询、字段类型丰富组件多运维成本高较高LokiKubernetes 环境轻量级日志聚合全文检索能力弱适合标签检索较低ClickHouse日志聚合分析、量大、统计类查询单条日志检索和高亮体验不如 ES中等如果团队规模不大日志量以 GB 为量级可以直接用 Loki。如果需要按关键字全文搜索、做上下文排查、保留复杂查询ELK 更成熟。ClickHouse 更适合已经有明确分析维度、以统计分析为主的日志仓库不太适合当成一对一的在线排查入口。“雾山实录”选 ELK 的原因是业务侧排查问题主要依赖关键字搜索和字段过滤Elasticsearch 的全文索引和 Kibana 的交互式查询体验更适合一线开发使用。2. 雾山实录 v29.7 的整体架构和数据结构2.1 版本号不能只看数字要看它承载的迭代目标“雾山实录”这个名字是内部代号“雾山”表示生产环境因为生产环境很多时候就像被雾罩住一样不把日志和指标捞出来根本看不清线上到底发生了什么“实录”强调日志必须真实、完整、不可随意丢弃。29.7 表示当前是第 29 个大版本下的第 7 个小版本迭代。29.7 这个版本解决的核心问题有三个让业务日志从产生到 Elasticsearch 可检索的时间控制在分钟级。统一所有服务的日志格式强制使用 JSON 结构化日志。把 TraceID 与日志字段打通使一次请求在多服务之间的日志能被一键串联。版本迭代到这一步说明平台不是从零开始而是已经在生产中运行了很长时间。阅读本文时不必纠结这个具体版本号只需理解它代表的工程阶段已有稳定底座正在优化细节。2.2 组件角色划分整套链路包含五个核心组件每个组件的职责要分清楚否则后续排查问题时不知道日志卡在哪一层。组件职责关键关注点业务应用产生结构化日志日志格式、TraceID 传递、脱敏Filebeat读取日志文件并传输文件路径、offset 管理、性能Kafka日志缓冲与分发Topic 分区数、副本数、消费组Logstash解析与清洗日志Pipeline 配置、字段映射、时区Elasticsearch Kibana存储、检索与展示索引模板、生命周期、查询性能2.3 数据流转架构用文本图可以直观表示整条日志链路应用日志文件 | v Filebeat 采集 | v Kafka Topic: app-log | v Logstash Consumer | v Elasticsearch Index: app-log-2025.01.15 | v Kibana Discovery / Alert数据流上Filebeat 只负责读文件和写 KafkaLogstash 只负责消费 Kafka 和写 ES业务应用不直接依赖 Logstash 或 ES。这样拆的好处是每一层的稳定性可以被单独保证任意一层挂掉上游数据都不会丢。2.4 日志事件的数据模型日志写入 Kafka 时已经是 JSON 格式。下面是一个标准日志事件示例{ timestamp: 2025-01-15T10:30:00.00008:00, level: ERROR, logger: com.demo.order.service.StockService, message: 库存扣减失败, thread: http-nio-8080-exec-3, traceId: a1b2c3d4e5f6a7b8, spanId: a1b2c3d4e5f6a7b9, service: order-service, host: 10.0.3.11, env: prod, exception: java.lang.RuntimeException: stock not enough\n\tat com.demo.order.service.StockService.deduct(StockService.java:88) }字段含义如下字段含义是否必填timestamp日志产生时间是level日志级别是logger记录该日志的类或包名是message业务描述信息是traceId调用链追踪 ID建议必填spanId单次调用单元 ID建议必填service服务名是host主机 IP是env环境标识是exception异常堆栈异常时必填这个模型的关键是“结构化”。非结构化日志是一行文本解析时只能靠正则结构化日志本身就是 JSONLogstash 可以直接把字段映射到 ES后续查询和聚合都方便得多。3. 环境准备把 Kafka、Elasticsearch 和 Filebeat 跑起来3.1 环境与版本要求下面以 Kafka 3.5、Elasticsearch 8.8、Logstash 8.8、Filebeat 8.8、Kibana 8.8 为例说明配置方式。实际项目中版本必须提前对齐尤其是 Elasticsearch、Logstash、Filebeat、Kibana 这四者尽量使用同一主版本否则可能出现协议不兼容或字段解析异常。环境要求可以按下表准备依赖项建议值JDK17 或与 Elasticsearch 版本匹配的 JDK内存Filebeat 1GBLogstash 2GBES 4GB 以上Kafka3.x 以上建议使用 KRaft 模式磁盘预留日志索引容量建议 SSD操作系统Linux 发行版均可个人学习和测试环境可以先用 Docker Compose 起单机版生产环境至少考虑三节点 ES 和 Kafka 集群。3.2 启动 Kafka 并创建 TopicKafka 在高版本中推荐使用 KRaft 模式不再依赖 ZooKeeper。下面是启动流程wget https://archive.apache.org/dist/kafka/3.5.0/kafka_2.13-3.5.0.tgz tar -xzf kafka_2.13-3.5.0.tgz cd kafka_2.13-3.5.0 # 生成集群 ID KAFKA_CLUSTER_ID$(bin/kafka-storage.sh random-uuid) # 格式化存储目录 bin/kafka-storage.sh format -t $KAFKA_CLUSTER_ID -c config/kraft/server.properties # 启动 Kafka bin/kafka-server-start.sh config/kraft/server.properties启动后再创建日志专用 Topicbin/kafka-topics.sh --create \ --topic app-log \ --partitions 3 \ --replication-factor 1 \ --bootstrap-server localhost:9092分区数需要根据日志量评估。测试环境 3 个分区够用生产环境建议按吞吐量估算单个分区写入压力有限分区越多 Logstash 并发消费能力越强但 ES 端写入分片也需要同步评估并非越多越好。验证 Topic 是否创建成功bin/kafka-topics.sh --describe --topic app-log --bootstrap-server localhost:90923.3 安装 Filebeat 并读取应用日志Filebeat 是整套链路中最轻量的一层部署在业务服务器上负责读取日志文件。下载安装后重点修改filebeat.ymlfilebeat.inputs: - type: filestream enabled: true paths: - /logs/app/order-service/*.log parsers: - ndjson: target: add_error_key: true output.kafka: hosts: [localhost:9092] topic: app-log partition.round_robin: reachable_only: false required_acks: 1 compression: gzip max_message_bytes: 10485760 logging.level: info这里有几个关键点filestream类型是 Filebeat 7.13 之后推荐的输入方式它比log输入方式更善于管理文件 offset。parsers.ndjson表示按 JSON 解析每一行日志解析结果会作为顶层字段输出到 Kafka。required_acks: 1表示 Kafka 写入确认级别。日志场景可以接受少量丢失优先保证吞吐。max_message_bytes控制单条消息最大值默认 10MB避免异常堆栈超过默认值时直接报错。启动 Filebeat./filebeat -e -c filebeat.yml如果日志目录下已经有历史日志文件Filebeat 会从文件末尾开始读也可通过配置ignore_older和scan_frequency控制读取策略。需要注意新版本默认行为可能与旧版本不同落地前先在小流量环境验证。4. 应用接入从 logback 到 Kafka 的结构化日志4.1 为什么在应用层就做结构化有些团队把日志解析的工作完全交给 Logstash应用层打印普通文本再用正则解析。这个方案能跑通但有两个问题正则解析非常脆弱代码里只要多打印一个空格ES 里的字段就解析失败。应用层不结构化开发人员在本地看日志也不够直观。“雾山实录”推荐的方式是应用层直接输出 JSON 日志Logstash 只做字段补全和类型纠正不依赖复杂正则。这样可以大幅降低清洗层的故障率。4.2 Maven 依赖配置以 Spring Boot 项目为例在pom.xml中加入 logstash-logback-encoderdependency groupIdnet.logstash.logback/groupId artifactIdlogstash-logback-encoder/artifactId version7.4/version /dependency实际项目要根据自己使用的 logback 版本选择匹配的 encoder 版本最好先查看对应版本的兼容说明不要在未确认版本的情况下直接复制依赖。4.3 logback-spring.xml 配置 Kafka Appender要让日志从应用直接写入 Kafka需要在logback-spring.xml中配置 Kafka appender。下面是一个最小可运行配置configuration appender nameKAFKA classcom.github.danielwegener.logback-kafka-appender.KafkaAppender encoder classnet.logstash.logback.encoder.LogstashEncoder includeMdctrue/includeMdc customFields{service:order-service}/customFields throwableConverter classnet.logstash.logback.encoder.composite.loggingevent.ThrowableProxyConverter maxLength20000/maxLength /throwableConverter /encoder topicapp-log/topic keyingStrategy classcom.github.danielwegener.logback-kafka-appender.keying.RoundRobinKeyingStrategy/ producerConfigbootstrap.serverslocalhost:9092/producerConfig producerConfigmax.block.ms1000/producerConfig /appender root levelINFO appender-ref refKAFKA/ /root /configuration这里需要说明logback-kafka-appender 是一个第三方库不同版本对 logback 的兼容性不同。生产环境更稳妥的方式是应用只写本地日志文件Filebeat 再采集日志文件写入 Kafka。这样应用和 Kafka 之间不直接耦合Kafka 短暂不可用时业务日志依然留在磁盘上。“雾山实录”在生产环境采用的就是“应用写文件 - Filebeat 采集”的方式避免第三方 appender 带来的稳定性风险。学习阶段可以直接使用上述配置验证链路生产环境建议退回文件采集方案。4.4 通过 MDC 写入 TraceID日志里的 TraceID 不是自动出现的需要应用在入口处生成并放到 SLF4J 的 MDC 中。下面是典型做法import org.slf4j.MDC; public class TraceIdFilter implements javax.servlet.Filter { Override public void doFilter(javax.servlet.ServletRequest request, javax.servlet.ServletResponse response, javax.servlet.FilterChain chain) throws java.io.IOException, javax.servlet.ServletException { String traceId UUID.randomUUID().toString().replace(-, ); MDC.put(traceId, traceId); try { chain.doFilter(request, response); } finally { MDC.remove(traceId); } } }关键点有两个在 finally 中移除 MDC否则线程池复用线程时TraceID 会串到其他请求上。调用远程服务时需要把 TraceID 放到 HTTP Header 中向下游传递例如X-Trace-Id。logback 配置中使用%X{traceId}可以把 MDC 中的值打进日志appender nameCONSOLE classch.qos.logback.core.ConsoleAppender encoder pattern%date{ISO8601} [%thread] %-5level %logger{36} traceId%X{traceId} - %msg%n/pattern /encoder /appender如果使用 LogstashEncoder并且开启了includeMdctraceId字段会自动出现在 JSON 里。4.5 从源头做敏感信息脱敏日志平台上线后最怕的就是把手机号、身份证号、Token 直接打印到日志里。一旦日志被采集到中央平台删除成本很高因此脱敏必须从源头做起。最基础的做法是定义日志工具类对需要打印的业务对象统一做脱敏处理public class MaskUtils { public static String maskMobile(String mobile) { if (mobile null || mobile.length() ! 11) { return mobile; } return mobile.substring(0, 3) **** mobile.substring(7); } public static String maskIdCard(String idCard) { if (idCard null || idCard.length() 8) { return idCard; } return idCard.substring(0, 4) ********** idCard.substring(14); } }更完整的方式是自定义 logback converter在输出前对日志内容做全局正则替换。注意这种情况下只能在日志内容层面脱敏已经进入业务方法参数里的值是否安全需要结合代码审查一起控制。5. 数据入库Logstash 清洗和 Elasticsearch 索引设计5.1 Logstash Pipeline 核心配置Logstash 负责从 Kafka 拉取日志经过 filter 处理后写入 ES。下面是pipeline.conf的核心配置input { kafka { bootstrap_servers localhost:9092 topics [app-log] group_id logstash-app-log codec json consumer_threads 4 } } filter { mutate { rename { log raw_entry } } date { match [timestamp, ISO8601] timezone Asia/Shanghai } mutate { remove_field [raw_entry, ecs, agent, input] } } output { elasticsearch { hosts [http://localhost:9200] index app-log-%{YYYY.MM.dd} } }这里有几个容易踩坑的地方codec json表示把 Kafka 消息按 JSON 解析。如果应用侧已经按 JSON 输出这里才能正常工作。rename { log raw_entry }是把 Filebeat 包装层留下的原始字段改名避免覆盖真正的日志字段。date插件用来解析timestamp如果日志时间戳是2025-01-15T10:30:00.00008:00使用ISO8601即可。删除ecs、agent、input等字段可以减少 ES 索引体积。生产环境建议保留host和service删除掉无用的元数据字段。5.2 Elasticsearch 索引模板与生命周期为了让日志索引具备合理的分片、副本和字段类型需要提前创建索引模板PUT _index_template/app-log { index_patterns: [app-log-*], template: { settings: { number_of_shards: 3, number_of_replicas: 1, index.lifecycle.name: app-log-policy, index.lifecycle.rollover_alias: app-log }, mappings: { properties: { timestamp: { type: date }, level: { type: keyword }, message: { type: text, analyzer: ik_max_word }, logger: { type: keyword }, traceId: { type: keyword }, spanId: { type: keyword }, service: { type: keyword }, host: { type: keyword }, env: { type: keyword }, exception: { type: text } } } } }字段类型的选择很关键。level、service、traceId这类字段应该用keyword因为它们主要用于精确匹配、聚合、排序message和exception应该用text因为要支持全文检索。如果日志量很大message的全文索引会占用较多磁盘需要结合保留周期一起规划。5.3 创建索引生命周期策略索引生命周期策略用来控制日志保留时间PUT _ilm/policy/app-log-policy { policy: { phases: { hot: { min_age: 0ms, actions: { rollover: { max_size: 50GB, max_age: 30d } } }, delete: { min_age: 180d, actions: { delete: {} } } } } }这个策略的含义是单个索引超过 50GB 或 30 天后滚动新索引日志保留 180 天后删除。生产环境把保留时长作为参数放在配置中心方便按业务和合规要求调整。5.4 写入性能调整当日志量变大时Logstash 和 ES 的默认参数可能不够用。常见调整方向如下参数位置作用调整建议consumer_threadsLogstash 输入增加 Kafka 消费并发与分区数一致不超过分区数batch.sizeLogstash 输出增大批量写入条数默认 125可调到 500 观察index.refresh_intervalES 索引设置控制可检索延迟默认 1s日志场景可调 5sindex.translog.durabilityES 索引设置控制数据落盘策略可调 async 提升性能number_of_shards索引模板控制分片数量根据写入峰量和节点数评估注意索引refresh_interval调大后日志出现在 Kibana 中的时间会更晚。日志平台通常可以接受 5 到 10 秒的延迟不需要追求毫秒级可见。6. 运行验证从乱日志到可检索字段6.1 链路启动检查清单完整链路启动后不要直接去 Kibana 搜日志要先按下面顺序确认每一层是通的Kafka Topic 存在消费者组能看到 Logstash 连接。Filebeat 日志无报错registry 文件有记录。Logstash 管道状态为 running无 error 日志。Elasticsearch 中已经有app-log-*索引。Kibana 中已经创建 Data View。Kafka 查看消费组命令bin/kafka-consumer-groups.sh --describe --group logstash-app-log --bootstrap-server localhost:9092如果消费组LAG一直增大说明 Logstash 消费速度跟不上生产速度需要重点排查 Logstash 输出到 ES 的效率。6.2 制造一条测试日志在业务应用中触发一条 ERROR 日志log.error(库存扣减失败, orderId{}, skuId{}, orderId, skuId, new RuntimeException(stock not enough));然后观察本地日志文件{timestamp:2025-01-15T10:30:00.00008:00,level:ERROR,logger:com.demo.order.service.StockService,message:库存扣减失败, orderId123456, skuId1001,thread:http-nio-8080-exec-3,traceId:a1b2c3d4e5f6a7b8,service:order-service}6.3 在 Kibana 中检索结果在 Kibana 的 Discover 页面用以下查询条件过滤service:order-service AND level:ERROR搜索结果里应该能看到刚才那条日志。点击展开后能直接看到traceId、message、exception等字段。验证检索是否生效还可以测试message的全文搜索message:库存扣减失败如果返回结果为空但精确搜索service字段正常多半是message字段类型写成keyword了。6.4 验证多服务链路串联如果订单服务和库存服务都接入了同一套日志平台可以在业务代码中让库存服务收到请求后从 Header 中读取 TraceID并写入自己的 MDC。这样两边日志里的traceId相同。在 Kibana 中搜索traceId:a1b2c3d4e5f6a7b8如果能看到订单服务、库存服务、网关服务的多条日志按时间顺序排列说明全链路日志关联已经打通。这一步是整个日志平台价值最大、也最容易做坏的地方很多系统虽然接了日志平台但因为没有 TraceID跨服务定位依然靠猜。7. 上线后最常见的问题排查清单7.1 Filebeat 能读文件但 Kafka 没有消息现象Filebeat 启动正常日志文件也有内容Kafka Topic 里却消费不到数据。排查顺序先确认 Topic 名称是否一致filebeat.yml中output.kafka.topic的值必须和 Kafka 中创建的主题完全一致。查看 Filebeat 日志中是否有权限错误或连接失败。查看 Filebeat 的 registry 文件位置确认是否已经消费过该文件。确认日志路径通配符是否匹配实际文件名。如果本地文件有大量历史日志Filebeat 会从文件末尾开始读可以先删除 registry 文件后重启测试但要小心删除 registry 文件可能导致重复消费历史日志。7.2 日志进了 Kafka但 ES 中没有索引现象Kafka 中消息堆积Logstash 消费正常但 ES 没有产生新索引。常见原因常见原因检查方式处理建议Logstash 配置了错误 Topic查看 Logstash 日志修改topics参数ES 认证或分片数超限查看 Logstash 输出日志检查 ES 集群健康状态JSON 解析失败查看 Logstash 日志中_jsonparsefailure回看应用侧日志格式Logstash group_id 与旧版重复查看消费组 offset重置消费组或更换 group_id7.3 时间字段和本地时间差了 8 小时现象日志产生时间是北京时间 18:00Kibana 中显示的却是 10:00。原因很明确日志时间戳带时区但 Logstash 解析时没有指定 timezone或者应用打印时间时使用了 UTC。处理方式统一规范所有应用只输出带时区的 ISO8601 时间。Logstash 的date插件中明确设置timezone Asia/Shanghai。Kibana 高级设置中确认当前时区为Asia/Shanghai或浏览器时区。生产环境建议统一使用 UTC 存储、展示时按本地时区转换避免不同机房、不同环境下出现歧义。7.4 异常堆栈被截断或变成一行不可读现象Kibana 中exception字段只有一半内容或者多行堆栈被折叠成一行。原因有两个方向logback 的ThrowableProxyConverter设置了maxLength堆栈超过长度后被截断。日志写入文件时没有做换行转义Filebeat 按 ndjson 解析失败堆栈被当作多行文本读取。解决方式在 logback 中将maxLength调大到 20000 或 30000同时保证 JSON encoder 对换行符做转义Filebeat 侧使用multiline配置时更要注意不要把 JSON 结构拆开。推荐做法是应用层直接输出单行 JSON由 logstash-logback-encoder 负责把堆栈编码成可解析的 JSON 字符串。7.5 日志重复消费或丢失现象ES 中同一个 traceId 出现两条内容相同的日志或者某个时间点日志缺失。排查重点方向原因处理建议重复消费group.id变更导致 Kafka 从旧 offset 重新消费使用稳定的 group_id记录消费进度重复采集Filebeat registry 被删除避免随意删除 registry 文件日志丢失Filebeat 来不及读取日志被 logrotate 切割调大scan_frequency配置 logrotate 延迟压缩日志丢失Kafkamax.message.bytes小于单条日志大小同步调整 Filebeat 和 Kafka Broker 参数对于“重复消费”日志平台本身可以容忍少量重复关键是不能丢失。因此生产环境 Kafka 的acks可以设置为all相比日志吞吐数据完整性更重要。8. 生产环境最佳实践与下一步扩展8.1 日志分级和采样策略不能所有日志都全量采集否则日志量大到一定程度存储成本会迅速失控。合理的策略是日志级别策略说明ERROR全量采集必须完整保留用于问题定位WARN全量或按错误率采样需要关注但不需要每一条都保留INFO按需保留关键业务日志避免在循环中打印大量 INFODEBUG默认关闭排查时临时开启事后关闭对于调用链日志还可以按 TraceID 做采样。比如 1% 的请求保留完整链路日志其余请求只保留 ERROR 日志这样可以大幅降低日志量同时保留排障能力。8.2 敏感信息脱敏规则日志平台建设越深入安全要求越高。上线前需要建立一份脱敏清单手机号保留前 3 后 4 位中间用****代替。身份证号保留前 4 后 4 位中间脱敏。银行卡号只保留后 4 位。密码、Token、Cookie一律不输出。SQL 参数避免打印用户输入中的敏感内容。脱敏逻辑应该在应用层完成不能只依赖 Logstash 过滤。因为日志一旦落盘或写入 Kafka就存在被其他系统读取的风险。8.3 存储成本控制Elasticsearch 是磁盘占用大户。控制成本的手段包括删除无用字段减少单条日志体积。调整refresh_interval降低索引写入开销。使用索引生命周期策略将旧索引转入冷存储或直接删除。对message和exception字段按需设置全文索引不是所有字段都需要分词。对不需要全文检索的字段使用keyword减少倒排索引开销。注意不要为了省空间把message字段也设成keyword那样等于放弃了关键字检索能力。日志平台的存核心价值就是“能搜到”存储成本要和检索能力一起权衡。8.4 从日志中心走向可观测性“雾山实录”当前版本已经从日志平台扩展成三类数据的统一入口日志Log负责输出业务细节和异常堆栈。指标Metrics用 Prometheus 采集 CPU、内存、QPS、错误率。链路Trace用 SkyWalking 或 Tempo 采集分布式调用链。三类数据用同一个 TraceID 关联排查问题时可以在一套界面上先看指标再点进链路最后看对应日志。这个演进方向比单纯堆日志组件更有价值因为很多线上故障是“指标正常但日志异常”或“日志正常但链路超时”只有三种数据关联起来才能完整还原现场。8.5 可复用的上线检查清单每次新服务接入日志平台建议按下面清单检查检查项检查方式日志文件路径是否被 Filebeat 覆盖查看 Filebeat 配置和日志是否输出 JSON 结构化日志查看本地日志文件是否正确写入 TraceID调用一次接口比对 MDC敏感字段是否脱敏在 Kibana 中搜索手机号、Token 样例日志级别是否关闭 DEBUG检查 logback 配置时区是否统一对比本地时间与 Kibana 展示时间索引模板是否生效查看_index_template和实际索引 settings生命周期策略是否绑定检查索引 setting 中的 ILM 策略消费组是否稳定观察 Kafka 消费组 LAG磁盘容量是否充足监控 ES 节点磁盘使用率这套清单在接入新服务时可以直接复用每项检查时间不超过 5 分钟但能避免 80% 以上的基础配置问题。日志平台这种基础设施最怕的不是组件多而是接入不规范。只要从第一天要求所有应用输出结构化日志、统一 TraceID 格式、明确脱敏规则后面维护成本会低很多。下一步可以重点把链路追踪和日志平台打通再逐步用告警规则替代人工搜索让“雾山实录”从“被动查日志”变成“主动发现问题”的工程基础。