package com.commons.logging;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.spi.ILoggingEvent;
import io.micrometer.core.instrument.MeterRegistry;
import net.logstash.logback.encoder.LogstashEncoder;
public class InstrumentedEncoder extends LogstashEncoder {
private static final String METRIC_LINES_NAME = "log_messages_lines";
private static final String METRIC_SIZE_BYTES_NAME = "log_messages_size_bytes";
private static final String LABEL_LEVEL_NAME = "level";
private static MeterRegistry meterRegistry;
private static InstrumentedEncoder instance;
public InstrumentedEncoder() {
instance = this;
}
public static InstrumentedEncoder bind(MeterRegistry other) {
meterRegistry = other;
return instance;
}
@Override
public byte[] encode(ILoggingEvent event) {
byte[] bytes = super.encode(event);
if (meterRegistry != null) {
final String level = switch (event.getLevel().levelInt) {
case Level.ERROR_INT -> "error";
case Level.WARN_INT -> "warn";
case Level.INFO_INT -> "info";
case Level.DEBUG_INT -> "debug";
case Level.TRACE_INT -> "trace";
default -> "unknown";
};
meterRegistry.counter(METRIC_LINES_NAME, LABEL_LEVEL_NAME, level).increment();
meterRegistry.counter(METRIC_SIZE_BYTES_NAME, LABEL_LEVEL_NAME, level).increment(bytes.length);
}
return bytes;
}
}
<!-- logback.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="com.commons.logging.InstrumentedEncoder">
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT"/>
</root>
</configuration>