如何使用Java生成指定格式的JSON结构化日志
Java生成指定格式JSON日志实现方法
你需要输出的是标准结构化JSON格式日志,不建议手动硬拼接字符串,容易出现转义错误、格式不合法问题,以下是两种可直接运行的实现方案:
方案1:生产环境通用方案(推荐)
基于日志门面SLF4J+Logback、Jackson序列化实现,是Java后端开发的标准实践,性能稳定、格式不会出错。
- 第一步:引入Maven依赖(如果是Gradle自行调整对应坐标即可)
<dependencies> <!-- 日志框架核心包 --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.11</version> </dependency> <!-- JSON序列化核心包 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.13.3</version> </dependency> </dependencies>
- 第二步:定义日志字段实体类,自动生成符合要求的UTC格式时间戳
import java.time.Instant; import java.time.format.DateTimeFormatter; public class BizLogDTO { private String log_level; private String timestamp; private String event_type; private String capture_id; private String cap_pid; private String deb; private String no_id; private String msg_id; private String module; // 构造时自动生成符合ISO-8601规范的UTC时间,末尾带Z标识,和样例格式一致 public BizLogDTO(String log_level, String event_type, String capture_id, String cap_pid, String deb, String no_id, String msg_id, String module) { this.log_level = log_level; this.timestamp = DateTimeFormatter.ISO_INSTANT.format(Instant.now()); this.event_type = event_type; this.capture_id = capture_id; this.cap_pid = cap_pid; this.deb = deb; this.no_id = no_id; this.msg_id = msg_id; this.module = module; } // 生成所有字段的getter方法,Jackson序列化时需要调用 public String getLog_level() {return log_level;} public String getTimestamp() {return timestamp;} public String getEvent_type() {return event_type;} public String getCapture_id() {return capture_id;} public String getCap_pid() {return cap_pid;} public String getDeb() {return deb;} public String getNo_id() {return no_id;} public String getMsg_id() {return msg_id;} public String getModule() {return module;} }
- 第三步:编写测试代码输出日志
import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.UUID; public class LogGenTest { private static final Logger logger = LoggerFactory.getLogger(LogGenTest.class); private static final ObjectMapper objectMapper = new ObjectMapper(); public static void main(String[] args) throws Exception { // 按业务场景传入对应字段值 BizLogDTO logDTO = new BizLogDTO( "INFO", "abc_c", "400011", "00053716", "0100", "0011", // 可直接调用UUID方法生成和样例格式一致的唯一消息ID UUID.randomUUID().toString(), "S_TH" ); // 序列化为标准JSON字符串后输出 String logContent = objectMapper.writeValueAsString(logDTO); logger.info(logContent); } }
如果需要和样例完全一致的微秒级时间戳,使用JDK9及以上版本运行即可;JDK8默认输出毫秒级时间,不影响日志格式合法性。
方案2:新手快速测试方案(无额外依赖)
如果只是临时做练习不想引入第三方依赖,可以用JDK原生API拼接JSON,注意做好格式校验:
import java.time.Instant; import java.time.format.DateTimeFormatter; import java.util.LinkedHashMap; import java.util.Map; import java.util.StringJoiner; public class SimpleLogGen { public static void main(String[] args) { // 用LinkedHashMap保证字段输出顺序和样例一致 Map<String, String> logFields = new LinkedHashMap<>(); logFields.put("log_level", "INFO"); logFields.put("timestamp", DateTimeFormatter.ISO_INSTANT.format(Instant.now())); logFields.put("event_type", "abc_c"); logFields.put("capture_id", "400011"); logFields.put("cap_pid", "00053716"); logFields.put("deb", "0100"); logFields.put("no_id", "0011"); logFields.put("msg_id", "d8c5derbn5-63cb-11ec-8980-0242ac110004"); logFields.put("module", "S_TH"); // 拼接JSON结构 StringJoiner jsonJoiner = new StringJoiner(",", "{", "}"); logFields.forEach((key, value) -> jsonJoiner.add("\"" + key + "\":\"" + value + "\"")); // 输出最终日志 System.out.println(jsonJoiner); } }
注意:你提供的样例日志末尾
"module":"S_TH}缺少闭合双引号,属于非法JSON格式,实际输出时需要补全引号,否则会导致日志解析失败。
内容的提问来源于stack exchange,提问作者abcd efgh
相关产品推荐
相关产品推荐

