Log4j定制JSON格式日志输出

embedded/2025/2/12 13:08:43/

1.前言

log4j是Java中一个强大的日志记录框架,通过简单的配置便可以在程序中进行日志打印与记录。关于log4j博主最近碰到一个需求,需要将程序运行过程中的日志按给定的json模板输出,本文记录一下log4j如何配置json格式的日志打印。

2.日志配置

2.1依赖配置

本文使用的是log4j 2.x版本,log4j的核心为log4j API( 接口)和log4j Core(实现),它可以通过桥接器log4j-slf4j-impl兼容其他的日志框架如SLF4J等。另外,由于需要支持json日志输出,需要引入log4j-layout-template-json

根据以上说明,下面给出具体maven的依赖:

  <dependencies><dependency><!-- SLF4J API --><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.22</version></dependency><!-- Log4j 2 API --><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-api</artifactId><version>2.17.2</version></dependency><!-- Log4j 2 Core --><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.17.2</version></dependency><!-- SLF4J to Log4j 2 Bridge --><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-slf4j-impl</artifactId><version>2.17.2</version></dependency><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-layout-template-json</artifactId><version>2.17.2</version></dependency></dependencies>

2.2日志行为设置

通过log4j2.xml来配置日志打印的行为,为了使用json格式来输出和保存日志,使用了JsonTemplateLayout,该布局可以通过eventTemplate[Uri]stackTraceElementTemplate[Uri]来自定义json的结构。

<!--log4j2.xml配置内容-->
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn"><Properties><property name="LOG_HOME">log</property><property name="MAX_SIZE">100MB</property></Properties><Appenders><!--控制台输出--><Console name="Console" target="SYSTEM_OUT"><!-- 使用 JsonTemplateLayout 输出日志 --><JsonTemplateLayout eventTemplateUri="classpath:template.json"/></Console><!--文件输出--><RollingFile name="File" fileName="log/res.log" filePattern="log/res-%d{yyyy-MM-dd}-%i.log"><!-- 使用 JsonTemplateLayout 输出日志 --><JsonTemplateLayout eventTemplateUri="classpath:template.json"/><!-- 定义滚动策略 --><Policies><!--日志文件超过了设定的大小, 会触发日志文件的滚动, 根据filePattern创建新的日志文件--><!--旧的日志文件会附加编号,例如res-1.log, res-2.log--><SizeBasedTriggeringPolicy size="${MAX_SIZE}"/></Policies><!--限制只保留最近的5个日志文件--><DefaultRolloverStrategy max="5" fileIndex="min"/></RollingFile></Appenders><Loggers><Root level="debug"><AppenderRef ref="Console"/><AppenderRef ref="File"/></Root></Loggers>
</Configuration>

JSON模板

log4j官方给出了自定义的模板JsonLayout.json,参考该配置,本文简单定义了如下的template.json模板:

json">{"Thread": {"$resolver": "thread","field": "name"},"ErrorCode": "${ctx:ErrorCode}","Timestamp": "${date:yyyy-MM-dd HH:mm:ss}","Message": {"$resolver": "message","stringified": true},"Thrown": {"message": {"$resolver": "exception","field": "message"},"name": {"$resolver": "exception","field": "className"},"extendedStackTrace": {"$resolver": "exception","field": "stackTrace"}}
}

说明:

  • 模板中的{ "$resolver": "message", "stringified": true }由由 JSON 模板布局编译器解释,并替换为引用的事件或堆栈跟踪模板解析器。
  • 通过ThreadContext可以往json模板动态传值,例如模板中的${ctx:ErrorCode}

3.日志测试

根据上面的配置,定义一个测试类进行日志打印测试:

