How to customize or remove default attributes in Log4j2 - JSON Layout
If you want to log only level
and loggerName
than customize like below in your configuration file.
...
<PatternLayout>
<pattern>{"level":"%p","loggerName":"%c"}</pattern>
</PatternLayout>
...
The parameter are described at here. Find Patterns
at Pattern Layout
.
Adding custom field to log4j json layout breaks spring logging structure
- download Jackson Annotations and import it because
JsonLayout
useJackson Annotations
internal code.- in my case, download and import these
jackson-annotations-2.10.3.jar
jackson-core-2.10.3.jar
jackson-databind-2.10.3.jar
- add
<JsonLayout>...</JsonLayout>
in your config(in my case log4j2.xml) like below
<JsonLayout>
<KeyValuePair key="testKey" value="testValue"/>
</JsonLayout>
Replace key
and value
to what you want to use. In my case key
is "testKey" and value
is "testValue"
- run and check your log!
it it my full sample code and xml configuration info.
code
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.ThreadContext;
public class LogTest{
private static final Logger logger = LogManager.getLogger(LogTest.class.getName());
public static void main(String[] args) {
ThreadContext.put("logFileName", "testFile1" );
logger.info("log printed! - testFile1");
ThreadContext.put("logFileName", "testFile2" );
logger.info("log printed! - testFile2");
ThreadContext.remove("logFileName");
}
}
log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Routing name="RoutingAppender">
<Routes pattern="${ctx:logFileName}">
<Route>
<RollingFile name="Rolling-${ctx:logFileName}"
fileName="./logs/${ctx:logFileName}.log"
filePattern="./logs/${ctx:logFileName}.%i.log.gz">
<JsonLayout>
<KeyValuePair key="testKey" value="testValue"/>
</JsonLayout>
<SizeBasedTriggeringPolicy size="512" />
</RollingFile>
</Route>
</Routes>
</Routing>
</Appenders>
<Loggers>
<Root level="all">
<AppenderRef ref="RoutingAppender" />
</Root>
</Loggers>
</Configuration>
output
{
"instant" : {
"epochSecond" : 1588590944,
"nanoOfSecond" : 469000000
},
"thread" : "main",
"level" : "INFO",
"loggerName" : "com.test.LogTest",
"message" : "log printed! - testFile2",
"endOfBatch" : false,
"loggerFqcn" : "org.apache.logging.log4j.spi.AbstractLogger",
"threadId" : 1,
"threadPriority" : 5,
"testKey" : "testValue"
}
Log4J2 JSONLAYOUT How to add custom Parameters
Solution is to explicitly add log4j2’s 2.10.0 version. This version supports custom parameter in JSONLayout!
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<JSONLayout compact="true" eventEol="true">
<KeyValuePair key="application" value="${sys:com.example.appname}"/>
</JSONLayout>
</Console>
<Async name="AsyncAppender" bufferSize="80">
<AppenderRef ref="Console"/>
</Async>
</Appenders>
Log4j2 JSON Layout: add custom date field in UTC
You can create your own lookup since, as I'm sure you already know, the KeyValuePair
supports lookups in its value attribute per the manual page you shared.
For example purposes I created a simple lookup that uses System.currentTimeMillis().
Here is the example code:
First, the lookup class:
package utcTime;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.lookup.StrLookup;
@Plugin(name = "UtcMillis", category = "Lookup")
public class UtcMillisLookup implements StrLookup{
/**
* Lookup the value for the key.
* @param key the key to be looked up, may be null
* @return The value for the key.
*/
public String lookup(String key) {
return String.valueOf(getUTCMillis());
}
/**
* @return current UTC time in milliseconds
*/
private long getUTCMillis(){
return System.currentTimeMillis();
}
/**
* Lookup the value for the key using the data in the LogEvent.
* @param event The current LogEvent.
* @param key the key to be looked up, may be null
* @return The value associated with the key.
*/
public String lookup(LogEvent event, String key) {
return String.valueOf(getUTCMillis());
}
}
Next, the log4j2.xml configuration file:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<JsonLayout compact="true" eventEol="true" stacktraceAsString="true">
<KeyValuePair key="@timestamp" value="$${UtcMillis:}"/>
</JsonLayout>
</Console>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
Note that the lookup has no parameters/keys so you can leave that part empty/blank but you still have to use the colon (:
) and this is why you see $${UtcMillis:}
in the above configuration.
Finally, a simple class to generate a log event:
package utcTime;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class MainUtcLookup {
private static final Logger log = LogManager.getLogger();
public static void main(String[] args){
log.info("Here's some info!");
}
}
Here is sample output:
{
"thread":"main",
"level":"INFO",
"loggerName":"utcTime.MainUtcLookup",
"message":"Here's some info!",
"endOfBatch":false,
"loggerFqcn":"org.apache.logging.log4j.spi.AbstractLogger",
"instant":{
"epochSecond":1534642997,
"nanoOfSecond":556000000
},
"threadId":1,
"threadPriority":5,
"@timestamp":"1534642997558"
}
I'm not going to delve into the details of all the different ways you can get the current time in UTC milliseconds as I'm sure you can research the details of that on your own. I just wanted to provide an example of how you could accomplish your primary goal of adding the millisecond timestamp to your log4j2 JSONLayout
.
Hope this helps!
Related Topics
How to Store a String Longer Than 4000 Characters in an Oracle Database Using Java/Jdbc
How to Convert a One-Dimensional Array to Two-Dimensional Array in Java
How to Update Only the Incoming Fields in a Model Using Spring Data Jpa
Shifting Characters Within a String
Wrong Answer in Task - Mistake in Algorithm
Arraylist: How Does the Size Increase
How to Check Whether a Field Exists or Not in Mongodb
How to Test Code Dependent on Environment Variables Using Junit
How to Check Whether a Given String Is Valid Json in Java
Java Coding Converted to Pseudo Code
Java Socket Api: How to Tell If a Connection Has Been Closed
Null Pointer on an Autowired Bean Which Is Not Mocked by Mockito
Spring Rest - Create Zip File and Send It to the Client
Java Spring Boot Test: How to Exclude Java Configuration Class from Test Context
@Responsebody , Responseentity Spring Return Object as Json
How to Send Date in Rest API in Post Method