logfellow / logstash-logback-encoder

Logback JSON encoder and appenders
Apache License 2.0
2.43k stars 407 forks source link

NoSuchMethodError: 'java.time.Instant ch.qos.logback.classic.spi.ILoggingEvent.getInstant()' #979

Closed hannes-angst closed 1 year ago

hannes-angst commented 1 year ago

Describe the bug When updating logstash dependency from 7.3 to 7.4. this error is logged instead of any data.

To Reproduce Steps to reproduce the behavior:

  1. Use this logback.xml configuration...

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    
    <springProperty scope="context" name="serviceName" source="spring.application.name"/>
    
    <appender name="JSON" class="net.logstash.logback.appender.LoggingEventAsyncDisruptorAppender">
        <appender class="ch.qos.logback.core.ConsoleAppender">
            <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
                <providers>
                    <timestamp>
                        <fieldName>time</fieldName>
                        <pattern>[UNIX_TIMESTAMP_AS_NUMBER]</pattern>
                    </timestamp>
                    <pattern>
                        <omitEmptyFields>true</omitEmptyFields>
                        <pattern>
                            {
                            "sourceApplication": "${serviceName}"
                            }
                        </pattern>
                    </pattern>
                    <uuid>
                        <fieldName>messageId</fieldName>
                    </uuid>
                    <logLevel>
                        <fieldName>severity</fieldName>
                    </logLevel>
                    <logLevelValue>
                        <fieldName>severity_value</fieldName>
                    </logLevelValue>
                    <message/>
                    <tags/>
                    <mdc/>
                    <logstashMarkers/>
                    <throwableClassName/>
                    <throwableRootCauseClassName/>
                    <stackTrace>
                        <throwableConverter class="net.logstash.logback.stacktrace.ShortenedThrowableConverter">
                            <maxDepthPerThrowable>30</maxDepthPerThrowable>
                            <maxLength>2048</maxLength>
                            <shortenedClassNameLength>20</shortenedClassNameLength>
                            <rootCauseFirst>true</rootCauseFirst>
                            <!-- generated class names -->
                            <exclude>\$\$FastClassByCGLIB\$\$</exclude>
                            <exclude>\$\$EnhancerBySpringCGLIB\$\$</exclude>
                            <exclude>^sun\.reflect\..*\.invoke</exclude>
                            <!-- JDK internals -->
                            <exclude>^com\.sun\.</exclude>
                            <exclude>^sun\.net\.</exclude>
                            <!-- dynamic invocation -->
                            <exclude>^net\.sf\.cglib\.proxy\.MethodProxy\.invoke</exclude>
                            <exclude>^org\.springframework\.cglib\.</exclude>
                            <exclude>^org\.springframework\.transaction\.</exclude>
                            <exclude>^org\.springframework\.validation\.</exclude>
                            <exclude>^org\.springframework\.app\.</exclude>
                            <exclude>^org\.springframework\.aop\.</exclude>
                            <exclude>^java\.lang\.reflect\.Method\.invoke</exclude>
                            <!-- Spring plumbing -->
                            <exclude>^org\.springframework\.ws\..*\.invoke</exclude>
                            <exclude>^org\.springframework\.ws\.transport\.</exclude>
                            <exclude>^org\.springframework\.ws\.soap\.saaj\.SaajSoapMessage\.</exclude>
                            <exclude>^org\.springframework\.ws\.client\.core\.WebServiceTemplate\.</exclude>
                            <exclude>^org\.springframework\.web\.filter\.</exclude>
                            <!-- Tomcat internals -->
                            <exclude>^org\.apache\.tomcat\.</exclude>
                            <exclude>^org\.apache\.catalina\.</exclude>
                            <exclude>^org\.apache\.coyote\.</exclude>
                            <exclude>^java\.util\.concurrent\.ThreadPoolExecutor\.runWorker</exclude>
                            <exclude>^java\.lang\.Thread\.run$</exclude>
                        </throwableConverter>
                    </stackTrace>
                </providers>
            </encoder>
        </appender>
    </appender>
    
    <root level="INFO">
        <appender-ref ref="JSON"/>
    </root>
    </configuration>
  2. Execute this logger statement (e.g. logger.debug(...)) ...

