<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>structured-logging on </title>
    <link>/tags/structured-logging/</link>
    <description>Recent content in structured-logging on </description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Tue, 07 Apr 2026 10:00:00 +0800</lastBuildDate><atom:link href="/tags/structured-logging/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Spring Boot 3.4&#43; 结构化日志实践记录：用 ECS &#43; Fluent API</title>
      <link>/posts/spring-boot-structured-logging-ecs/</link>
      <pubDate>Tue, 07 Apr 2026 10:00:00 +0800</pubDate>
      
      <guid>/posts/spring-boot-structured-logging-ecs/</guid>
      <description>为什么我开始关注结构化输出 Spring Boot 默认的 Logback 输出是人类可读的文本行，形如：
2026-04-07 10:00:00.123 INFO 12345 --- [main] c.e.OrderService : order created orderId=ORD-001 这在本地开发时没有问题，但一旦日志进入 OpenSearch，文本行只能靠全文检索（message: *ORD-001*）来定位，无法按字段过滤、聚合统计或设置告警规则。当并发量上来，同一秒内几百条日志里找一个 orderId 靠的是运气而不是索引。
解决这个问题的方式是让每条日志以结构化 JSON 格式输出，每个上下文值都成为独立字段，可以被 OpenSearch 精确索引和查询。Spring Boot 3.4 正式将这个能力内建进框架，开发者不再需要引入 logstash-logback-encoder 或手写复杂的 XML encoder 配置。
5 行配置启用 ECS 结构化输出 ECS（Elastic Common Schema）是 Elastic 定义的日志字段规范，OpenSearch 原生兼容。Spring Boot 3.4+ 内建了 ECS 格式支持，至少在这个场景里，只需要在 application.yml 里声明：
spring: application: name: order-service logging: structured: format: # console 不设置：本地开发保留 Logback 默认彩色文本（不设置即为默认行为） # console: ecs # 容器环境如需从 stdout 采集，将此行取消注释 file: ecs # 生产输出：ECS JSON file: name: logs/app.</description>
    </item>
    
    <item>
      <title>Java 日志开发实践整理</title>
      <link>/posts/logging-development-guidelines/</link>
      <pubDate>Mon, 06 Apr 2026 10:00:00 +0800</pubDate>
      
      <guid>/posts/logging-development-guidelines/</guid>
      <description>为什么团队最好先约定一套日志写法 日志不是“顺手打印一行字符串”，而是故障排查、审计追踪和可观测性的一部分。没有相对一致的写法时，最常见的问题不是“没有日志”，而是日志很多却无法检索、无法关联、无法长期维护。
典型表现包括：
message 风格混乱，同类事件写法完全不同 关键上下文字段缺失，只能靠全文检索猜测问题链路 敏感信息进入日志，带来合规和安全风险 生产问题无法按 traceId、requestId、订单号或用户 ID 快速定位 本文不讨论“如何随手打一行日志”，而是尝试把日志整理成一套团队更容易落地的开发约定：哪些值得优先做，哪些应尽量避免，哪些是我比较推荐的实践；同时给出 Spring Boot 项目的落地示例和支撑链接。
日志开发的基本原则 日志约定先解决的是可用性，而不是“看起来有日志”。
我更推荐的原则是：message 只描述发生了什么，不承担完整上下文；关键上下文最好通过结构化字段输出；默认假设日志会进入集中平台并长期保留，因此内容最好可检索、可审计、可脱敏。
不建议把日志当成临时调试输出。不要依赖随手拼接字符串来补充上下文，也不要把敏感信息、不可检索的大段文本或纯噪声写进生产日志。
推荐的做法是让 message 与结构化字段组合起来回答三个问题：发生了什么、影响了什么、后续如何定位。这样日志才能服务排障、审计和关联分析。
错误示例：把所有信息拼进 message，无法按字段过滤，也无法聚合统计：
// 上下文全靠字符串拼接，检索只能依赖全文匹配 log.info(&amp;#34;Order &amp;#34; + orderId + &amp;#34; status changed from &amp;#34; + oldStatus + &amp;#34; to &amp;#34; + newStatus + &amp;#34; for user &amp;#34; + userId); 正确示例：message 稳定、简洁，上下文放到结构化字段，可按任意维度检索：
log.atInfo() .setMessage(&amp;#34;order status changed&amp;#34;) .addKeyValue(&amp;#34;orderId&amp;#34;, orderId) .addKeyValue(&amp;#34;fromStatus&amp;#34;, oldStatus) .addKeyValue(&amp;#34;toStatus&amp;#34;, newStatus) .addKeyValue(&amp;#34;userId&amp;#34;, userId) .log(); 日志框架选型与使用建议 团队在日志框架选型时通常会优先考虑解耦和可维护性。我更倾向于在应用代码中使用 SLF4J 作为日志门面，而不是直接绑定具体实现（如 Logback、Log4j2）。这样做的好处是未来切换底层实现时只需更换依赖，无需修改业务代码。</description>
    </item>
    
  </channel>
</rss>
