Log4j定制JSON格式日志输出

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的依赖:

xml 复制代码
  <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的结构。

xml 复制代码
<!--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.日志测试

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

java 复制代码
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
            }
        ]
    }
}
相关推荐
回眸&啤酒鸭8 小时前
【回眸】自动化白盒测试落地实战指南
运维·自动化·log4j
胖头鱼的鱼缸(尹海文)9 小时前
胖头鱼的技术专栏-474 从能跑到能上线:PG SplitJSON 0.2.0 和 0.1.0 差在哪(20261008)
postgresql·json
?? Daisy14 小时前
Claude Code 接入 GPT:settings.json 两种配置方法(2026-10)
gpt·json
小静AI工程实验室17 小时前
Python 爬虫解析 JSON-LD:多块 script、@graph 与坏数据的 9 个边界
爬虫·python·json
goehou2 天前
LLM 结构化输出全解:从 Prompt 约束到 Schema 硬保证,三层实现怎么选
ai·llm·json·agent·教程·结构化输出
独立开发者阿乐2 天前
结构化数据 JSON-LD 实战:让 AI 读懂你的网页
人工智能·json·结构化数据·geo优化·json-ld·ai收录·faqpage
我就是不信2 天前
CuTest:轻量级 C 语言单元测试框架实战指南
c语言·单元测试·log4j
liangshanbo12154 天前
高级前端面试题:package.json 常见字段
前端·json
梦帮科技4 天前
【3.0修订版】创世与节点工程:genesis.json 与 node.toml 解剖
数据结构·算法·json·去中心化·区块链·智能合约·信任链
weixin_440730505 天前
内置函数、json文本、pickle二进制
开发语言·python·json