Grails2.3.8中两个位置的log4j日志记录配置
我想将BootStrap.groovy文件中的一些信息记录到控制台和日志文件中。输出报告一些配置信息,并标记从配置到应用程序执行阶段的转换。我遇到的问题是,只在控制台上看到所需的输出,而不在日志文件中看到。我的环境包括Grails2.3.8中两个位置的log4j日志记录配置,grails,logging,log4j,grails-2.3,Grails,Logging,Log4j,Grails 2.3,我想将BootStrap.groovy文件中的一些信息记录到控制台和日志文件中。输出报告一些配置信息,并标记从配置到应用程序执行阶段的转换。我遇到的问题是,只在控制台上看到所需的输出,而不在日志文件中看到。我的环境包括 Grails 2.3.8 Red Hat Enterprise Linux工作站6.5版 我提供了两个代码片段来说明我在做什么。它们也很容易插入到空的Grails项目中(不需要创建域类或控制器来查看我看到的行为)。当我运行'grails run app'时,我希望环境块的开发
- Grails 2.3.8
- Red Hat Enterprise Linux工作站6.5版
环境
块的开发部分将引导输出配置到两个位置。除了让两个位置的日志记录都能正常工作外,如果您对我的log4j配置有任何一般性建议,也将不胜感激
我已经修改了我的引导程序。groovy:
import grails.util.Environment
class BootStrap {
def grailsApplication
def init = { servletContext ->
log.info """
tryLoggingInGrails2-3-8 configuration {---------------- ${new Date()}
environment : ${Environment.current.name}
dataSource.username : ${grailsApplication.config?.dataSource?.username}
dataSource.url : ${grailsApplication.config?.dataSource?.url}
------------------------------------------------------}"""
}
def destroy = {
}
}
在Config.groovy中,log4j配置部分是:
// ----------------------------- Start Config.groovy snippet
// log4j configuration
def catalinaBase = System.getProperty( 'catalina.base' )
if ( !catalinaBase ) catalinaBase = './target' // just in case
def logDirectory = "${catalinaBase}/logs"
def consoleLevelThreshold = org.apache.log4j.Level.WARN
def fileLevelThreshold = org.apache.log4j.Level.INFO
environments {
development {
consoleLevelThreshold = org.apache.log4j.Level.DEBUG
fileLevelThreshold = org.apache.log4j.Level.DEBUG
}
}
// Inside the log4j closure, use '${myAppName}' instead of '${appName}'
def myAppName = appName
log4j = {
appenders {
// This 'null' prevents the empty stacktrace.log file from being created
// in the default location, where we may not have permission to write
// in a production tomcat.
'null' name: 'stacktrace'
console name: 'stdoutAppender',
threshold: consoleLevelThreshold,
layout: pattern( conversionPattern: '%-5p %c{2} %m%n' )
file name: 'fileAppender',
file: "${logDirectory}/${myAppName}.log",
threshold: fileLevelThreshold,
layout: pattern( conversionPattern: '%-4r [%t] %-5p %c %d %x - %m%n' ),
append: false
file name: 'stacktraceAppender',
file: "${logDirectory}/${myAppName}_stacktrace.log",
threshold: org.apache.log4j.Level.ERROR,
append: false
} // appenders
root {
warn 'fileAppender', 'stdoutAppender'
}
error stacktraceAppender: "StackTrace"
error fileAppender: [
'grails.app',
'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'
]
environments {
development {
debug additivity: false,
stdoutAppender: [
"grails.app.conf.BootStrap"
]
debug additivity: false,
fileAppender: [
"grails.app.conf.BootStrap"
]
} // development
production {
info additivity: false,
fileAppender: [
"grails.app.conf.BootStrap"
]
} // production
} // environments
}
// ----------------------------- End Config.groovy snippet
我采用了我们的日志配置,并用您的配置进行了测试。它确实实现了你想要的。开发模式的日志目录最终位于
logs
下,而不是target
。另外,请确保在Config.groovy
的顶部为PatternLayout
、Level
和Environment
添加导入。也许你可以从这一个倒转过来
// If we are running under tomcat, this is the tomcat base
def logHome = "./logs"
environments {
production {
logHome = (System.getProperty("catalina.base") ?: ".") + "/logs"
}
}
// Ensure the log directory exists
new File(logHome).mkdirs()
def applicationName = appName
log4j = {
def layout = new PatternLayout("%d %-5p %c %x - %m%n")
def logName = { String baseName -> "${logHome}/${applicationName}-${baseName}.log" }
// Only configure file appenders if running under tomcat
appenders {
console name: 'stdout', layout: pattern(conversionPattern: "%-5p %c{2} - %m%n"), threshold: Level.INFO
console name: 'stderr', layout: pattern(conversionPattern: "%-5p %c{2} - %m%n"), threshold: Level.ERROR
// Disable the stacktrace.log file, it's already going to error anyway
'null' name: 'stacktrace'
rollingFile name: "errorLog", threshold: Level.ERROR, fileName: logName('error'), layout: layout, immediateFlush: true, maxFileSize: "100MB", maxBackupIndex: 5
rollingFile name: "infoLog", threshold: Level.INFO, fileName: logName('info'), layout: layout, maxFileSize: "100MB", maxBackupIndex: 5
rollingFile name: "debugLog", threshold: Level.DEBUG, fileName: logName('debug'), layout: layout, maxFileSize: "100MB", maxBackupIndex: 5
}
def infoLogged = [
'grails.app.conf',
'grails.app.taglib.com.triu',
'grails.app.filters.com.triu',
'grails.app.services.com.triu',
'grails.app.controllers.com.triu',
'grails.app.domain',
'liquibase',
'grails.plugin.databasemigration'
]
// Mirror logs to stdout and info logging
environments {
development {
info stdout: infoLogged, infoLog: infoLogged
debug debugLog: infoLogged
}
test {
info stdout: infoLogged, infoLog: infoLogged
}
production {
info infoLog: infoLogged
error errorLog: infoLogged
debug debugLog: infoLogged
}
}
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
'grails.spring',
'org.springframework',
'org.hibernate'
// Per docs, can't put environment blocks inside of root block
root {
error 'errorLog', 'stderr'
}
}
这确实是为了补充Aaron的答案,但是StackOverflow中的注释没有我想要使用的丰富格式
我花了一些时间来重新审视这一点,发现我之前使用的Grails2.2.4和Grails2.3.8在行为上有所不同
设置logDirectory
后,将调试println
添加到Config.groovy文件中:
def logDirectory = "${catalinaBase}/logs"
println "logDirectory = ${logDirectory}"
显示在Grails2.2.4下(可能是2.3.x之前的任何版本)
但在Grails2.3.8下,会打印一个“GrailsRun应用程序”
啊哈!看到两个位置,我现在记得在“”中读到,许多命令现在可以分叉到一个单独的JVM中。以前,使用空的“catalinaBase
”值执行“grails run app”,我的输出进入target/logs目录下的日志文件。但对于Grails2.3.8,我没有意识到在target/work/tomcat下创建了第二组日志文件:
tryLoggingInGrails2-3-8$ find . -name *.log -print
./target/logs/tryLoggingInGrails2-3-8.log (expected file is created, but empty)
./target/logs/tryLoggingInGrails2-3-8_stacktrace.log (expected file, but empty)
./target/work/tomcat/logs/tryLoggingInGrails2-3-8.log (unexpected file)
./target/work/tomcat/logs/tryLoggingInGrails2-3-8_stacktrace.log (unexpected file)
我想要的输出进入了另一组日志文件,显然一个fork得到了一个非null的catalinaBase值。我以为我没有从log4j获得输出,但它工作正常;只是进入了一个我不知道或找不到的文件
Aaron的代码之所以有效,是因为他的代码块没有被这一点所愚弄,它专门针对生产环境,并且目标文件是按预期设置的:
def logHome = "./logs"
environments {
production {
logHome = (System.getProperty("catalina.base") ?: ".") + "/logs"
}
}
谢谢你的建议,但是我的日志文件的输出没有改变。除了尝试你所说的建议之外,我还把“可加性”部分放在第一位(这并不重要),两种方式的结果都是一样的。奇怪的是,我们做了完全相同的事情,我们的配置或多或少与你的相似。唯一的例外是我们只指定了“grails.app.conf”,而没有显式地引导。我还确认使用“grails.app.conf”而不是“grails.app.conf.BootStrap”并不能改善结果。我已经用一个有效的配置更新了我的答案,虽然稍微复杂一些。感谢您在@Aaron上的帮助。如果我提出任何重要的简化,我会发布一个摘要。
tryLoggingInGrails2-3-8$ find . -name *.log -print
./target/logs/tryLoggingInGrails2-3-8.log (expected file is created, but empty)
./target/logs/tryLoggingInGrails2-3-8_stacktrace.log (expected file, but empty)
./target/work/tomcat/logs/tryLoggingInGrails2-3-8.log (unexpected file)
./target/work/tomcat/logs/tryLoggingInGrails2-3-8_stacktrace.log (unexpected file)
def logHome = "./logs"
environments {
production {
logHome = (System.getProperty("catalina.base") ?: ".") + "/logs"
}
}