Search code examples
scalagroovylogbacktypesafe-config

How to reference a nested scala object to dynamically set configs on logback.groovy?


I use typesafe config library to manage my Scala project's configuration. I use the following pattern to organize and load my configurations in a type-safe manner

object AppConfig {
  private val config = ConfigFactory.load()
  lazy val host: String = config.getString("host")
  object Splunk {
    private lazy val splunkConf = config.getConfig("splunk")
    lazy val index = splunkConf.getString("index")
    lazy val token = splunkConf.getString("token")
  }
}

I need to inject some of those configs in my logback.groovy. This works perfectly when accessing direct properties of AppConfig : example AppConfig.host(), but not for nested objects: like AppConfig.Splunk.token() logback.groovy

appender("splunk", HttpEventCollectorLogbackAppender) {
    url = "http://someSplunkUrl:8088/services/collector"
    host = AppConfig.host()
    token = AppConfig.Splunk.token() 
    index = AppConfig.Splunk.index()
    batch_size_count = 1
    layout(PatternLayout) {
        pattern = "%msg"
    }
}
groovy.lang.MissingPropertyException: No such property: Splunk for class: AppConfig
    at groovy.lang.MetaClassImpl.invokeStaticMissingProperty(MetaClassImpl.java:1028)
    at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:1932)
    at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:1908)
    at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:3886)
    at org.codehaus.groovy.runtime.callsite.ClassMetaClassGetPropertySite.getProperty(ClassMetaClassGetPropertySite.java:50)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGetProperty(AbstractCallSite.java:298)
    at Script1$_run_closure2.doCall(Script1.groovy:18)
    at Script1$_run_closure2.doCall(Script1.groovy)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

Solution

  • I ended up referencing the nested objected as below :

    def splunkConf = Class.forName("com.util.AppConfig\$Splunk\$")
                          .getDeclaredConstructor().newInstance()
    

    I could then access the fields successfully :

    token = splunkConf."token"()
    index = splunkConf."index"()