有没有办法将Grails数据源注入logback.groovy以便与DBAppender一起使用?

时间:2016-11-01 17:07:43

标签: grails logback logback-groovy grails3

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

logback.groovy在某种程度上是Grails的外部因素,所以它不接受Spring自动装配,而grails.util.Holders.findApplication()之类的其他技巧似乎不起作用。

1 个答案:

答案 0 :(得分:3)

Woof,这是一件苦差事。坦率地说,我对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)
    }
}

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

假设您有多个dataSource(甚至只有一个配置用于logback,称为dataSources.logging。在这种情况下,bean引用将是dataSource_logging。在这种情况下默认的dataSource(称为dataSources.dataSource bean引用只是dataSource。让我花一点时间来解决这个问题。

总而言之,我错过了使用Grails DSL在Grails配置文件中配置 Log4j 的日子。我认为从Grails中分离日志记录意味着Graeme和Grails团队要处理的事情少了一些,但这对于我认为常见的东西来说是一个主要的PITA。 ¯\ _(ツ)_ /¯