I am using logstash-logback-encoder to print logs in json format.
My logback.xml
looks like below:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<includeContext>false</includeContext>
<fieldNames>
<timestamp>timestamp</timestamp>
<version>[ignore]</version>
<levelValue>[ignore]</levelValue>
</fieldNames>
</encoder>
</appender>
<appender name="stash"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>/tmp/SolrUpdater.%d{yyyy-MM-dd}.log
</fileNamePattern>
<maxHistory>7</maxHistory>
</rollingPolicy>
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<includeContext>false</includeContext>
<fieldNames>
<timestamp>timestamp</timestamp>
<version>[ignore]</version>
<levelValue>[ignore]</levelValue>
</fieldNames>
</encoder>
</appender>
<root level="error">
<appender-ref ref="CONSOLE" />
<appender-ref ref="stash" />
</root>
</configuration>
Can someone let me know how can I display all level
in lowercase like error
, rather than the default ERROR
and WARN
as warning
?
UPDATE - I created a CustomLogLevelJsonProvider
as suggested by Zakhar:
package com.jabong.discovery.importer.solrUpdater.log;
public class CustomLogLevelJsonProvider extends LogLevelJsonProvider {
final static String DEBUG = "debug";
final static String ERROR = "error";
final static String INFO = "info";
final static String WARNING = "warning";
@Override
public void writeTo(JsonGenerator generator, ILoggingEvent event)
throws IOException {
JsonWritingUtils.writeStringField(generator, getFieldName(),
getCustomLogLevel(event));
}
private String getCustomLogLevel(ILoggingEvent event) {
if (event.getLevel() == Level.ALL) {
return Level.ALL.toString();
}
if (event.getLevel() == Level.DEBUG) {
return DEBUG;
}
if (event.getLevel() == Level.ERROR) {
return ERROR;
}
if (event.getLevel() == Level.INFO) {
return INFO;
}
if (event.getLevel() == Level.WARN) {
return WARNING;
}
return "";
}
}
Updated logback.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="com.jabong.discovery.importer.solrUpdater.log.CustomEncoder">
<includeContext>false</includeContext>
<fieldNames>
<timestamp>timestamp</timestamp>
<version>[ignore]</version>
<levelValue>[ignore]</levelValue>
</fieldNames>
</encoder>
</appender>
<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>/tmp/SolrUpdater.%d{yyyy-MM-dd}.log
</fileNamePattern>
<maxHistory>7</maxHistory>
</rollingPolicy>
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<includeContext>false</includeContext>
<fieldNames>
<timestamp>timestamp</timestamp>
<version>[ignore]</version>
<levelValue>[ignore]</levelValue>
</fieldNames>
</encoder>
</appender>
<root level="error">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
</root>
</configuration>
Now I am seeing two level
:
{"timestamp":"2015-12-26T23:41:08.818+05:30","message":"Partial Updater Initialization Failed ","logger_name":"com.jabong.discovery.importer.solrUpdater.partialupdate.PartialUpdater","thread_name":"main","level":"ERROR","stack_trace":"java.lang.Exception: Failed to Connect to SolrIndex Type:solr, Core:discovery, Host:localhost, Port:8888\n\tat com.jabong.discovery.importer.solrUpdater.partialupdate.PartialUpdater.initIndexUpdater(PartialUpdater.java:83) [classes/:na]\n\tat com.jabong.discovery.importer.solrUpdater.partialupdate.PartialUpdater.initialise(PartialUpdater.java:36) [classes/:na]\n\tat com.jabong.discovery.importer.solrUpdater.partialupdate.PartialUpdater.<init>(PartialUpdater.java:30) [classes/:na]\n\tat Updater.initialise(Updater.java:50) [classes/:na]\n\tat Updater.main(Updater.java:70) [classes/:na]\n","level":"error"}
I do not know if this is somehow configurable via XML. But I just tried to override behavior you do not like. You will need to implement two new classes.
1)
public class CustomEncoder extends LogstashEncoder {
public CustomEncoder() {
LoggingEventJsonProviders providers = getFormatter().getProviders();
// Remove provider that is responsible for log level appending
removeDefaultProvider(providers);
// Register our implementation
providers.addLogLevel(new CustomLogLevelJsonProvider());
}
private void removeDefaultProvider(LoggingEventJsonProviders providers) {
JsonProvider<ILoggingEvent> providerToDelete = null;
for (JsonProvider<ILoggingEvent> provider : providers.getProviders()) {
if (provider instanceof LogLevelJsonProvider) {
providerToDelete = provider;
break;
}
}
providers.removeProvider(providerToDelete);
}
}
2)
public class CustomLogLevelJsonProvider extends LogLevelJsonProvider {
@Override
public void writeTo(JsonGenerator generator, ILoggingEvent event) throws IOException {
JsonWritingUtils.writeStringField(
generator, getFieldName(), event.getLevel().toString().toLowerCase());
}
}
3) Enable new Encoder in config.
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="com.test.encoder.CustomEncoder">
<includeContext>false</includeContext>
<fieldNames>
<timestamp>timestamp</timestamp>
<version>[ignore]</version>
<levelValue>[ignore]</levelValue>
</fieldNames>
</encoder>
</appender>
Update:
You have updated your question. You will need some additional logic to transform WARN or warn to warning. As this will happen on each log message this will create overhead.
Value that you want to change is hardcoded in class: ch.qos.logback.classic.Level