向json发送logj4消息

时间:2017-04-10 09:10:24

标签: java json logging log4j log4j2

我有一条消息可以说delay=1, name=Ash我要使用log4j2进行记录。我的日志文件的每一行我都希望它是json格式的那样

{"@timestamp": 1234, "delay"=1, "name"="Ash"}

@timestamp字段是记录器生成的时间戳,而delayname字段是消息的字段。

有办法吗?通过使用JsonLayout我知道我可以以json格式记录每个记录的输出但仍然没有找到操作日志消息的方法,以便我可以将它的不同部分放在不同的字段中。 / p>

2 个答案:

答案 0 :(得分:2)

您可以使用log4j2 JSONLayout执行此操作。

  • 首先,您必须指定jsonlayout

示例:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <JSONLayout compact="true" eventEol="true" properties="true"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

如果你设置了compact = false,json将以prity格式打印

  • 其次,您可以ThreadContext将值作为键值对。

示例:

for (int i = 0; i < 5; i++) {
    ThreadContext.clearAll();
    ThreadContext.put("delay", String.valueOf(i));
    ThreadContext.put("name", "Ash " + i);
    LOGGER.info("Testing ", "k1", "v1", "k2", "v2");
}

此处ThreadContext保留所有键值对,直至您清除。

输出:

{"timeMillis":1491819918389,"thread":"main","level":"INFO","loggerName":"com.ashraful.ilpexp.LogTest","message":"Testing ","endOfBatch":false,"loggerFqcn":"org.apache.logging.log4j.spi.AbstractLogger","contextMap":{"delay":"0","name":"Ash 0"},"threadId":1,"threadPriority":5}
{"timeMillis":1491819918504,"thread":"main","level":"INFO","loggerName":"com.ashraful.ilpexp.LogTest","message":"Testing ","endOfBatch":false,"loggerFqcn":"org.apache.logging.log4j.spi.AbstractLogger","contextMap":{"delay":"1","name":"Ash 1"},"threadId":1,"threadPriority":5}
{"timeMillis":1491819918504,"thread":"main","level":"INFO","loggerName":"com.ashraful.ilpexp.LogTest","message":"Testing ","endOfBatch":false,"loggerFqcn":"org.apache.logging.log4j.spi.AbstractLogger","contextMap":{"delay":"2","name":"Ash 2"},"threadId":1,"threadPriority":5}
{"timeMillis":1491819918505,"thread":"main","level":"INFO","loggerName":"com.ashraful.ilpexp.LogTest","message":"Testing ","endOfBatch":false,"loggerFqcn":"org.apache.logging.log4j.spi.AbstractLogger","contextMap":{"delay":"3","name":"Ash 3"},"threadId":1,"threadPriority":5}
{"timeMillis":1491819918505,"thread":"main","level":"INFO","loggerName":"com.ashraful.ilpexp.LogTest","message":"Testing ","endOfBatch":false,"loggerFqcn":"org.apache.logging.log4j.spi.AbstractLogger","contextMap":{"delay":"4","name":"Ash 4"},"threadId":1,"threadPriority":5}

答案 1 :(得分:0)

试试这个:

<强> log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
    <Appenders>
        <Console name="STDOUT" target="SYSTEM_OUT">
            <PatternLayout pattern='{"@timestamp": %d{UNIX_MILLIS}, "delay"=%X{delay}, "name"="%X{name}"}%n'/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="STDOUT"/>
        </Root>
    </Loggers>
</Configuration>

<强> Utils.java

public class Utils {

  private static final Logger logger = LogManager.getLogger();

  public static void logMsg(long delay, String name) {
    ThreadContext.put("delay", delay + "");
    ThreadContext.put("name", name);
    logger.info("");
  }
}

<强>输出

{"@timestamp": 1491821218548, "delay"=1, "name"="hello"}

<强>更新

实际上,我更喜欢直接在代码中构建日志消息字符串。

e.g。

public static void logMsg(long delay, String name) {
  String s = String.format("{\"@timestamp\":%s, \"delay\"=%s, \"name\"=\"%s\"}", System.currentTimeMillis(), delay, name);
  logger.info(s);
}

注意:将log4j2.xml模式布局更改为

<PatternLayout pattern='%msg%n'/>