Log4j2的JsonLayout将LogEvent内容转换为JSON,如下所示:
爪哇:
logger.info("This is an info message");
输出:
{
"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
时,它会将消息吐出为字符串。
假设我的豆子是这样的:
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:
logger.info(new MyLogBean("UserLogged","john.appleseed@example.com","192.168.1.56"));
输出:
{
"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编写消息,如下所示:
{
"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转换器,消息也会再次变成字符串,输出也会变成如下所示:
{
"message" : "{\"message\":\"UserLogin\",\"userId\":\"john\",\"ip\":\"10.2.3.4\"}"
}
发布于 2020-09-02 18:51:58
UPDATE:随着Log4J2的2.14.0发布,LogstashLayout现在作为JsonTemplateLayout集成到Log4J2本身中。
事实证明,LogstashLayout是起作用的自定义布局。
"message": "${json:message:json}"
文件编写LogstashJsonEventLayoutV1.json
。MultiformatMessage
并在getFromattedMessage
方法中返回JSON字符串。getMessageFormats()
方法还必须返回JSON
。发布于 2020-08-28 22:46:26
文档中说你应该做:
<JsonLayout objectMessageAsJsonObject="true"/>
如果所有日志事件都需要userId和ip,则可以将它们添加到ThreadContextMap中。然后,它们将自动出现在contextMap部分,您可以简单地记录您的消息。
另一个选项是在MyLogBean()中包含一个MyLogBean()方法,该方法将相关字段作为JSON返回。
如果不能修改bean类,则可以创建自己的IntrospectingMessage,它接受bean作为参数,并在调用getFormattedMessage时返回所有属性的JSON字符串。
https://stackoverflow.com/questions/63634337
复制相似问题