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