tomcat - 多个Grails Application + tomcat-slf4j-logback,如何将应用程序名称写入日志文件

标签 tomcat grails groovy slf4j logback

我们目前正在将几个 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”。它由所有从 application.properties 文件中查找它的应用程序共享的 Grails 插件中的 Grails 过滤器放置在那里。这会在日志文件中产生类似于以下内容的输出:

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 文件(它们在每个 war 中都打包在 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 模式访问的属性

任何帮助将不胜感激

最佳答案

配置步骤:

  1. 在 grails-app/conf/application.yml 或外部应用程序配置文件中添加以下行:

     logging:
     config: "C:/Application/config/logback.groovy"  
     file: "app.log"  
     path: "C:/Application/logs"  
    
  2. 将配置文件放在上面提供的配置路径中(在上面例如 C:/Application/config/logback.groovy):

例如:

import grails.util.BuildSettings  
import grails.util.Environment  

import ch.qos.logback.classic.encoder.PatternLayoutEncoder  
import ch.qos.logback.core.ConsoleAppender  
import ch.qos.logback.core.FileAppender  

import static ch.qos.logback.classic.Level.DEBUG  

def targetDir = System.getProperty("LOG_PATH")  
def targetFile = System.getProperty("LOG_FILE")  

appender("FILE", FileAppender) {  
file = "${targetDir}/${targetFile}"  
encoder(PatternLayoutEncoder) {  
pattern = "%date %level %logger - %msg%n"  
}  
}
appender("STDOUT", ConsoleAppender) {  
encoder(PatternLayoutEncoder) {  
pattern = "%msg%n"  
}  
}  
root(INFO, ["FILE", "STDOUT"])  

所有的应用程序都可以按照第一步指向同一个配置文件。所以,所有的日志都会按照第一步指定的路径和文件生成。

日志系统负责为您创建的系统属性:

•   ${PID} the current process ID.  
•   ${LOG_FILE} if logging.file was set in Boot’s external configuration.  
•   ${LOG_PATH} if logging.path was set (representing a directory for log files   to live in).  
•   ${LOG_EXCEPTION_CONVERSION_WORD} if logging.exception-conversion-word was   set in Boot’s external configuration.  

因此您可以在 logback.groovy 文件中使用它们,如上所示 System.getProperty("LOG_PATH")。
引用资料:
https://docs.spring.io/spring-boot/docs/current/reference/html/howto-logging.html

关于tomcat - 多个Grails Application + tomcat-slf4j-logback,如何将应用程序名称写入日志文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31172544/

相关文章:

java - 我应该把我的 css 文件放在 Intellij IDEA 的什么地方

Grails Spring Security(获取当前用户)

eclipse - Groovy/Grails - 无法解析类

grails - 对地址栏中直接插入的链接进行Geb测试

java - 启动 Web 应用程序时出现 IllegalStateException - Spring + Wicket

java - eclipse 中的 Tomcat 不考虑我的修改

java - Tomcat、OpenSSL、SSL 错误,keytool : Keystore was tampered with, 或密码不正确

grails - IntelliJ 中使用 GroovyDSL 进行动态方法定义

grails - 为自定义grails脚本编写帮助

java - 方法 : java. lang.String.getCatalogName() 的签名不适用于参数