【发布时间】:2021-09-18 23:28:03
【问题描述】:
我在通过 log4j 打印上下文变量时遇到问题。 如果变量为空,则打印如下: { "status":"${ctx:status}" }
但我希望它像这样打印: {“状态”:“”}
请与我分享你的想法。
【问题讨论】:
-
你能出示一下代码吗?
标签: java spring spring-boot log4j
我在通过 log4j 打印上下文变量时遇到问题。 如果变量为空,则打印如下: { "status":"${ctx:status}" }
但我希望它像这样打印: {“状态”:“”}
请与我分享你的想法。
【问题讨论】:
标签: java spring spring-boot log4j
我想为s7vr's 回答添加一些细节。我完全同意答案,但有解决办法。打印空值的问题取决于jackson-databind 库。如果你使用如下的值模式
<KeyValuePair key="status" value="$${ctx:status:-}"/>
如果想在最终的json对象中放入空字符串,可以使用jackson-databind不高于2.10.5的版本。
这意味着以下配置将起作用:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.14.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.5</version>
</dependency>
【讨论】:
对于变量查找返回 null 或缺失的情况,您最好提供 非空 默认值。当前实现在无法解析时按原样返回值。添加默认值会在无法解析时返回默认值。
<KeyValuePair key="status" value="$${ctx:status:-missingornullorempty}"/>
添加一个空的默认值将从日志消息中删除该字段,因为 log4j json 对象映射器配置为仅包含非空字段 (https://github.com/apache/logging-log4j2/blob/master/log4j-layout-jackson-json/src/main/java/org/apache/logging/log4j/jackson/json/Log4jJsonObjectMapper.java#L48),目前无法配置对象映射器 (https://issues.apache.org/jira/browse/LOG4J2-2670) .
【讨论】:
如果不显示您当前的实现,很难知道已经尝试过什么。下面的代码是一个记录变量的方法。
private static DataNotFoundException notFound(final long id) {
log.warn("Event not found for id: {}", id);
return new DataNotFoundException("No group event found with id " + id);
}
如果下面是返回 null 的,那么我们可以使用 Log4j2 的 NullAppender 类。我建议查看 Apache documentation 以获取实现以下内容所需的样板代码:
@Plugin(name = "Stub", category = "Core", elementType = "appender", printObject = true)
public final class StubAppender extends AbstractOutputStreamAppender<StubManager> {
private StubAppender(String name,
Layout<? extends Serializable> layout,
Filter filter,
boolean ignoreExceptions,
StubManager manager) {
super(name, layout, filter, ignoreExceptions, true, manager);
}
@PluginFactory
public static StubAppender createAppender(@PluginAttribute("name") String name,
@PluginAttribute("ignoreExceptions") boolean ignoreExceptions,
@PluginElement("Layout") Layout layout,
@PluginElement("Filters") Filter filter) {
if (name == null) {
LOGGER.error("No name provided for StubAppender");
return null;
}
StubManager manager = StubManager.getStubManager(name);
if (manager == null) {
return null;
}
if (layout == null) {
layout = PatternLayout.createDefaultLayout();
}
return new StubAppender(name, layout, filter, ignoreExceptions, manager);
}
}
【讨论】: