【问题标题】:Strange Log4J error calling grails war w/ Grails 2.1使用 Grails 2.1 调用 grails 战争时出现奇怪的 Log4J 错误
【发布时间】:2012-08-05 17:24:14
【问题描述】:

当我在命令行上执行grails -skipTests -verbose -plainOutput war 时,它会尝试为生产环境配置日志记录。但是,我不希望在构建战争时有任何应用程序日志记录。有谁知道为什么 Grails 会尝试这样做以及如何避免它?谢谢。

它尝试登录的目录在 BuildAgent 上不存在。但这就是重点。没有应用运行,我只是想建立一个战争。

我的日志配置:

// log4j configuration
log4j = {
    appenders {
        def logDir = '/someDirectory/'

        if (Environment.getCurrentEnvironment() in [Environment.DEVELOPMENT, Environment.TEST]) {
            logDir = 'log/'
        }

        def logFile = "${logDir}someLog.log"
        def stacktraceLogFile = "${logDir}stacktrace.log"

        appender new org.apache.log4j.DailyRollingFileAppender(name: "file",
                layout: pattern(conversionPattern: "%d{[ dd.MM.yy HH:mm:ss.SSS]} [%t] %-5p %c %x - %m%n"),
                file: logFile,
                datePattern: "'.'yyyy-MM-dd")

        appender new org.apache.log4j.DailyRollingFileAppender(name: "stacktrace",
                layout: pattern(conversionPattern: "%d{[ dd.MM.yy HH:mm:ss.SSS]} [%t] %-5p %c %x - %m%n"),
                file: stacktraceLogFile,
                datePattern: "'.'yyyy-MM-dd")
    }

    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.springframework'

    root {
        warn 'stdout', 'file'

        environments {
            production {
                error 'stdout', 'file'
            }
        }
    }
}

我的堆栈跟踪:

java.io.FileNotFoundException: /someDirectory/stacktrace.log (No such file or directory)
at java.io.FileOutputStream.openAppend(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:192)
at java.io.FileOutputStream.<init>(FileOutputStream.java:116)
at org.apache.log4j.FileAppender.setFile(FileAppender.java:294)
...
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSite.invoke(PogoMetaMethodSite.java:226)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:52)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:46)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:145)
at gant.Gant.executeTargets(Gant.groovy:590)
at org.codehaus.groovy.grails.cli.GrailsScriptRunner.executeWithGantInstance(GrailsScriptRunner.java:748)
at org.codehaus.groovy.grails.cli.GrailsScriptRunner.executeScriptFile(GrailsScriptRunner.java:551)
at org.codehaus.groovy.grails.cli.GrailsScriptRunner.executeScriptWithCaching(GrailsScriptRunner.java:452)
at org.codehaus.groovy.grails.cli.GrailsScriptRunner.callPluginOrGrailsScript(GrailsScriptRunner.java:396)
at org.codehaus.groovy.grails.cli.GrailsScriptRunner.executeCommand(GrailsScriptRunner.java:371)
at org.codehaus.groovy.grails.cli.GrailsScriptRunner.main(GrailsScriptRunner.java:232)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.groovy.grails.cli.support.GrailsStarter.rootLoader(GrailsStarter.java:234)
at org.codehaus.groovy.grails.cli.support.GrailsStarter.main(GrailsStarter.java:262)

更新

我刚刚注意到,只有在使用 Grails 启用详细日志记录时(即在我的 Jenkins 构建代理上),才会公开此异常。对我来说,这似乎是一种被普通标准输出日志隐藏的不良行为。

【问题讨论】:

    标签: grails logging log4j


    【解决方案1】:

    该错误可能意味着/someDirectory 不存在并且log4j 没有创建它的必要权限。

    从堆栈跟踪来看,Grails 似乎确实初始化了配置,可能是因为大多数命令都需要它。

    我的建议是在 Grails 主配置文件中创建另一个环境,它要么根本不配置 log4j,要么只配置控制台附加程序。

    或者,将文件附加程序移动到生产配置或将其配置为写入开发配置中的相对路径并在生产中覆盖此路径。

    [编辑]替换

    def logDir = '/someDirectory/'
    

    def logDir = System.getProperty( 'appname.logDir', '/someDirectory/' );
    

    【讨论】:

    • 感谢您的回答。但似乎我表达得不够清楚。我什至不启动Tomcat。我只是在制造一场战争。即使 log4j 尝试写入该日志文件,但我不明白为什么
    • 抱歉,感谢您再次将我的头推到那里 :-) 但这正是我想知道的。如果这些命令需要它以及为什么会这样。因为当我知道的时候,我就知道该怎么做了。稍后我会深入研究您的替代建议。
    • 我认为你从堆栈跟踪中截断了有趣的部分
    • 是的,我做到了。我只是查看了它,createWar 目标只是初始化了 log4j 配置。这就是为什么不同的环境不起作用的原因:我想为生产环境创建一个战争,所以我当然需要使用相同的配置。我现在的问题是,如何为 grails prod war 禁用 prod 环境附加程序。
    • 您可以从系统属性中查找 logDir :-/ 查看我的编辑。
    猜你喜欢
    • 1970-01-01
    • 2011-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-11
    相关资源
    最近更新 更多