Grails stacktrace.log

Grails 1.0.x started creating a stacktrace.log file in the directory where the servlet container starts. In a development environment, using grails run-app, that’s simple enough— it appears in the top level of your application. In a production environment, this becomes a problem. Your production container (e.g. Tomcat) may start someplace where it can’t create files, like /. Thus you get exceptions sent to your container’s log files like:

java.io.FileNotFoundException: stacktrace.log (Permission denied)

Also, messages are appended to stacktrace.log– so it will continue to grow if you don’t do something about it. One option is to change where your container starts, e.g. have the startup script change to its logs directory. You can also configure your grails app to change the location of the stacktrace.log file or turn it off completely.

Changing file location

To change the file location/name, edit your grails-app/conf/Config.groovy file. In Grails 1.0.3, you want to change the line:

appender.'stacktraceLog.File'="stacktrace.log"

to something like:

appender.'stacktraceLog.File'="/var/log/myapp/stacktrace.log"

In Grails 1.0, 1.0.1, and 1.0.2, the property is:

appender.'errors.File'="stacktrace.log"

Turning off stacktrace.log

To turn off the log file completely, in 1.0.3 change the line:

StackTrace="error,stacktraceLog"

to:

StackTrace="error"

In previous versions, the original line is:

StackTrace="error,errors"

What we are doing is removing the only appender from the StackTrace logger (automatically created by Grails) so the messages will not be written anywhere (and the file will not be created). The word error that remains indicates the logging level. We could also change it to off to be clear (only doing that without removing the appender will still result in an attempt to create the file).

No stacktrace processing

According to the Grails docs, you can also turn this off by setting a command line property:

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

(yes, true) If you don’t also turn off the logging property, the stacktrace.log file will still be created but won’t be written to. Putting that line in Config.groovy doesn’t do anything. It also doesn’t help when creating a war for deployment. You’ll have to put that property definition into your container startup (setting the environment variable CATALINA_OPTS or adding to your jsvc command line).

Console logging

The docs also suggest sending the stacktrace to the console (for Tomcat 5.x that’s $CATALINA_HOME/logs/catalina.out), by changing the stacktraceLog or errors appender in the above line to stdout, like this:

StackTrace="error,stdout"

But error messages seem to go to the console anyways and so will be doubled.

Environments

You can make these changes for different environments. In Config.groovy add something like this:

environments {
production { log4j.logger.StackTrace="error" }
}

which will turn off the stacktrace logging file for your production environment, but leave it on for development.

Upgrades

I didn’t notice all this until just now with my new grails projects, because my original Grails projects were created before these shenanigans started happening. I’ve done grails upgrade several times since then, but stacktrace.log configuration isn’t yet in the upgrade script.

Tags: ,

Leave a Reply