知識庫 / JSON RSS 訂閱

獲取日誌輸出為JSON格式

JSON,Logging
HongKong
5
09:54 PM · Dec 05 ,2025

1. 簡介

目前大多數 Java 日誌庫都提供不同的佈局選項,用於格式化日誌,以滿足每個項目的需求。

在本快速教程中,我們想將日誌條目格式化為 JSON 格式。 我們將瞭解如何使用兩個最常用的日誌庫:Log4j2 和 Logback。

它們都使用 Jackson 內部來表示日誌為 JSON 格式。

要了解這些庫的介紹,請查看我們的《Java 日誌簡介》文章。

2. Log4j2

Log4j2 是最流行的 Java 日誌庫 Log4j 的直接後繼者。

作為 Java 項目的新標準,我們將演示如何將其配置為輸出 JSON。

2.1. Maven 依賴

首先,我們需要在我們的 <em >pom.</em >xml 文件中包含以下依賴項:

<dependencies>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.19.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.19.0</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.17.2</version>
    </dependency>
</dependencies>

最新版本的先前依賴項可以在 Maven Central 上找到:log4j-api, log4j-core, jackson-databind.

2.2. 使用 JsonLayout

然後,在我們的 log4j2.xml文件中,我們可以創建一個使用 JsonLayout和新的LoggerAppender

<Appenders>
    <Console name="ConsoleJSONAppender" target="SYSTEM_OUT">
        <JsonLayout complete="false" compact="false">
            <KeyValuePair key="myCustomField" value="myCustomValue"/>
        </JsonLayout>
    </Console>
</Appenders>

<Logger name="CONSOLE_JSON_APPENDER" level="TRACE" additivity="false">
    <AppenderRef ref="ConsoleJSONAppender"/>
</Logger>

如示例配置所示,我們可以使用 KeyValuePair 添加自定義值到日誌中,該選項甚至支持查看日誌上下文。

compact 參數設置為 false 將增加輸出的大小並使其更易於閲讀。

現在,讓我們測試我們的配置。在我們的代碼中,我們可以實例化新的 JSON 日誌器並生成新的調試級別的跟蹤記錄:

Logger logger = LogManager.getLogger("CONSOLE_JSON_APPENDER");
logger.debug("Debug message");

先前代碼的調試輸出消息將是:

{
  "instant" : {
    "epochSecond" : 1696419692,
    "nanoOfSecond" : 479118362
  },
  "thread" : "main",
  "level" : "DEBUG",
  "loggerName" : "CONSOLE_JSON_APPENDER",
  "message" : "Debug message",
  "endOfBatch" : false,
  "loggerFqcn" : "org.apache.logging.log4j.spi.AbstractLogger",
  "threadId" : 1,
  "threadPriority" : 5,
  "myCustomField" : "myCustomValue"
}

2.3. 使用 <em >JsonTemplateLayout</em >

在上一節中,我們看到了如何使用 <em >JsonLayout</em > 屬性。自版本 2.14.0 起,該屬性已被棄用並替換為 <em >JsonTemplateLayout</em >

<em >JsonTemplateLayout</em >> 提供增強功能和提高效率,因為它默認優化為以最快的速度編碼日誌事件。

此外,它支持無垃圾回收日誌記錄,因此在垃圾回收暫停對性能產生影響的情況下,具有一定的性能優勢。要啓用無垃圾回收日誌記錄,我們需要將 <em >log4j2.garbagefreeThreadContextMap</em ><em >log4j2.enableThreadLocals</em >> 屬性設置為 true:

-Dlog4j2.garbagefreeThreadContextMap=true 
-Dlog4j2.enableThreadlocals=true 

要使用 <em >JsonTemplateLayout</em >》,請將log4j-layout-template-json> 依賴添加到 <em >pom.xml</em >> 中:

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-layout-template-json</artifactId>
    <version>2.24.3</version>
</dependency>

接下來,讓我們修改我們的 Appender,使用 JsonTemplateLayout 代替:

<Appenders> 
    <Console name="ConsoleJSONAppender" target="SYSTEM_OUT">
        <JsonTemplateLayout eventTemplateUri="classpath:JsonLayout.json">
            <EventTemplateAdditionalField key="myCustomField" value="myCustomValue"/>
        </JsonTemplateLayout>
    </Console>
</Appenders>

這裏我們使用 JsonTemplateLayout 並使用 eventTemplateUri 指定 JSON 佈局格式。 eventTemplateUri 定義 JSON 輸出的格式。當 eventTemplateUri 未指定時,它將使用 Elastic Common Schema (ECS) 格式作為默認值 (classpath:EcsLayout.json)。

其他支持的模板包括 Graylog Extended Log Format (GELF) ,值為 classpath:GelfLayout.json

JsonLayout.json 模板旨在輕鬆地從 JsonLayout 轉換為 JsonTemplateLayout。 在我們的情況下,我們使用 JsonLayout.json 以保持先前部分示例的初始格式:

{
  "instant": {
    "epochSecond": 1736320992,
    "nanoOfSecond": 804274875
  },
  "thread": "main",
  "level": "DEBUG",
  "loggerName": "CONSOLE_JSON_APPENDER",
  "message": "Debug message",
  "endOfBatch": false,
  "loggerFqcn": "org.apache.logging.log4j.spi.AbstractLogger",
  "threadId": 1,
  "threadPriority": 5,
  "myCustomField": "myCustomValue"
}

JsonLayout 採用 KeyValuePair 屬性添加自定義鍵值對的方式不同,我們使用名為 EventTemplateAdditionalField 的屬性來添加鍵和值。

3. Logback

Logback 可以被認為是 Log4j 的又一繼任者。它由相同的開發者編寫,並聲稱比其前身更高效、更快。

因此,讓我們看看如何配置它以獲得日誌輸出的 JSON 格式。

3.1. Maven 依賴

以下依賴項應包含在我們的 <em pom.xml</em> 中:

<dependencies>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.4.8</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback.contrib</groupId>
        <artifactId>logback-json-classic</artifactId>
        <version>0.1.5</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback.contrib</groupId>
        <artifactId>logback-jackson</artifactId>
        <version>0.1.5</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.15.2</version>
    </dependency>
</dependencies>

我們可以在這裏查看這些依賴項的最新版本: logback-classic, logback-json-classic, logback-jackson, jackson-databind

3.2. 使用 JsonLayout

首先,我們在我們的 logback-test.xml 中創建一個新的 appender,該 appender 使用 JsonLayoutJacksonJsonFormatter

之後,我們可以創建一個使用該 appender 的新的 logger

<appender name="json" class="ch.qos.logback.core.ConsoleAppender">
    <layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
        <jsonFormatter
            class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
            <prettyPrint>true</prettyPrint>
        </jsonFormatter>
        <timestampFormat>yyyy-MM-dd' 'HH:mm:ss.SSS</timestampFormat>
    </layout>
</appender>

<logger name="jsonLogger" level="TRACE">
    <appender-ref ref="json" />
</logger>

如我們所見,參數 prettyPrint 啓用後,可以獲得可讀的 JSON。

為了測試我們的配置,讓我們在代碼中實例化日誌記錄器並記錄一條調試消息:

Logger logger = LoggerFactory.getLogger("jsonLogger");
logger.debug("Debug message");

通過這 – 我們將獲得以下輸出:

{
    "timestamp":"2017-12-14 23:36:22.305",
    "level":"DEBUG",
    "thread":"main",
    "logger":"jsonLogger",
    "message":"Debug message",
    "context":"default"
}

3.3. 使用 <em >JsonEncoder</em >

使用 JSON 格式記錄輸出的另一種方式是使用 <em >JsonEncoder</em >。它將日誌事件轉換為有效的 JSON 文本。

讓我們添加一個新的 <em >appender</em >,它使用 <em >JsonEncoder</em >,以及一個使用此 <em >appender</em >> 的新 <em >logger</em >>

<appender name="jsonEncoder" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="ch.qos.logback.classic.encoder.JsonEncoder"/>
</appender>

<logger name="jsonEncoderLogger" level="TRACE">
    <appender-ref ref="jsonEncoder" />
</logger>

現在,讓我們實例化logger並調用debug()來生成一條日誌消息:

Logger logger = LoggerFactory.getLogger("jsonEncoderLogger");
logger.debug("Debug message");

執行此代碼後,我們得到以下輸出:

{
    "sequenceNumber":0,
    "timestamp":1696689301574,
    "nanoseconds":574716015,
    "level":"DEBUG",
    "threadName":"main",
    "loggerName":"jsonEncoderLogger",
    "context":
        {
            "name":"default",
            "birthdate":1696689301038,
            "properties":{}
        },
    "mdc": {},
    "message":"Debug message",
    "throwable":null
}

在此,message 字段表示日誌消息。context 字段則顯示日誌上下文。通常情況下,它為 default,除非我們已設置多個日誌上下文。

4. 結論

在本文中,我們瞭解到如何輕鬆配置 Log4j2 和 Logback 以生成 JSON 輸出格式。我們將解析的複雜性委託給了日誌庫,因此我們無需修改任何現有的日誌器調用。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.