前面已经说过了配置语法和环境的概念,现在来看看最常用的配置:日志。
Grails的日志是Common-logging + Log4j的组合,日志的配置在Config.groovy中完成。我们同样可以对它使用环境,比方说对于开发环境设置一个日志级别(如debug),对于产品环境则设置另一个(如error)。在运行时,Grails会根据日志配置在web-app/WEB-INF/classes中产生合适的log4j.properties。典型的日志配置如下:
log4j = {
        error  'org.codehaus.groovy.grails.web.servlet',
            'org.codehaus.groovy.grails.web.pages'
        warn   'org.mortbay.log'
    }
上面的配置针对不同的包设置了不同的日志级别,一般情况下,我们会对Grails自带包或工具包设为error,而对于工程相关的包则是在开发环境下设成debug,在产品环境下设为error。在了解如何进行这样的配置之前,我们先复习一下Log4j的相关概念。Log4j主要由3部分组成:
1.Logger:相当于日志的分类,root为根。所有的logger都继承root的设置。简单理解的话,不妨将类的包结构于Logger划上等号。参考文档中列出了一些Grails常用的Logger,请注意。
上面给出的例子是单独给不同的logger指定了不同的日志级别,如果相同级别的logger很多,一一指定的话就太麻烦了,这时可以通过设置root来完成。设置root有两种方法:
方法1:单独使用(log4j的闭包内)
root {
        debug 'stdout', 'file'
        additivity = true
    }
方法2:使用log4j闭包传入的root:
log4j = { root ->
        root.level = org.apache.log4j.Level.DEBUG
        …
    }
2.appender:负责日志输出。主要的appender有:
  • jdbc:输出到数据库
  • console:输出到stdout
  • file:输出到文件
  • rollingFile:输出到文件,达到预定大小后,文件自动分割
appender的指定也是在log4j闭包中完成的:
appenders {
         rollingFile name:"myAppender", 
               maxFileSize:1024, file:"/tmp/logs/myApp.log"
    }
使用则是在Logger中指定:
root {
        debug 'myAppender'
        additivity = true
    }
3.layout:负责日志输出的格式。主要格式:
  • xml:xml格式
  • html:html格式
  • simple:简单文本
  • pattern:指定输出的模式
layout的指定是在appender中进行的:
appenders { console name:'stdout', layout:pattern(conversionPattern: '%c{2} %m%n') }
接下来,回到我们刚才的问题:“针对开发环境设置debug,针对产品环境设置error”,整个配置如下:
log4j = {
        environments {
            production {
               root {
                    error 'stdout'
                    additivity = true
                }
            }
            development {
               root {
                    debug 'stdout'
                    additivity = true
                }
            }
            test {
                root {
                    debug 'stdout'
                    additivity = true
                }
            }
        }
    
        error  'org.codehaus.groovy.grails.web.servlet',  //  controllers
            'org.codehaus.groovy.grails.web.pages', //  GSP
            'org.codehaus.groovy.grails.web.sitemesh', //  layouts
            'org.codehaus.groovy.grails.web.mapping.filter', // URL mapping
            'org.codehaus.groovy.grails.web.mapping', // URL mapping
            'org.codehaus.groovy.grails.commons', // core / classloading
            'org.codehaus.groovy.grails.plugins', // plugins
            'org.codehaus.groovy.grails.orm.hibernate', // hibernate integration
            'org.springframework',
            'org.hibernate',
               'net.sf.ehcache.hibernate',
               'org.apache', //注意这里这一行和下一行
               'net.sf'
    
        warn   'org.mortbay.log'
    }
接下来我们谈谈堆栈的输出。一般情况下,Grails会把完整的堆栈信息输出到stacktrace.log,而只在stdout显示过滤后的内容。但我们也可以改变它:
  • 方法1,在标准输出上输出完整堆栈:error stdout:"StackTrace"
  • 方法2,禁止堆栈过滤:grails -Dgrails.full.stacktrace=true run-app
Grails为我们使用日志提供了非常大的便利条件:每个应用部件都会被动态添加一个log属性,因此,在这些部件中可以直接使用log。如:log.debug "The value of foo is $foo"。在配置时,使用约定:grails.app.<artefactType>.ClassName。主要的名称:
  • bootstrap:启动类
  • dataSource:数据源
  • tagLib:标签库
  • service:服务类
  • controller:控制器
  • domain:领域类
配置示例:
log4j = {
        // 所有部件
        info "grails.app"
        // 特定的Controller
        debug "grails.app.controller.YourController"
        ...
    }
在使用日志时,还有其他需要注意的地方,请参见这些经验