Grails - How to Use Native Server Logging Configuration (e.g. Tomcat GlassFish JBoss)

Posted on February 7th, 2010 by Reiner.
Categories: Grails, English.

Grails comes complete with logging out-of-the-box. However, if a Grails application is being deployed to a production servlet container, it may be advisable or even required for Grails to step aside and let the server admins do their jobs :-)

Update: There’s a follow up that includes full source and a ready-to-deploy war. See How to Deploy a Grails Application to JBoss 5.

You need not avoid the loggers injected by Grails in order to use the native logging provided by servlet containers (e.g. Tomcat, GlassFish, JBoss). Grails loggers (always have implemented and now still) implement org.apache.commons.log.Log through jcl-over-slf4j delegating to some slf4j implementation adapter. You’re free to choose which logging system will ultimately perform the “real” logging. This is what we do:

  1. Use the slf4j Implementation adapter that delegates to the native logging supplied by the web server container, e.g. slf4j-log4j12 for JBoss or slf4j-jdk14 for GlassFish / standard Tomcat 6. One (and only one) of those must be packaged within the war.
  2. Remove any logging implementation from our war (e.g. log4j), as it will be supplied by the servlet container (e.g. Log4j with JBoss or Java-logging with GlassFish / standard Tomcat 6.x).
  3. Disable Grails logging configurator.
  4. Use whatever means the web server container offers to configure its logging.

Step 2 can be implemented within grails-app/BuildConfig.groovy similar to:

grails.war.resources = {stagingDir ->
  def toRemove = [
          "$stagingDir/WEB-INF/lib/log4j-1.2.14.jar", // Logging -> native GlassFish/Tomcat/JBoss
          "$stagingDir/WEB-INF/lib/log4j-1.2.15.jar", // "
          "$stagingDir/WEB-INF/classes/log4j.properties", // "
          "$stagingDir/WEB-INF/lib/slf4j-log4j12-1.5.6.jar", // "
          "$stagingDir/WEB-INF/lib/slf4j-log4j12-1.5.8.jar", // "
  ].each {
    delete(file: it)
  }
}

Step 3 can be achieved by altering the web.xml, either verbatim or by means of a grails-app/scripts/_Events.groovy which might looks similar to:

import groovy.xml.StreamingMarkupBuilder

eventWebXmlEnd = {String tmpfile ->

 def root = new XmlSlurper().parse(webXmlFile)

 // remove some log4j stuff
 def log4j = root.listener.findAll {node ->
   node.'listener-class'.text() == 'org.codehaus.groovy.grails.web.util.Log4jConfigListener'
 }
 log4j.replaceNode {}

 def log4jFile = root.'context-param'.findAll {node ->
   node.'param-name'.text() == 'log4jConfigLocation'
 }
 log4jFile.replaceNode {}

 webXmlFile.text = new StreamingMarkupBuilder().bind {
   mkp.declareNamespace("": "http://java.sun.com/xml/ns/j2ee")
   mkp.yield(root)
 }
}

3 comments.

Waseem

Comment on March 4th, 2010.

Hi Reiner,
I followed the steps you mentioned here, however I am getting a hell lot of errors. I pasted them here:http://wb.pastebin.com/utfftdRG

p.s. Im using a local installed JBoss
Please let me know your comments.

Reiner

Comment on March 5th, 2010.

Oops, I’ll have a look at them and try to provide a minimal Grails app for JBoss deployments. I’m afraid, it’ll take till Monday though…

Reiner Saddey’s Place » How to Deploy a Grails Application to JBoss 5

Pingback on March 6th, 2010.

[…] outlined at Grails - How to Use Native Server Logging Configuration (e.g. Tomcat GlassFish JBoss), it may be advisable to remove any conflicting logging implementation when deploying a Grails […]

Leave a comment

Comments can contain some xhtml. Names and emails are required (emails aren't displayed), url's are optional.