0

我想将 BootStrap.groovy 文件中的一些信息记录到控制台和日志文件中。输出报告了一些配置信息,并标记了应用程序从配置到执行阶段的过渡。我遇到的问题是仅在控制台上看到所需的输出,而不是在日志文件中。我的环境包括

  • 圣杯 2.3.8
  • 红帽企业 Linux 工作站 6.5 版

我提供了两个代码片段来展示我在做什么。它们也很容易插入一个空的 Grails 项目(不需要创建域类或控制器来查看我所看到的行为)。当我运行“ grails run-app ”时,我希望块的开发部分environments将 BootStrap 输出配置到两个位置。除了让日志记录到这两个位置之外,如果您对我的 log4j 配置有任何一般性建议,也将不胜感激。

我修改了我的BootStrap.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
4

2 回答 2

1

我采用了我们的日志记录配置并使用您的配置对其进行了测试。它确实完成了你想要的。我们用于开发模式的日志目录最终位于logs而不是target. 此外,请PatternLayout确保LevelEnvironmentConfig.groovy. 也许你可以从这个倒退。

// 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'
    }
}
于 2014-05-19T23:03:51.523 回答
0

这确实是为了增强 Aaron 的答案,但是 StackOverflow 中的注释没有我想要使用的丰富格式。

我有时间重新审视这一点,发现我之前使用的 Grails 2.2.4 和 Grails 2.3.8 之间的行为存在差异。

println设置后向Config.groovy文件添加调试logDirectory

def logDirectory = "${catalinaBase}/logs"
println "logDirectory = ${logDirectory}"

在 Grails 2.2.4 下显示(可能是 2.3.x 之前的任何版本)

logDirectory = ./target/logs

但在 Grails 2.3.8 下,会打印一个“ grails run-app ”

logDirectory = ./target/logs
...
logDirectory = ./target/work/tomcat/logs

啊哈!看到两个位置,我现在记得在“ grails 2.3 中的新功能? ”中读到的许多命令现在可以分叉到一个单独的 JVM 中。以前的“ grails run-app ”使用空的“ catalinaBase”值执行,我的输出进入了 target/logs 目录下的日志文件。但是对于 Grails 2.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 得到一个非空catalinaBase值来处理。我以为我没有从 log4j 获得输出,但它正在工作;只是进入一个我不知道或寻找的文件。

Aaron 的代码之所以有效,是因为他的代码块不会被此愚弄,它专门针对生产环境,并且目标文件已按预期设置:

def logHome = "./logs"
environments {
    production {
        logHome = (System.getProperty("catalina.base") ?: ".") + "/logs"
    }
}
于 2014-06-06T20:11:49.123 回答