【问题标题】:Is there a way to inject a Grails datasource into logback.groovy for use with DBAppender?有没有办法将 Grails 数据源注入 logback.groovy 以与 DBAppender 一起使用?
【发布时间】:2016-11-01 17:07:43
【问题描述】:

因此,Grails 已经设置了由连接池支持的数据源。有没有办法利用它们在 Logback 中与 DBAppender 一起使用,这样我就不必创建单独的并行数据源/连接池?

logback.groovy 在某种程度上是 Grails 外部的,因此它不接受 Spring 自动装配,并且像 grails.util.Holders.findApplication() 这样的其他技巧似乎不起作用。

【问题讨论】:

  • 我一直在摆弄Spring Logback Extension,但这肯定是多余的吗?问题是 Grails 依赖 logback.groovy 和 Logback 的 DSL,而不是从 application.yml 或者更可能的 application.groovy 实例化它来利用 Grails 创建的应用程序上下文?

标签: grails logback logback-groovy grails3


【解决方案1】:

哇,这是一件苦差事。坦率地说,我对 Logback 有点失望。 Logback 创建它自己的 Spring ApplicationContext。所以我们有两个不同的上下文。啊。此外,Logback 用于在 Groovy 中配置 Spring 的 DSL 与 Grails 不同,这当然无济于事。

由于 Logback 在 Grails 完全启动之前就被启动了,我们需要告诉 Logback 创建一些虚拟的 appender,它们只会存储日志消息,直到我们从 Grails 中启动 appender。我们使用 Spring 的 logback 扩展来执行此操作。

build.gradle

compile 'org.logback-extensions:logback-ext-spring:0.1.4'

logback.groovy

import ch.qos.logback.ext.spring.DelegatingLogbackAppender

appender('DB', DelegatingLogbackAppender)
appender('STDOUT', DelegatingLogbackAppender)

resources.groovy

import ch.qos.logback.ext.spring.ApplicationContextHolder
import ch.qos.logback.classic.encoder.PatternLayoutEncoder
import ch.qos.logback.classic.db.DBAppender
import ch.qos.logback.core.ConsoleAppender
import ch.qos.logback.core.db.DataSourceConnectionSource
import org.slf4j.LoggerFactory

beans = {
    applicationContextHolder(ApplicationContextHolder)

    loggerContext(LoggerFactory) { bean ->
        bean.factoryMethod = "getILoggerFactory"
    }

    patternLayoutEncoder(PatternLayoutEncoder) { bean ->
        bean.initMethod = 'start'
        bean.destroyMethod = 'stop'

        context = ref(loggerContext)
        pattern = "%level %logger - %msg%n"
    }

   STDOUT(ConsoleAppender) { bean ->
        bean.initMethod = 'start'
        bean.destroyMethod = 'stop'
        context = ref(loggerContext)
        encoder = ref(patternLayoutEncoder)
    }

    connectionSource(DataSourceConnectionSource) { bean ->
        bean.initMethod = 'start'
        bean.destroyMethod = 'stop'
        context = ref(loggerContext)
        dataSource = ref(dataSource)
    }

    DB(DBAppender) { bean ->
        bean.initMethod = 'start'
        bean.destroyMethod = 'stop'
        context = ref(loggerContext)
        connectionSource = ref(connectionSource)
    }
}

DataSourceConnectionSource 中的ref(dataSource) 引用了您在application.ymlapplication.groovy 中配置的数据源。

假设您有多个数据源(或者甚至一个为 logback 配置的称为 dataSources.logging。在这种情况下,bean 引用将是 dataSource_logging。在这种情况下默认数据源(称为 dataSources.dataSource bean 引用只是 @987654331 @. 我花了一段时间才弄明白。

总而言之,我怀念使用 Grails DSL 从 Grails 配置文件中配置 Log4j 的日子。我知道将日志记录与 Grails 分开意味着 Graeme 和 Grails 团队需要处理的事情更少,但这是我认为很常见的事情的主要 PITA。 ¯\_(ツ)_/¯

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-15
    • 1970-01-01
    • 2018-03-15
    • 2016-11-01
    • 1970-01-01
    • 2018-09-07
    • 1970-01-01
    相关资源
    最近更新 更多