4

编码器模式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到每条日志消息来解决这个问题。这个问题的想法是提供一种可配置的方法。

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

4

1 回答 1

2

LogbackPatternLayout包含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>
    

有了这些更改,您的自定义转换器将被启用,输出将如下所示......

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

1847637306发出日志事件的类的 hashCode在哪里。

笔记:

  • 在上述实现中,我假设您感兴趣的 hashCode 是发出日志事件的类的 hashCode。如果这不是您感兴趣的,那么您将更改HashCodeConverter
  • 尽管上述获取发出日志事件的类的方法是 Logback 中的标准做法,但它确实需要生成堆栈跟踪,并且在大容量日志环境中为每个日志事件执行此操作可能会非常昂贵。如果是这样,那么在每条消息中包含 hashCode 可能是您唯一的选择。
于 2018-05-29T08:36:04.600 回答