Why does stacktrace.log not fill with logback in grails 3?

扶醉桌前 提交于 2019-12-14 04:16:24

问题


When you create a new grails application, the default logback.groovy file (and almost every example of a logback.groovy, even Mr Haki's example) contains the following code, which I have simplified to focus on the relevant piece:

root(ERROR, ['STDOUT'])

appender("FULL_STACKTRACE", FileAppender) {
    file = "build/stacktrace.log"
    append = true
    encoder(PatternLayoutEncoder) {
        pattern = "%level %logger - %msg%n"
    }
}
logger("StackTrace", ERROR, ['FULL_STACKTRACE'], false )

However, following this approach does not result in errors being output to the stacktrace.log file.

@JeffScottBrown's answer contained the following Bootstrap.groovy file to test if the stacktrace was logging as expected:

class BootStrap {

    def init = { servletContext ->
        log.error 'this is a new error'
    }
    def destroy = {
    }
}

With that bootstrap file, running the grails application will not produce any output into build/stacktrace.log.

If you remove the StackTrace logger, and add FULL_STACKTRACE to the root logger:

root(ERROR, ['STDOUT', 'FULL_STACKTRACE']

you will get output into the stacktrace.log.

Alternatively, rename the StackTrace logger to grails.app.init.Bootstrap (thanks to @JeffScottBrown for this line):

logger 'grails.app.init.BootStrap', ERROR, ['FULL_STACKTRACE'], false

and you will get output into the stacktrace.log

This observation leads me to believe that the StackTrace logger doesn't do anything. I further am led to believe that any logger not named for a package doesn't work.

As a result of all this, my question is:

  • Does logback work for non-package/class named loggers?
  • If so, why does the StackTrace logger in the default logback.groovy not result in output to stacktrace.log?

EDIT:

  • The main issue for me is that the StackTrace logger seems completely unnecessary, so why is it included in the default file?

Second Edit:

Another way to confirm this is to make only the StackTrace logger write to the STDOUT appender, and watch stacktraces disappear from the console when you throw an exception:

logger("StackTrace", ERROR, ['STDOUT','FULL_STACKTRACE'], false) root(ERROR, [])


回答1:


I expect that you aren't configuring the appender to be used properly.

The following works:

import grails.util.BuildSettings
import grails.util.Environment

// See http://logback.qos.ch/manual/groovy.html for details on configuration
appender('STDOUT', ConsoleAppender) {
    encoder(PatternLayoutEncoder) {
        pattern = "%level %logger - %msg%n"
    }
}

root(ERROR, ['STDOUT'])

def targetDir = BuildSettings.TARGET_DIR
if (Environment.isDevelopmentMode() && targetDir) {
    appender("FULL_STACKTRACE", FileAppender) {
        file = "${targetDir}/stacktrace.log"
        append = true
        encoder(PatternLayoutEncoder) {
            pattern = "%level %logger - %msg%n"
        }
    }
    logger("StackTrace", ERROR, ['FULL_STACKTRACE'], false)
}

logger 'grails.app.init.BootStrap',
        ERROR, ['FULL_STACKTRACE'], false

In BootStrap.groovy...

class BootStrap {

    def init = { servletContext ->
        log.error 'this is a new error'
    }
    def destroy = {
    }
}

That error shows up in stacktrace.log.

EDIT To Address New Questions:

Does logback work for non-package/class named loggers?

Yes.

If so, why does the StackTrace logger in the default logback.groovy not result in output to stacktrace.log?

The StackTrace logger does result in output being written to stacktrace.log for all of the loggers associated with the corresponding appender.




回答2:


change

logger("StackTrace", ERROR, ['FULL_STACKTRACE'], false )

to

logger("grails.app", INFO, ['FULL_STACKTRACE'], false)

will write all the logs in grails-app to stacktrace.log




回答3:


Your log statement in Bootstrap.groovy:

log.error 'this is a new error'

logs a regular ERROR level message to the logger named grails.app.init.yourapp.BootStrap. It does not log to the logger named StackTrace. The FULL_STACKTRACE appender is for unfiltered stacktraces. These are written by the framework to the logger StackTrace.

If you replace

log.error 'this is a new error'

with

throw new RuntimeException("foo")

you will see the full stacktrace being logged to stacktrace.log



来源:https://stackoverflow.com/questions/36723285/why-does-stacktrace-log-not-fill-with-logback-in-grails-3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!