【发布时间】:2015-09-19 06:33:02
【问题描述】:
我们目前正在将多个 Grails (2.4.4) 应用程序部署到 Tomcat 7 服务器,并已完全按照此处tomcat-slf4j-logback 所述配置日志记录。
希望通过一个 logback.xml 文件配置所有 grails 应用程序,并将所有应用程序记录到一个文件中,但根据 grails 的 application.properties 中定义的应用程序名称区分日志消息:
#Grails Metadata file
app.name=my-application
我们的 logback.xml appender 目前看起来像这样:
<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${catalina.base}/logs/all.log</file>
<append>true</append>
<encoder>
<charset>utf-8</charset>
<pattern>%d [%X{appname:-null}] %-5level %logger : %msg%n</pattern>
</encoder>
...
</appender>
如您所见,我们目前正在从 MDC(映射诊断上下文)中提取“appname”。它由 Grails 插件中的 Grails 过滤器放置在那里,由所有应用程序共享,这些应用程序从 application.properties 文件中查找它。这会在日志文件中产生类似于以下内容的输出:
13:34:18.796 [application-1] DEBUG a.b.c.MyClass : hello
13:34:18.797 [application-2] DEBUG a.b.c.MyClass : hello
13:34:18.798 [null] DEBUG b.c.d.OtherClass : No App Name
13:34:18.798 [application-3] DEBUG a.b.c.MyClass : hello
13:34:18.799 [null] DEBUG b.c.d.OtherClass : No App Name
由于 MDC 的 threadLocal 特性,缺少此解决方案。那些在请求/响应线程之外执行的类无法访问同一个 MDC 来获取“appname”,而是打印“[null]”。
我在 logback.xml 中尝试过以下操作
<property resource="application.properties" />
应该从类路径加载 application.properties 但给出:
13:34:18.796 [app.name_IS_UNDEFINED] DEBUG a.b.c.MyClass : hello
我认为这意味着 logback 找不到 application.properties 文件(它们在每个战争中都打包在 WEB-INF\classes\ 中)...
我也尝试过在本地使用 logback.groovy ala:
// logback.groovy
// Read in the Grails application.properties
def props = new Properties()
new File("application.properties").withInputStream {
stream -> props.load(stream)
}
def slurper = new ConfigSlurper().parse(props)
// Get the application name.
String grailsAppName = slurper.app.name
appender("CONSOLE", ConsoleAppender) {
encoder(PatternLayoutEncoder) {
pattern = "%d [${grailsAppName ?: 'Application Name Not Set'}] %-5level %logger - %msg%n"]
}
}
这有效,只要我将“logback.configurationFile”设置为指向它,但我认为用 logback.groovy 替换单个 logback.xml Tomcat 7 服务器不会起作用(但它是我的下一个列表尝试)
我尝试过的其他事情
- 使用 Bootstrap.groovy 访问 logback 上下文并将“app.name”“放入”上下文中
- 使用 Bootstrap.groovy 到 MDC.put('app.name', ""application-1")
- 我读过 ContextSelectors http://logback.qos.ch/manual/contextSelector.html 和 JNDI contextSelector 很有趣,但我不想重复配置,只需在每个应用程序中添加一个属性即可使用 appender 模式访问
任何帮助将不胜感激
【问题讨论】:
标签: tomcat grails groovy slf4j logback