## 3.1.2 Logging

#### Logging Basics

Grails uses its common configuration mechanism to configure the underlying Log4j log system. To configure logging you must modify the file `Config.groovy` located in the `grails-app/conf` directory.

This single `Config.groovy` file allows you to specify separate logging configurations for `development`, `test`, and `production` environments. Grails processes the `Config.groovy` and configures Log4j appropriately.

Since 1.1 Grails provides a Log4j DSL, that you can use to configure Log4j an example of which can be seen below:

    log4j = {
        error  'org.codehaus.groovy.grails.web.servlet',  //  controllers
    	       'org.codehaus.groovy.grails.web.pages' //  GSP    warn   'org.mortbay.log'
    }

Essentially, each method translates into a log level and you can pass the names of the packages you want to log at that level as arguments to the method.

Some useful loggers include:

- `org.codehaus.groovy.grails.commons` - Core artefact information such as class loading etc.
- `org.codehaus.groovy.grails.web` - Grails web request processing
- `org.codehaus.groovy.grails.web.mapping` - URL mapping debugging
- `org.codehaus.groovy.grails.plugins` - Log plugin activity
- `org.springframework` - See what Spring is doing
- `org.hibernate` - See what Hibernate is doing

#### The Root Logger

The Root logger is the logger that all other loggers inherit from. You can configure the Root logger using the root method:

    root {
        error()
        additivity = true
    }

The above example configures the root logger to log messages at the error level and above to the default standard out appender. You can also configure the root logger to log to one or more named appenders:

    appenders {
    	file name:'file', file:'/var/logs/mylog.log'
    }
    root {
        debug 'stdout', 'file'
        additivity = true
    }

Here the root logger will log to two appenders - the default 'stdout' appender and a 'file' appender.

You can also configure the root logger from the argument passed into the Log4J closure:

    log4j = { root ->
        root.level = org.apache.log4j.Level.DEBUG
        …
    }

The closure argument "root" is an instance of `org.apache.log4j.Logger` , so refer to the API documentation for Log4J to find out what properties and methods are available to you.

#### Custom Appenders

Using the Log4j you can define custom appenders. The following appenders are available by default:

- `jdbc` - An appender that logs to a JDBC connection
- `console` - An appender that logs to standard out
- `file` - An appender that logs to a file
- `rollingFile` - An appender that logs to rolling set of files

For example to configure a rolling file appender you can do:

    log4j = {
    	appenders {
    		rollingFile name:"myAppender", maxFileSize:1024, file:"/tmp/logs/myApp.log"
    	}
    }

Each argument passed to the appender maps to a property of underlying Appender class. The example above sets the `name`, `maxFileSize` and `file` properties of the RollingFileAppender class.

If you prefer to simply create the appender programmatically yourself, or you have your own appender implementation then you can simply call the `appender` method and appender instance:

    import org.apache.log4j.*log4j = {
    	appenders {
    		appender new RollingFileAppender(name:"myAppender", maxFileSize:1024, file:"/tmp/logs/myApp.log")
    	}
    }

You can then log to a particular appender by passing the name as a key to one of the log level methods from the previous section:

    error myAppender:"org.codehaus.groovy.grails.commons"

#### Custom Layouts

By default the Log4j DSL assumes that you want to use a PatternLayout. However, there are other layouts available including:

- `xml` - Create an XML log file
- `html` - Creates an HTML log file
- `simple` - A simple textual log
- `pattern` - A Pattern layout

You can specify custom patterns to an appender using the `layout` setting:

    log4j = {
    	appenders {
            console name:'customAppender', layout:pattern(conversionPattern: '%c{2} %m%n')
        }
    }

This also works for the built-in appender "stdout", which logs to the console:

    log4j = {
        appenders {
            console name:'stdout', layout:pattern(conversionPattern: '%c{2} %m%n')
        }
    }

#### Full stacktraces

When exceptions occur, there can be an awful lot of noise in the stacktrace from Java and Groovy internals. Grails filters these typically irrelevant details and restricts traces to non-core Grails/Groovy class packages.

When this happens, the full trace is always written to the `StackTrace` logger. This logs to a file called `stacktrace.log` - but you can change this in your `Config.groovy` to do anything you like. For example if you prefer full stack traces to go to standard out you can add this line:

    error stdout:"StackTrace"

You can completely disable stacktrace filtering by setting the `grails.full.stacktrace` VM property to `true`:

    grails -Dgrails.full.stacktrace=true run-app

#### Logging by Convention

All application artefacts have a dynamically added `log` property. This includes domain classes, controllers, tag libraries and so on. Below is an example of its usage:

    def foo = "bar"
    log.debug "The value of foo is $foo"

Logs are named using the convention `grails.app.<artefactType>.ClassName`. Below is an example of how to configure logs for different Grails artefacts:

    log4j = {
    	// Set level for all application artefacts
    	info "grails.app"
    	// Set for a specific controller
    	debug "grails.app.controller.YourController"
    	// Set for a specific domain class
    	debug "grails.app.domain.Book"
    	// Set for all taglibs
    	info "grails.app.tagLib"}

The artefacts names are dictated by convention, some of the common ones are listed below:

- `bootstrap` - For bootstrap classes
- `dataSource` - For data sources
- `tagLib` - For tag libraries
- `service` - For service classes
- `controller` - For controllers
- `domain` - For domain entities