Any log message is affected.

  1. See error, or unexpected output
java.lang.NoSuchMethodError: 'java.time.Instant ch.qos.logback.classic.spi.ILoggingEvent.getInstant()'

    at net.logstash.logback.composite.loggingevent.LoggingEventFormattedTimestampJsonProvider.getTimestampAsInstant(LoggingEventFormattedTimestampJsonProvider.java:29)
    at net.logstash.logback.composite.loggingevent.LoggingEventFormattedTimestampJsonProvider.getTimestampAsInstant(LoggingEventFormattedTimestampJsonProvider.java:25)
    at net.logstash.logback.composite.AbstractFormattedTimestampJsonProvider.writeTo(AbstractFormattedTimestampJsonProvider.java:164)
    at net.logstash.logback.composite.JsonProviders.writeTo(JsonProviders.java:78)
    at net.logstash.logback.composite.AbstractCompositeJsonFormatter.writeEventToGenerator(AbstractCompositeJsonFormatter.java:290)
    at net.logstash.logback.composite.AbstractCompositeJsonFormatter$JsonFormatter.writeEvent(AbstractCompositeJsonFormatter.java:190)
    at net.logstash.logback.composite.AbstractCompositeJsonFormatter.writeEvent(AbstractCompositeJsonFormatter.java:156)
    at net.logstash.logback.encoder.CompositeJsonEncoder.encode(CompositeJsonEncoder.java:106)
    at net.logstash.logback.encoder.CompositeJsonEncoder.encode(CompositeJsonEncoder.java:92)
    at net.logstash.logback.encoder.CompositeJsonEncoder.encode(CompositeJsonEncoder.java:36)
    at ch.qos.logback.core.OutputStreamAppender.subAppend(OutputStreamAppender.java:230)
    at ch.qos.logback.core.OutputStreamAppender.append(OutputStreamAppender.java:102)
    at ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:84)
    at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:51)
    at ch.qos.logback.classic.Logger.appendLoopOnAppenders(Logger.java:270)
    at ch.qos.logback.classic.Logger.callAppenders(Logger.java:257)
    at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:421)
    at ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:383)
    at ch.qos.logback.classic.Logger.info(Logger.java:599)
    ... 
hannes-angst commented 1 year ago

This might be the issue:

https://github.com/logfellow/logstash-logback-encoder/blob/b1e7653914fba93baf6042b15d44e54909879e4f/src/main/java/net/logstash/logback/composite/loggingevent/LoggingEventFormattedTimestampJsonProvider.java#LL29C12-L29C12

hannes-angst commented 1 year ago
hannes-angst commented 1 year ago

In Version 7.3, there is a check that was removed in Version 7.4:

@Override
    protected Instant getTimestampAsInstant(ILoggingEvent event) {
        if (LogbackUtils.isVersion13()) {
            return event.getInstant();
        }
        else {
            return Instant.ofEpochMilli(event.getTimeStamp());
        }
    }
hannes-angst commented 1 year ago

Support of logback 1.2.x was dropped: https://github.com/logfellow/logstash-logback-encoder/commit/ea18315d95596623d50d0473259fbc7f850941cb

kyrylo-merzlikin-blablacar commented 1 year ago

@hannes-angst more specifically, Spring Boot of versions 2.x uses logback 1.2.x. Spring Boot 3 uses logback 1.3.
But given that Spring Boot 2 is pretty widely used and is far from being deprecated, I'm not sure that removing the support for logback 1.2 from logstash-logback-encoder was a good idea

philsttr commented 1 year ago

As mentioned in the release notes for 7.4, support for logback 1.2 was removed.

Spring Boot 2 users will need to continue using logstash-logback-encoder 7.3 until they upgrade to Spring Boot 3.