In order to improve logs on cloud environment, it is required to write logs in Json format.
- new dependencies need to be added
api("ch.qos.logback:logback-classic:${logback_version}")
api("ch.qos.logback.contrib:logback-jackson:${logback_jackson_version}")
api("ch.qos.logback.contrib:logback-json-classic:${logback_json_classic_version}")
logback_version=1.2.3
# https://mvnrepository.com/artifact/ch.qos.logback.contrib/logback-jackson/0.1.5
logback_jackson_version=0.1.5
# https://mvnrepository.com/artifact/ch.qos.logback.contrib/logback-json-classic/0.1.5
logback_json_classic_version=0.1.5
logback.xml:
nomal log appender:
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
json log appender:
<appender name="json" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
<appendLineSeparator>true</appendLineSeparator>
<jsonFormatter
class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
<prettyPrint>false</prettyPrint>
</jsonFormatter>
<timestampFormat>yyyy-MM-dd' 'HH:mm:ss.SSS</timestampFormat>
</layout>
</appender>
if you want enable the json format log, you just configure the Environment variable : LOG_APPENDER: json
A JsonLayout builds its jsonMap from a source ILoggingEvent with the following keys/value pairs:
Key | Value | Notes |
---|---|---|
timestamp | String value of ILoggingEvent.getTimeStamp() | By default, the value is not formatted; it is simply String.valueOf(timestamp). To format the string using a SimpleDateFormat, set the timestampFormat property with the corresponding SimpleDateFormat string, for example, yyyy-MM-dd HH:mm:ss.SSS. |
level | String value of ILoggingEvent.getLevel() | String value of ILoggingEvent.getLevel() for example log.info get the level is info |
thread | ILoggingEvent.getThreadName() | |
mdc | ILoggingEvent.getMDCPropertyMap() | Unlike the other values which are all Strings, this value is a Map<String,String>. If there is no MDC, this property will not be added to the JSON map. |
thread | ILoggingEvent.getLoggerName() | |
message | ILoggingEvent.getFormattedMessage() | This is the formatted message. The raw (unformatted) message is available as raw-message. Most people will want the formatted message as the raw message does not reflect any log message arguments. |
raw-message | ILoggingEvent.getMessage() | |
exception | ILoggingEvent.getThrowableProxy() | If there is no exception, this property will not be added to the JSON map. If there is an exception, it will be formatted to a String first via a ThrowableProxyConverter. |
context | ILoggingEvent.getLoggerContextVO() | The name of the logger context. Defaults to default. |
examples case :
log before change:
[2021-08-12 18:25:47.953] [RMI TCP Connection(2)-127.0.0.1] ERROR e.d.b.g.s.GameConfigServiceImpl - [PROVIDER: 1] error updating game provider configurationjavax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1514)
at org.hibernate.query.Query$list.call(Unknown Source)
log after change:
{
"timestamp": "2021-08-12 18:07:45.831",
"level": "ERROR",
"thread": "RMI TCP Connection(2)-127.0.0.1",
"mdc": {
"ip": "192.168.1.10"
},
"logger": "eu.digient.billfold.game.service.GameConfigServiceImpl",
"message": "[PROVIDER: 1] error updating game provider configuration",
"context": "default",
"exception": "javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1514)
at org.hibernate.query.Query$list.call(Unknown Source)
......
"
}
REF: https://blog.csdn.net/weixin_33850015/article/details/88659213