Grails has some fantastic built-in facilities for logging. If you haven’t see them already, you should check them out.

There is only one problem: what happens if you want to configure your logging outside of Grails at the app server layer? Grails is only one of the apps in our stack, so we prefer to control our logging configuration at the app server JVM layer. Looking at the Grails user guide’s logging section, there is seemingly no clear way of doing this. But if you know one thing about Grails, you know that you can do anything with it. You just have to do some digging. After you do, you’ll find out that Grails is using an app context listener plugin to wrap and control logging in a WAR deployment: org.codehaus.groovy.grails.plugins.log4j.web.util.Log4jConfigListener . This is configured inside the web.xml that is deployed with the app, so you need to modify it before deployment. There are two ways to do this. You can run 

grails install-templates

and edit out the Log4j listener element from src/templates/war/web.xml:

<listener>
   <listener-class>org.codehaus.groovy.grails.plugins.log4j.web.util.Log4jConfigListener</listener-class>
</listener>

Alternatively, you can create a file scripts/_Events.groovy under your app with these contents:

// Add this code to scripts/_Events.groovy under your Grails app
// Removes Log4jConfigListener from Grails web.xml

import groovy.xml.DOMBuilder
import groovy.xml.XmlUtil
import groovy.xml.dom.DOMCategory

eventCreateWarStart = { warName, stagingDir ->

   def webXmlFile = new File(stagingDir, '/WEB-INF/web.xml') 
   def wxml = DOMBuilder.parse(new StringReader(webXmlFile.text)).documentElement

   String className = 'org.codehaus.groovy.grails.plugins.log4j.web.util.Log4jConfigListener'
   use (DOMCategory) {
      def listenerNodes = wxml.'listener'
      for (n in listenerNodes) {
         if (n.'listener-class'.text() == className) {
            wxml.removeChild n
         }
      }
   }

   webXmlFile.withWriter { it << XmlUtil.serialize(wxml) }
}

That’s it!