Log4J2 JSONLAYOUT 如何添加自定义参数[英] Log4J2 JSONLAYOUT How to add custom Parameters

本文是小编为大家收集整理的关于Log4J2 JSONLAYOUT 如何添加自定义参数的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

如何将自定义参数添加到log4j2的jsonlayout?

还有一种方法可以将模式添加到jsonlayout的消息元素?

我尝试了此处列出的选项 - >
logging.apache.org/log4j/2.x/manual/layouts.html#jsonaylayout

请帮助!

推荐答案

解决方案是明确添加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>

其他推荐答案

我理解,您正在寻找一种从JSONLayout自定义JSON输出格式的方法,其方式类似于如何通过指定"转换模式"来自定义PatternLayout.

我相信答案是您不能以相同的方式自定义JSONLayout.您 can 选择要包含在消息中的各种信息.例如, documentation 显示:

如果为true,则appender在生成的JSON中包含线程上下文映射.默认为false.

因此,您可以设置各种参数以包括某些类型的信息,但是您对所包括的特定项目没有直接控制.

您可以做的是将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对象)中,因为现在您只需倾倒地图的内容.

使用相同Java代码的样本输出,其布局更改为PatternLayout,如上所述:

{"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"}}

本文地址:https://www.itbaoku.cn/post/1575203.html

问题描述

How to add customized parameters to Log4j2’s JSONLAYOUT?

Also is there a way to add pattern to the JSONLAYOUT’s message element?

I have tried the options listed here ->
logging.apache.org/log4j/2.x/manual/layouts.html#JSONLayout

Please help!

推荐答案

Solution is to explicitly add log4j2’s 2.10.0 version. This version supports custom parameter in 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>

其他推荐答案

As I understand it you're looking for a way to customize the format of the JSON output from the JSONLayout in a manner similar to how you can customize the PatternLayout by specifying "Conversion Patterns".

I believe the answer is that you can't customize the JSONLayout in the same manner. You can select the various pieces of information you want to be included in the message. For example, the documentation shows parameters like properties:

If true, the appender includes the thread context map in the generated JSON. Defaults to false.

So you can set various parameters to include certain kinds of information, but you don't have the direct control over the specific items that are included.

What you could do instead is to use ObjectMessage along with a JSON library to generate a JSON message. However, this would generate JSON within JSON (assuming you still wish to use JSONLayout with this approach). Here is some sample code to illustrate:

A class with a main method to generate a log message:

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);
    }
}

The log4j2.xml config file:

<?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>

The output from the above:

{
  "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
}

As you can see, the message name value pair has a value that is a JSON string. In order to parse this you would have to parse the outer object as JSON, pull the message field and then parse its value as JSON as well.

However, if you use a different layout such as a very basic PatternLayout like this: <PatternLayout pattern="%m%n"/>

You will be able to generate just one level of JSON output and therefore only have to parse once. However, you would have to write your logic to obtain all of the data that you need in your message and stuff it into your map (and JSON object) because now you're simply dumping the contents of the map.

Sample output using same java code with the layout changed to PatternLayout as described above:

{"myKey":"myValue"}

EDIT:

You could even do something like the following if you want to use the "Conversion Patterns" of PatternLayout, output logs in JSON format, and not have to write the logic to obtain some of the specifics:

<PatternLayout>
    <pattern>{"timeMillis":"%d{UNIX_MILLIS}","thread":"%t","level":"%p","loggerName":"%c","message":%m}%n</pattern>
</PatternLayout>

Sample output:

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