Mini tutorial, log4j en Grails

El siguiente mini tutorial intenta explicar como configurar Grails para que ciertas clases (las que nosotros queramos) escriban sus logs en un fichero distinto. Esto puede ser necesario si, por ejemplo, hemos programado un componente en concreto usando varias clases que generan muchas trazas, y el fichero de log general de nuestro servidor de aplicaciones nos las muestra todas juntas y mezcladas, haciendo difícil el seguimiento de errores. Lo que vamos a hacer es:

  • Configurar log4j para que cree un fichero de log independiente llamado pepito.log
  • Configurar una clase para que escriba sus trazas en este fichero de log.

Primero tenemos que editar el fichero grails-app/conf/Config.groovy y añadirle un nuevo appender y una categoría nueva en la sección log4j.

log4j = {
    appenders {
        console name: 'stdout', layout: pattern(conversionPattern: '%d{yyyy-MM-dd HH:mm:ss} %-5p [%c{2}] %m%n')

        rollingFile name:'pepitoAppender', file: "/tmp/pepito.log", append: true, 
            layout: pattern(conversionPattern: '%d{yyyy-MM-dd HH:mm:ss} %-5p [%c{2}] %m%n')
    }

    info pepitoAppender:'pepito', additivity:false
    ...
}

El atributo additivity:false indica que si se usa ese appender, no se utilice ninguno otro más. De esta manera se evita que los logs salgan, además, en la salida standard y, por lo tanto, en el fichero de log principal de nuestro servidor de aplicaciones.

Ahora tenemos que especificar en cada una de las clases (nuestro controladores, servicios, etc) que utilice nuestra categoría “pepito”. Para ello, utilizaremos el constructor LogFactory.getLog() indicando como parámetro un String que empiece siempre con "pepito.", por ejemplo "pepito.xxxx" o "pepito."+MiClase.class.getName()

package pepito
import org.apache.commons.logging.*

class PepitoController {

    private static Log log = LogFactory.getLog("pepito."+PepitoController.class.getName())

    def index = {
        log.info "Esto debería salir en pepito.log"
    }
}

Si utilizamos Tomcat, podemos hacer que nuestros logs se creen en la carpeta $CATALINA_HOME/logs con el siguiente código:

log4j = {

    def catalinaBase = System.properties.getProperty('catalina.base')
    def logDirectory = !catalinaBase? '/tmp': "${catalinaBase}/logs"

    appenders {
        rollingFile name:'pepitoAppender', file: "${logDirectory}/pepito.log", append: true, 
            layout: pattern(conversionPattern: '%d{yyyy-MM-dd HH:mm:ss} %-5p [%c{2}] %m%n')
    }

Así, si está definida la propiedad Java ‘catalina.base’ con el directorio de instalación de Tomcat (ya se encarga el propio Tomcat de definir esta propiedad cuando arranca), utilizará el directorio logs de Tomcat. Si no estuviera definida, utilizará “/tmp”.

Otra forma de hacerlo sería especificando un appender distinto para cada environment. De esta manera podemos cambiar o añadir parámetros de configuración en los appenders, como el tamaño del fichero, el número de backups:

log4j = {

    appenders {

        development {
            rollingFile name:'pepitoAppender', file: "/tmp/pepito.log", append: true, 
                layout: pattern(conversionPattern: '%d{yyyy-MM-dd HH:mm:ss} %-5p [%c{2}] %m%n')
        }
        production {
            rollingFile name:'pepitoAppender', file: "/usr/local/tomcat/logs/pepito.log", append: true, 
                maxBackupIndex: 10, maxFileSize: "10MB", 
                layout: pattern(conversionPattern: '%d{yyyy-MM-dd HH:mm:ss} %-5p [%c{2}] %m%n')
        }
    }

Más información:

5 thoughts on “Mini tutorial, log4j en Grails

  1. Muy bueno. Me ha gustado sobre todo lo de PepitoController. Es difícil tener tanta imaginación a la hora de nombrar las clases.

    Evidentemente, yo aprendí del mejor sensei. Mi función pepino de javaScript es una de las más famosas en el BBVA.

    Ah… yo en desarrollo tengo un ConsoleAppender de toda la vida ¿tu te pones a abrir el fichero de log?

  2. Hombre David.

    Yo hasta en la cocina tengo un RollingFileAppender que luego nunca se sabe.

    Además, creo que es una buena manera de acostumbrar a la gente que empieza y que aprendan de los perros viejunos.

    Saludos.

    P.D un dia de esto miro Grails :))

  3. Recuerdo lo de la función pepino del BBVA completamente x’DDD
    En desarrollo no, pero en producción, todos los ficheros se miran igual con un tail -f :D

  4. Voy a hacer unas pruebas, nosotros hemos tenido dificultades para **separar** los logs… resulta que por cada appender que configuramos, terminando duplicándose los logs en la stdout… :(

Comments are closed.