本系列第 11 篇。分布式系统不会登服务器 tail 文件,而是把日志集中到平台统一检索。这篇讲经典的 Kafka → ELK 链路。

整体链路

应用(logback) --JSON--> Kafka --> Logstash/消费端 --> Elasticsearch --> Kibana 检索

日志先以 JSON 格式推到 Kafka,消费端转存到 Elasticsearch,最后在 Kibana 上按字段检索。

关键点一:日志要输出成 JSON

平台要结构化检索,就不能打纯文本。用 logstash-logback-encoder 提供的 JSON Encoder:

<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
    <providers class="net.logstash.logback.composite.loggingevent.LoggingEventJsonProviders">
        <pattern>
            <pattern>
                {
                  "indexname": "${appName}-%d{yyyy}",
                  "message": "%msg",
                  "level": "%level",
                  "logger": "%logger",
                  "thread": "%thread",
                  "traceId": "%X{traceId}"
                }
            </pattern>
        </pattern>
    </providers>
</encoder>

建议至少包含 levelloggertraceId,方便在 Kibana 里过滤和串联链路。

关键点二:用 KafkaAppender 发送

<appender name="kafkaAppender" class="com.github.danielwegener.logback.kafka.KafkaAppender">
    <producerConfig>bootstrap.servers=${logServers}</producerConfig>
    <producerConfig>retries=0</producerConfig>
    <producerConfig>max.block.ms=2000</producerConfig>
    <producerConfig>request.timeout.ms=2000</producerConfig>
    <encoder ...>...JSON...</encoder>
    <topic>${logTopic}</topic>
    <keyingStrategy class="...HostNameKeyingStrategy"/>         <!-- 按主机名分区 -->
    <deliveryStrategy class="...AsynchronousDeliveryStrategy"/> <!-- 异步投递 -->
</appender>

关键点三:日志绝不能拖垮业务

这是接平台最重要的原则,几个具体手段:

  • retries=0:日志发送失败不重试,避免卡住业务。
  • max.block.ms=2000 / request.timeout.ms=2000:Kafka 不可用时最多阻塞 2 秒,不会无限等。
  • 屏蔽 Kafka 客户端自身日志,防止“日志→Kafka→Kafka 客户端打日志→再进 Kafka”的放大/循环。
  • 再套一层 AsyncAppender

核心原则:日志系统故障绝不能影响主业务。宁可丢日志,不可阻塞下单。

其他平台方案

  • Loki + Grafana:更轻量,适合云原生。
  • 直接 Filebeat 采集文件:应用只管打文件,采集交给 Filebeat,应用侧零侵入,也很常见。

上一篇:自定义 Appender
下一篇:高级篇 · MDC 链路追踪

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