首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何编写由Log4j2 JSONLayout自动转换为JSON的Java类?

如何编写由Log4j2 JSONLayout自动转换为JSON的Java类?
EN

Stack Overflow用户
提问于 2020-08-28 13:03:22
回答 2查看 582关注 0票数 2

Log4j2的JsonLayout将LogEvent内容转换为JSON,如下所示:

爪哇:

代码语言:javascript
运行
复制
  logger.info("This is an info message");

输出:

代码语言:javascript
运行
复制
{
  "timeMillis" : 1598613343782,
  "thread" : "main",
  "level" : "INFO",
  "loggerName" : "com.example.Test",
  "message" : "This is an info message",
  "endOfBatch" : false,
  "loggerFqcn" : "org.apache.logging.log4j.spi.AbstractLogger",
  "contextMap" : { },
  "threadId" : 1,
  "threadPriority" : 5
}

但是,当一个对象(Bean)被传递给Logger时,它会将消息吐出为字符串。

假设我的豆子是这样的:

代码语言:javascript
运行
复制
public class MyLogBean {
    private String message;
    private String userId;
    private String ip;
    public MyLogBean(String message, String userId, String ip) {
        this.message = message;
        this.userId = userId;
        this.ip = ip;
    }
    public MyLogBean() {}
    public String getMessage() {return message;}
    public void setMessage(String message) {this.message = message;}
    public String getUserId() {return userId;}
    public void setUserId(String userId) {this.userId = userId;}
    public String getIp() {return ip;}
    public void setIp(String ip) {this.ip = ip;}
}

然后,如果尝试使用以下内容编写MyLogBean:

代码语言:javascript
运行
复制
    logger.info(new MyLogBean("UserLogged","john.appleseed@example.com","192.168.1.56"));

输出:

代码语言:javascript
运行
复制
{
  "timeMillis" : 1598613343782,
  "thread" : "main",
  "level" : "INFO",
  "loggerName" : "com.example.Test",
  "message" : "com.example.MyLogBean@328cf0e1",
  "endOfBatch" : false,
  "loggerFqcn" : "org.apache.logging.log4j.spi.AbstractLogger",
  "contextMap" : { },
  "threadId" : 1,
  "threadPriority" : 5
}

它打印"com.example.MyLogBean@328cf0e1"作为消息。

如何让它用JSON编写消息,如下所示:

代码语言:javascript
运行
复制
{
  "timeMillis" : 1598613343782,
  "thread" : "main",
  "level" : "INFO",
  "loggerName" : "com.example.Test",
  "message" : {
      "message":"UserLogged",
      "userId":"john.appleseed@example.com",
      "ip":"192.168.1.56"      
  },
  "endOfBatch" : false,
  "loggerFqcn" : "org.apache.logging.log4j.spi.AbstractLogger",
  "contextMap" : { },
  "threadId" : 1,
  "threadPriority" : 5
}

我需要MyLogBean类由JsonLayout自动转换为JSON。不幸的是,默认情况下,JsonLayout使用toString方法并将所有对象内容作为字符串。

我尝试通过使用MyLogBean接口实现Log4J 消息类将其转换为JSON,但它仍然使用string方法(getFormattedMessage)。即使我将字符串用于JSON转换器,消息也会再次变成字符串,输出也会变成如下所示:

代码语言:javascript
运行
复制
{
  "message" : "{\"message\":\"UserLogin\",\"userId\":\"john\",\"ip\":\"10.2.3.4\"}"
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-09-02 18:51:58

UPDATE:随着Log4J2的2.14.0发布,LogstashLayout现在作为JsonTemplateLayout集成到Log4J2本身中。

事实证明,LogstashLayout是起作用的自定义布局。

  1. "message": "${json:message:json}"文件编写LogstashJsonEventLayoutV1.json
  2. Java必须实现MultiformatMessage并在getFromattedMessage方法中返回JSON字符串。
  3. getMessageFormats()方法还必须返回JSON
票数 2
EN

Stack Overflow用户

发布于 2020-08-28 22:46:26

文档中说你应该做:

代码语言:javascript
运行
复制
<JsonLayout objectMessageAsJsonObject="true"/>

如果所有日志事件都需要userId和ip,则可以将它们添加到ThreadContextMap中。然后,它们将自动出现在contextMap部分,您可以简单地记录您的消息。

另一个选项是在MyLogBean()中包含一个MyLogBean()方法,该方法将相关字段作为JSON返回。

如果不能修改bean类,则可以创建自己的IntrospectingMessage,它接受bean作为参数,并在调用getFormattedMessage时返回所有属性的JSON字符串。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63634337

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档