Log4J2 JSONLAYOUT 如何添加自定义参数

4
如何向Log4j2的JSONLAYOUT添加自定义参数?
此外,是否有一种方法可以向JSONLAYOUT的消息元素添加模式?
我已经尝试了此处列出的选项-> logging.apache.org/log4j/2.x/manual/layouts.html#JSONLayout
请帮忙!

https://logging.apache.org/log4j/2.x/manual/layouts.html#JSONLayout - D.B.
@D.B. 谢谢。我已经仔细检查了那个链接,但没有找到如何添加自定义参数的说明。问题是关于添加未在该链接中提及的自定义参数。 - TuneIt
请问您能否澄清一下添加自定义参数的意思是什么? - D.B.
@D.B. 像环境细节、日期格式等参数。在 PatternLayout 中,我将其作为模式的一部分添加,但在这里我没有看到模式起作用。 - TuneIt
你应该分享你所做的任何尝试。查看文档,我没有看到一种定制JSON输出格式的方法。我现在不在电脑旁边,所以等我有机会时我会尝试一些东西。 - D.B.
根据2.10.0版本,https://logging.apache.org/log4j/2.x/manual/layouts.html#JSONLayout解决了此问题! - TuneIt
2个回答

10

解决方法是明确添加log4j2的2.10.0版本。此版本支持在JSONLayout中使用自定义参数!

<Appenders>

    <Console name="Console" target="SYSTEM_OUT">
        <JSONLayout compact="true" eventEol="true">
            <KeyValuePair key="application" value="${sys:com.example.appname}"/>
        </JSONLayout>
    </Console>
    <Async name="AsyncAppender" bufferSize="80">
        <AppenderRef ref="Console"/>
    </Async>

</Appenders>

这里有一篇很好的文章解释了这个问题。它包括XML配置方法和属性方法:https://www.studytonight.com/post/log4j2-jsonlayout-adding-custom-keyvaluepair-fields - iamabhishek

9
据我所知,您正在寻找一种类似于通过指定“转换模式”来自定义“PatternLayout”的方式来自定义JSONLayout的JSON输出格式的方法。 我认为答案是您无法以相同的方式自定义JSONLayout。 您可以选择要包含在消息中的各个信息。例如,文档显示了像属性之类的参数。因此,您可以设置各种参数以包括某些类型的信息,但您无法直接控制包括的特定项目。相反,您可以使用ObjectMessage以及JSON库生成JSON消息。 但是,这将在JSON内部生成JSON(假设您仍希望在此方法中使用JSONLayout)。以下是一些示例代码:
package example;

import java.util.HashMap;
import java.util.Map;

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

public class JsonMessageExample {

    private static final Logger log = LogManager.getLogger();
    
    public static void main(String[] args) {
        Map<String,String> msgMap = new HashMap<>();
        msgMap.put("myKey", "myValue");
        JSONObject message = new JSONObject(msgMap);
        log.info(message);
    }
}

log4j2.xml 配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <JSONLayout/>
        </Console>

    </Appenders>

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

以上输出内容如下:
{
  "timeMillis" : 1510429852038,
  "thread" : "main",
  "level" : "INFO",
  "loggerName" : "example.JsonMessageExample",
  "message" : "{\"myKey\":\"myValue\"}",
  "endOfBatch" : false,
  "loggerFqcn" : "org.apache.logging.log4j.spi.AbstractLogger",
  "threadId" : 1,
  "threadPriority" : 5
}

正如您所看到的,消息名值对有一个JSON字符串的值。为了解析这个,您需要将外部对象解析为JSON,取出消息字段,然后再将其值解析为JSON。
然而,如果您使用另一种布局,比如非常基本的`PatternLayout`,像这样:<PatternLayout pattern="%m%n"/>
您将能够生成一个级别的JSON输出,因此只需解析一次。但是,您需要编写自己的逻辑来获取所有需要的消息数据,并将其放入映射(和JSON对象)中,因为现在您只是简单地倾倒映射的内容。
使用更改为`PatternLayout`的相同Java代码的示例输出如下: {"myKey":"myValue"} 编辑:
甚至可以像以下这样做,如果您想使用`PatternLayout`的“转换模式”以JSON格式输出日志,并且不必编写某些特定内容的逻辑:
<PatternLayout>
    <pattern>{"timeMillis":"%d{UNIX_MILLIS}","thread":"%t","level":"%p","loggerName":"%c","message":%m}%n</pattern>
</PatternLayout>

样例输出:

{"timeMillis":"1510455694601","thread":"main","level":"INFO","loggerName":"example.JsonMessageExample","message":{"myKey":"myValue"}}

感谢您的建议。 有没有其他方法将自定义参数添加到“JSONLayout”中? - TuneIt
1
你可以编写自己的布局。 - D.B.
@D.B. 如何编写自定义布局? - Guerino Rodella
@GuerinoRodella 请查看log4j2手册 - D.B.
这是一个很好的例子,因为PatternLayout非常广泛,但使用它的主要问题是无法在值内部转义引号。例如,您的{"myKey":"myValue"}没有被转义,所以"message"将无法被正确读取,并且会破坏任何读取这些JSON值的解析器。 - jef
@jef 我不同意。输出是有效的 JSON。message 是一个键,其值是一个 JSON 对象。 - D.B.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接