package com.example.log;import org.apache.logging.log4j.ThreadContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class TraceLogTest {static Logger log =  LoggerFactory.getLogger(TraceLogTest.class);public static void main(String[] args) {// 设置上下文变量ThreadContext.put("ErrorCode", "1024");// 记录日志try{int i = 1 / 0;}catch (Exception e){log.error("Log test", e);}// 清除上下文变量ThreadContext.clearAll();}
}

运行上述代码的记录的日志(格式化后)如下:

json">{"Thread": "main","ErrorCode": "1024","Timestamp": "2025-02-10 14:35:27","Message": "Log test","Thrown": {"message": "/ by zero","name": "java.lang.ArithmeticException","extendedStackTrace": [{"class": "com.example.log.TraceLogTest","method": "main","file": "TraceLogTest.java","line": 15}]}
}

http://www.ppmy.cn/embedded/161600.html

相关文章

5.14.哈夫曼树

一.带权路径长度&#xff1a; 1.如结点3&#xff0c;从树的根到该结点的路径长度为3&#xff0c;该结点的权值为3&#xff0c;因此结点3的带权路径长度为3 * 39&#xff1b; 2.求树的带权路径长度举例&#xff1a; 二.哈夫曼树的构造&#xff1a; 1.结点下面的1&#xff0c;2&…

【前端】【面试】ref与reactive的区别

ref 与 reactive 的区别笔记 一、概述 在 Vue 3 的组合式 API 中&#xff0c;ref 和 reactive 是两个非常重要的响应式工具&#xff0c;它们都用于创建响应式数据&#xff0c;但在使用方式、适用场景和内部实现上存在一些区别。 二、基本使用方式 1. ref ref 用于创建一个…

Redis 集群工作原理? 如何通信?MOVED和ASKED 有什么区别

目录 Redis 集群工作原理 1. 数据分片 2. 节点角色 3. 自动故障转移 Redis 集群通信方式 1. Gossip 协议 2. TCP 通信 MOVED 和 ASK 错误的区别 1. MOVED 错误 2. ASK 错误 Redis 集群工作原理 1. 数据分片 Redis 集群采用哈希槽(Hash Slot)来实现数据的分片存储…

从词袋到Transformer:自然语言处理的演进与实战

自然语言处理(NLP)是人工智能领域中最具挑战性和吸引力的方向之一。从最早的规则系统到如今的深度学习模型,NLP技术的发展历程充满了创新与突破。本文将带你深入探讨NLP的核心技术演进,并通过代码和案例展示如何从简单的词袋模型过渡到强大的Transformer架构。 1. 词袋模型…

浅谈Deepseek MoE

文章目录 Deepseek MoE1. MoE的定义1.1 什么是MoE&#xff08;Mixture of Experts&#xff09;&#xff1f;1.2 传统MoE的架构1.2.1 专家网络&#xff08;Experts&#xff09;1.2.2 门控网络&#xff08;Gating Network&#xff09; 1.3 传统MoE的工作流程1.4 传统MoE的特点1.5…

Linux内核实时机制x - 实时性之中断响应优化

Linux内核实时机制x - 实时性之中断响应优化 在基于PREEMPT_RT的Linux实时系统&#xff0c;社区开发了一套测试工具集rt-test&#xff0c;用于测试实时系统的各种指标。 其中重点关注的指标有&#xff1a; 中断响应时间 Cyclitest信号混洗时间 sigwaittest死锁解除时间 ptsem…

matlab基础

文章目录 数据类型符号表向量、矩阵操作多项式单元数组结构型变量 数据类型 常量&#xff1a; 1. pi #圆周率 2. inf #无穷大 3. NaN #无效值 变量&#xff1a; 1. char #字符型数据&#xff0c;属于整型数据的一种&#xff0c;占用1 个字节。 2. unsigned char #无符…

在 Flutter 实现下拉刷新、上拉加载更多和一键点击回到顶部的功能

在 Flutter 中&#xff0c;实现下拉刷新、上拉加载更多和一键点击回到顶部的功能&#xff0c;通常会结合使用 RefreshIndicator、ListView 和 ScrollController 来实现这些交互效果。下面分别介绍如何实现这些功能。 1. 下拉刷新 Flutter 提供了 RefreshIndicator 组件来实现…