Есть ли способ внедрить источник данных Grails в logback.groovy для использования с DBAppender?

Таким образом, Grails уже устанавливает источники данных, поддерживаемые пулами соединений. Есть ли способ использовать их для использования с DBAppender в Logback, чтобы мне не приходилось создавать отдельный параллельный пул источников данных/соединений?

logback.groovy является чем-то внешним по отношению к Grails, поэтому он не поддерживает автосвязывание Spring, а другие приемы, такие как grails.util.Holders.findApplication(), похоже, не работают.


person U47    schedule 01.11.2016    source источник
comment
Я возился с расширением Spring Logback, но, безусловно, это избыточный? Является ли проблема в том, что Grails полагается на logback.groovy и DSL Logback вместо того, чтобы создавать все это из application.yml или, что более вероятно, application.groovy для использования контекста приложения, создаваемого Grails?   -  person U47    schedule 08.11.2016


Ответы (1)


Уф, это было муторно. Честно говоря, я немного разочарован Logback. Logback создает собственный Spring ApplicationContext. Таким образом, у нас есть два отдельных контекста. Фу. Кроме того, конечно, не помогает то, что DSL, который Logback использует для настройки Spring в Groovy, отличается от Grails.

Поскольку Logback запускается до полного запуска Grails, нам нужно указать Logback создать несколько фиктивных приложений, которые будут просто хранить сообщения журнала, пока мы не запустим приложения из Grails. Для этого мы используем расширение logback для Spring.

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.yml или application.groovy.

Скажем, у вас есть несколько источников данных (или даже один, настроенный только для журнала, с именем dataSources.logging. В этом случае ссылка на компонент будет dataSource_logging. Источник данных по умолчанию в этом случае (называется ссылка на компонент dataSources.dataSource просто dataSource. Мне потребовалось некоторое время, чтобы понять это .

В общем, я скучаю по тем временам, когда приходилось настраивать Log4j из конфигурационного файла Grails с помощью Grails DSL. Я понимаю, что отделение ведения журналов от Grails означает, что Грэму и команде Grails придется иметь дело с одной задачей меньше, но это было серьезное PITA для того, что, как я думал, будет обычным явлением. ¯\_(ツ)_/¯

person U47    schedule 10.11.2016