I am having a problem with printing my context variables by log4j. If variable is null then it's printed like: { "status":"${ctx:status}" }
But I want it to be printed like: { "status":"" }
Please share your ideas with me.
I am having a problem with printing my context variables by log4j. If variable is null then it's printed like: { "status":"${ctx:status}" }
But I want it to be printed like: { "status":"" }
Please share your ideas with me.
You are better off providing non empty default value for cases where the variable look up returns null or missing. The current implementation returns the value as is when it can not be resolved. Adding a default value would return the default value when it can't be resolved.
<KeyValuePair key="status" value="$${ctx:status:-missingornullorempty}"/>
Adding an empty default value will remove the field from log message as the log4j json object mappper is configured to only include non empty field (https://github.com/apache/logging-log4j2/blob/master/log4j-layout-jackson-json/src/main/java/org/apache/logging/log4j/jackson/json/Log4jJsonObjectMapper.java#L48) and currently there is no way to configure the object mapper (https://issues.apache.org/jira/browse/LOG4J2-2670).
without dispalying your current implementation it is rather hard to know what has already been attempted. The following code is a method that logs a variable.
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);
}
If the following is what returns a null, then we can use the NullAppender class of Log4j2. I advise looking at the Apache documentation for the boilerplate code necessary to implement the following:
@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);
}
}
I wanted to add some details for s7vr's answer. I totally agree with answer, but there is work around. The issue with printing empty value is depended on jackson-databind library. If you use value pattern as below
<KeyValuePair key="status" value="$${ctx:status:-}"/>
and want to put empty string in final json object, you can use the version of jackson-databind no newer than 2.10.5.
This means the following configuration will work:
<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>