Log4j2 JSON 布局:在 UTC 中添加自定义日期字段

Log4j2 JSON Layout: add custom date field in UTC

Log4j2 支持 JSON Layout,我在 log4j2.xml 中添加了一个额外的自定义字段:

<JsonLayout compact="true" eventEol="true" stacktraceAsString="true">
    <KeyValuePair key="@timestamp" value="$${date:yyyy-MM-dd'T'HH:mm:ss.SSS'Z'}"/>
</JsonLayout>

一般来说,一切正常,但此日志由 Filebeats 处理,并且假定日期以 UTC 格式显示。

所有日志条目都有本地时区的日期值。

是否可以以某种方式输出 UTC 日期?

你可以create your own lookup since, as I'm sure you already know, the KeyValuePair supports lookups in its value attribute per the manual page you shared

出于示例目的,我创建了一个使用 System.currentTimeMillis() 的简单查找。

示例代码如下:

首先,查找class:

package utcTime;

import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.lookup.StrLookup;

@Plugin(name = "UtcMillis", category = "Lookup")
public class UtcMillisLookup implements StrLookup{
    /**
     * Lookup the value for the key.
     * @param key  the key to be looked up, may be null
     * @return The value for the key.
     */
    public String lookup(String key) {
        return String.valueOf(getUTCMillis());
    }

    /**
     * @return current UTC time in milliseconds
     */
    private long getUTCMillis(){
        return System.currentTimeMillis();
    }

    /**
     * Lookup the value for the key using the data in the LogEvent.
     * @param event The current LogEvent.
     * @param key  the key to be looked up, may be null
     * @return The value associated with the key.
     */
    public String lookup(LogEvent event, String key) {
        return String.valueOf(getUTCMillis());
    }
}

接下来,log4j2.xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <JsonLayout compact="true" eventEol="true" stacktraceAsString="true">
                <KeyValuePair key="@timestamp" value="$${UtcMillis:}"/>
            </JsonLayout>
        </Console>

    </Appenders>

    <Loggers>
        <Root level="debug">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

请注意,查找没有 parameters/keys,因此您可以保留那部分 empty/blank,但您仍然必须使用冒号 (:),这就是为什么您会看到 $${UtcMillis:}在上面的配置中。

最后,一个简单的class生成日志事件:

package utcTime;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class MainUtcLookup {
    private static final Logger log = LogManager.getLogger();
    public static void main(String[] args){
        log.info("Here's some info!");
    }
}

这是示例输出:

{  
   "thread":"main",
   "level":"INFO",
   "loggerName":"utcTime.MainUtcLookup",
   "message":"Here's some info!",
   "endOfBatch":false,
   "loggerFqcn":"org.apache.logging.log4j.spi.AbstractLogger",
   "instant":{  
      "epochSecond":1534642997,
      "nanoOfSecond":556000000
   },
   "threadId":1,
   "threadPriority":5,
   "@timestamp":"1534642997558"
}

我不打算深入探讨获取 UTC 毫秒当前时间的所有不同方法的细节,因为我相信您可以自行研究这些细节。我只是想提供一个示例,说明如何实现将毫秒时间戳添加到 log4j2 JSONLayout.

的主要目标

希望对您有所帮助!