logback doesn't print method or line number

前端 未结 1 1788
你的背包
你的背包 2021-01-27 02:08

This is in a Gradle project using Groovy for the app code as well as test code. But I\'m using a logback.xml file for configuration.

One factor here that may be signific

相关标签:
1条回答
  • 2021-01-27 02:38

    logback.groovy

    appender("STDOUT", ConsoleAppender) {
      encoder(PatternLayoutEncoder) {
        pattern = "%d{HH:mm:ss.SSS} [%thread] %-5level {%logger} - %class.%method:%line - %msg%n"
      }
    }
    root(DEBUG, ["STDOUT"])
    

    X.groovy

    @GrabConfig(systemClassLoader=true)
    @GrabResolver(name='maven2',root='http://repo1.maven.org/maven2/')
    @Grab(group='ch.qos.logback', module='logback-classic', version='1.2.3')
    @Grab(group='org.slf4j', module='slf4j-api', version='1.7.30')
    
    import groovy.util.logging.Slf4j
    
    @Slf4j
    class A {
        def f() {
            log.info 'msg-info-2'       //line 11
            log.with{
                info  'msg-info-1'      //line 13
                //new Exception("test").printStackTrace(System.out)
            }
        }
    }
    
    def a = new A()
    a.f()
    

    The command groovy X.groovy prints:

    12:24:43.134 [main] INFO  {A} - A.f:11 - msg-info-1
    12:24:43.139 [main] INFO  {A} - sun.reflect.NativeMethodAccessorImpl.invoke0:-2 - msg-info-2
    

    why

    in logback there is a class CallerData with method extract that extracts caller data information as an array based on a Throwable parameter and returns an array of StackTraceElement. It tries to cleenup the stacktrace, however for groovy it could be really complex.

    For example if you uncomment the line new Exception("test").printStackTrace(System.out)

    You'll see stacktrace like this:

    java.lang.Exception: test
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        ... + 11 elements
        at A$_f_closure1.doCall(X.groovy:14)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        ... + 15 elements
        at A.f(X.groovy:12)
        ... + 20 elements
    

    CallerData tries to skip the technical groovy elements from stacktrace but fails to detect the right one.


    solution

    It's possible to modify the Framework Packages for the logback context.

    I don't know how to do that from logback.xml, but I found how to do it using logback.groovy

    logback.groovy (modified)

    maybe for your case you have to add another framework (ignored) packages...

    context.getFrameworkPackages().addAll([
        "sun.reflect", 
        "java.lang.reflect", 
        "org.codehaus.groovy", 
        "groovy.lang.MetaMethod",
        "jdk.internal.reflect"
        ])
    
    appender("STDOUT", ConsoleAppender) {
      encoder(PatternLayoutEncoder) {
        pattern = "%d{HH:mm:ss.SSS} [%thread] %-5level {%logger} - %class.%method:%line - %msg%n"
      }
    }
    root(DEBUG, ["STDOUT"])
    

    with this configuration the code above prints lines correctly:

    13:12:14.410 [main] INFO  {A} - A.f:11 - msg-info-2
    13:12:14.416 [main] INFO  {A} - A$_f_closure1.doCall:13 - msg-info-1
    
    0 讨论(0)
提交回复
热议问题