1

I would like to inject log4j config stuff stored in a properties file in my Config.groovy.

Here is my properties file :

log.file=path/to/my/log
log.root.level=info
log.grails.app.level=info

No problem for file path EL syntax ${} but it doesn't work for levels as it is not strings. Here is the config.groovy :

appenders {
    file name:'file', file:"${config.log.file}"
}

root {
    ${log.root.level} 'stdout', 'file'
}

Any advise ?

2 Answers2

1

You have to read the properties file and convert it to a ConfigObject to use in Config.groovy.

log4j {
    def props = new Properties()
    new File("path/to/log.properties").withReader{
        props.load(it)
    }
    def slurp = new ConfigSlurper().parse(props)

    appenders {
        file name:'file', file:"$slurp.log.file"
    }

    root {
        "$slurp.log.root.level" 'stdout', 'file'
    }
}

Refer this similar question.

Community
  • 1
  • 1
dmahapatro
  • 49,365
  • 7
  • 88
  • 117
  • Thanks, I am now able to load my properties but when server is starting I have a **Exception occured configuring log4j logging: No signature of method: groovy.util.ConfigObject.level() is applicable for argument types: (java.lang.String, java.lang.String) values: [stdout, file]** – Laurent BOURGEOIS Jan 23 '14 at 16:14
  • My bad. Missed the quotes.Updated answer. – dmahapatro Jan 23 '14 at 16:27
  • It works, thanks. I didn't understood exactly the double quotes trilck, I am quite new to Groovy/Grails world... – Laurent BOURGEOIS Jan 23 '14 at 17:17
0

If I'm reading the code of the Grails Log4J DSL parser correctly you should just be able to say

root {
    "${config.config.log.root.level}" 'stdout', 'file'
}

or if that doesn't work then

root {
    delegate."${config.config.log.root.level}" 'stdout', 'file'
}

Normally, within the log4j closure you have access to the complete grailsApplication.config (including options merged in from external configuration files) as the variable config but it looks like you need a second config in front of that when you're inside the root {} block.

Explanation - the closure delegate of the root closure is a RootLog4jConfig object, which has a property config pointing to the main Log4jConfig which is the delegate for the rest of the log4j closure, and that in turn has its own property config pointing to the parsed ConfigObject. I somehow doubt that this behaviour is deliberate, and it might be worth a JIRA to suggest that config should resolve to the same thing inside the root block as outside it.

Ian Roberts
  • 120,891
  • 16
  • 170
  • 183
  • I have tried the both solutions. No output logs and this message on server startup **log4j:ERROR Property missing when configuring log4j: log** – Laurent BOURGEOIS Jan 23 '14 at 17:15
  • @LaurentBOURGEOIS for the `config.` things to work you'll have to list the external properties file in `grails.config.locations` – Ian Roberts Jan 23 '14 at 17:44
  • properties file is already in my config.locations `def envName = System.properties.getProperty("tomcat.server.name") grails.config.locations = ["classpath:"+envName+"-config.properties"]` – Laurent BOURGEOIS Jan 24 '14 at 08:45
  • @LaurentBOURGEOIS hmm, inspecting [the code](https://github.com/grails/grails-core/blob/master/grails-plugin-log4j/src/main/groovy/org/codehaus/groovy/grails/plugins/log4j/Log4jConfig.groovy) it looks like `config.config.log.root.level` might work --you need an extra "config" inside the root closure compared to outside it. I doubt this is intentional... – Ian Roberts Jan 24 '14 at 10:29