8

Grails 3 uses logback as the default system of logging.

I need a example of how use logback in grails 3 in this form

log.info("some Info")
Tung
  • 1,579
  • 4
  • 15
  • 32

5 Answers5

14

You have to set the fourth argument of the logger config to false:

logger('grails.app.controllers', INFO, ['STDOUT'], false)

then the logging is not displayed twice.

I think that's because the root logger catches INFO too.

Stefan van den Akker
  • 6,661
  • 7
  • 48
  • 63
Pascal
  • 2,059
  • 3
  • 31
  • 52
  • 3
    You don't have to add the 'false' (i.e. additivity flag) if you also remove the `['STDOUT']` part. You get duplicate logging because (without the false), you're telling logback to append via the root logger (to STDOUT) AND via this specific logger. Removing STDOUT means it will only append via the root logger. See [the documentation](http://logback.qos.ch/manual/architecture.html) for an explanation of the additivity flag. – GreenGiant May 06 '16 at 18:43
  • @GreenGiant 's comment was the solution for me in Grails 3.2.1. Logging worked well for "run-app" but not for "test-app". Then I noticed that the root logger configuration treated "dev" specially. I just expanded the logic to include the 'test' env, then logging appeared with no duplicates: `if ((Environment.isDevelopmentMode() || Environment.currentEnvironment == Environment.TEST) ...) { ...` – jerryb Feb 01 '17 at 11:20
  • Logback Additivity Example → https://examples.javacodegeeks.com/enterprise-java/logback/logback-additivity-example/ – pinei Jun 13 '17 at 14:03
4

I was just looking into this, because I had similar a similar question. Grails 3 does use Logback for logging configuration, but the AST transform still uses Apache Commons Logging.

https://github.com/grails/grails-core/blob/master/grails-logging/src/main/groovy/org/grails/compiler/logging/LoggingTransformer.java

It then uses the jcl-over-slf4j bridge to map it all back into all back into Logback.

According to the mailing list, http://grails.1312388.n4.nabble.com/Grails-2-1-1-Is-it-possible-to-replace-the-injected-log-object-td4638834.html, to replace the injected log globally, you have to exclude the logging dependencies and replace the AST Transformer with your own.

The Logback plugin that the blog post in the comment above mentions provides this: https://github.com/grails-plugins/grails-logback/blob/master/src/java/org/codehaus/groovy/grails/compiler/logging/Slf4jTransformer.java. However, it seems like a lot of redundancy, as Grails 3 already has Logback support.

If you don't want to go through that work to change the log injection, you can override the logger by annotating the class with @Slf4j and that will override the logger for that class.

atreides322
  • 159
  • 1
  • 11
2
import org.slf4j.Logger
import org.slf4j.LoggerFactory

static Logger log = LoggerFactory.getLogger(SomeClass.class)

This works but I'm also wondering if grails 3 can auto inject log.

ericbado
  • 203
  • 1
  • 9
1

I tried like this and it works fine. This is from petclinic example.

Additional details avalable at logback docs

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


appender('STDOUT', ConsoleAppender) {
    encoder(PatternLayoutEncoder) {
        pattern = "%level %logger - %msg%n"
    }
}

root(ERROR, ['STDOUT'])

if(Environment.current == Environment.DEVELOPMENT) {
    def targetDir = BuildSettings.TARGET_DIR
    if(targetDir) {

        appender("FULL_STACKTRACE", FileAppender) {

            file = "${targetDir}/stacktrace.log"
            append = true
            encoder(PatternLayoutEncoder) {
                pattern = "%level %logger - %msg%n"
            }
        }
        logger("StackTrace", ERROR, ['FULL_STACKTRACE'], false )
    }
}
demon101
  • 544
  • 1
  • 11
  • 39
user3877963
  • 348
  • 3
  • 7
  • I've run into an issue that has made me question this code: did you confirm that data is actually going into the stacktrace.log file? It may look like it is working because stacktraces hit stdout, but my experience has been that it doesn't actually hit the stacktrace.log file. So I'm trying to figure out if it is just me or if this is an issue with almost all the examples on the internet. – Ryan Heathcote Apr 19 '16 at 15:27
  • See [this question](http://stackoverflow.com/questions/36723285/why-does-stacktrace-log-not-fill-with-logback-in-grails-3) -- it appears that this will not log to the stacktrace.log file. – Ryan Heathcote Apr 19 '16 at 20:17
0

Needed this as well in Grails 3. Found this post by mrhaki:

grails 3 logging

I tested this on a Quartz job. I added the following line in logback.groovy

logger("grails.app.jobs", INFO, ['STDOUT'])

Using test log in the quartz job:

log.info "test " + new Date()

shows log info in the console

INFO grails.app.jobs.myapp.TestJob - test Tue Oct 20 10:07:31 CEST 2015

Funny thing is happening. I see 2 duplicate lines for each log.info

log.info "test"
log.info "test2"
System.out.println("test"3)

Gives me:

INFO grails.app.jobs.myapp.TestJob - test
INFO grails.app.jobs.myapp.TestJob - test
INFO grails.app.jobs.myapp.TestJob - test2
INFO grails.app.jobs.myapp.TestJob - test2
test3
A.W.
  • 2,858
  • 10
  • 57
  • 90
  • 1
    Adding `false` to `logger("grails.app.jobs", INFO, ['STDOUT'], false)` will remove duplicate log entries. – A.W. May 03 '16 at 07:36