如何在logback的编码器模式中显示实例的身份哈希码?

时间:2018-05-27 15:51:59

标签: logging logback logback-classic slf4j-api

logback.xml中的编码器模式

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
</appender>

允许使用当前线程和类名等上下文信息来增强日志记录消息。是否有可能在消息中显示身份哈希码(由System.identityHashcode(Object)返回)?我不会介意子类形式的自定义扩展,即使每个类或包的配置都很好。我根本不知道从哪里开始。

我知道我可以通过在每条日志消息中添加System.identityHashcode来解决此问题。这个问题的想法是提供一种可配置的方法。

我通过SLF4J API 1.7.25访问logback-classic 1.2.3,但不介意升级到1.8.x快照。

1 个答案:

答案 0 :(得分:1)

Logback的PatternLayout包含defaultConverterMap,它将转换字(%n%msg%d等)映射到ch.qos.logback.core.pattern.Converter的实现。这就是你所说的:

  

使用当前线程和类名

等上下文信息增强日志记录消息

要在日志输出中包含hashCode,您可以提供自己的ch.qos.logback.core.pattern.Converter实现,并将其与自定义转换字关联,如下所示...

  1. 将其添加到logback.xml

    <conversionRule conversionWord="hc" converterClass="some.package.HashCodeConverter" />
    
  2. 按如下方式实施some.package.HashCodeConverter

    import ch.qos.logback.classic.pattern.ClassicConverter;
    import ch.qos.logback.classic.spi.ILoggingEvent;
    import ch.qos.logback.classic.spi.CallerData;
    
    public class HashCodeConverter extends ClassicConverter {
        @Override
        public String convert(ILoggingEvent le) {
            StackTraceElement[] cda = le.getCallerData();
            if (cda != null && cda.length > 0) {
                return Integer.toString(System.identityHashCode(cda[0]));
            } else {
                return CallerData.NA;
            }
        }
    }
    
  3. 更新编码器模式以使用转换字hc

    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss}|[%thread]|%-5level|%logger{36}|%hc|%msg %n</pattern>
    </encoder>
    
  4. 随着这些变化的到位,您的自定义转换器将被启用,输出将如下所示......

    2018-05-29 09:30:09|[main]|INFO |o.g.sandbox.logback.LogbackTest|1847637306|hello! 
    

    其中1847637306是发出日志事件的类的hashCode。

    注意:

    • 在上面的实现中,我假设您感兴趣的hashCode是发出日志事件的类的hashCode。如果那不是您感兴趣的,那么您将更改HashCodeConverter
    • 的实现
    • 虽然上面获取发出日志记录事件的类的方法是Logback中的标准做法,但它确实需要生成堆栈跟踪,并且在高容量日志环境中对每个日志事件执行此操作可能会非常昂贵。如果是这样,那么在每条消息中包含hashCode可能是您唯一的选择。