I am trying to manipulate a wildfly 10.1. standalone.xml
via gradle buildscript to modify logger settings. I have done this before, and with logger entries, this works as expected. However, now I need to add a new periodic-rotating-file-handler
which in itself is not a problem, but it does act up when trying to tell what file to actually log to.
Existing code:
def configFile = {wildflyDir}/standalone/configuration/standalone.xml"
def xml = new XmlSlurper(false,false).parse(configFile)
def logging = xml.profile.subsystem.find{ it['@xmlns'] == "urn:jboss:domain:logging:3.0' }
logging.appendNode {
logger(category:"loggingCategory") {
level(name:"LEVEL")
}
}
This is, as expected, highly functional. Now I need to add a snippet like this:
<periodic-rotating-file-handler>
<formatter>
<named-formatter name="PATTERN" />
</formatter>
<file path="file.log" relative-to="jboss.logging.dir" />
<suffix value=".yyyy-MM-dd" />
<append value="true" />
</periodic-rotating-file-handler>
The problem exists in the file
definition, as that one would look like this in the build.gradle
file:
file(path:"file.log" "relative-to":"jboss.logging.dir")
And this is being interpreted by gradle as new File(arg1, arg2)
, so basically it is trying to add a file-Object with the given parameters to the XML.
This is valid, but definitely not what I want, since I just need the corresponding XML Node. I tried escaping in multiple ways:
file
with single quotes, double quotes, triple quotes, made it a slashy and a dollarslashy string -> Tried to create a File objectThere have been a few more things I tried, but I cannot recall them due to frustration.
My final attempt was to try and just add an empty file
node to the XML, however when using file()
gradle did not know which File-constructor to use, and when I used file
I got an error: Namespace prefix: file is not bound to a URI
If anyone has any idea how to properly escape file
or has another way of adding said file
-node to the XML please let me know.
Thank you.
(1) call builder functions on delegate:
//just declare `file` to emulate problem in usual groovy console
def file={String a, String b-> println "file: a=$a, b=$b"}
def xml = new XmlSlurper(false,false).parseText('''
<root>
<profile>
<subsystem xmlns="urn:jboss:domain:logging:3.0"/>
</profile>
</root>''')
def logging = xml.profile.subsystem.find{ it['@xmlns'] == "urn:jboss:domain:logging:3.0" }
logging.plus{
logger(category:"loggingCategory") {
level(name:"LEVEL")
}
//be specific that you want to call file function on delegate and not on owner (by default)
delegate.'file'(path:"file.log", "relative-to":"jboss.logging.dir")
//or this also works:
"${'file'}"(path:"file.log", "relative-to":"jboss.logging.dir")
}
println groovy.xml.XmlUtil.serialize(xml)
(2) workaround with XmlParser :
use current
as accessor to current parent node
def xml = new XmlParser(false,false).parseText('''
<root>
<profile>
<subsystem xmlns="urn:jboss:domain:logging:3.0"/>
</profile>
</root>''')
def logging = xml.profile.subsystem.find{ it['@xmlns'] == "urn:jboss:domain:logging:3.0" }
logging.plus{
logger(category:"loggingCategory") {
level(name:"LEVEL")
}
current.appendNode("file", [path:"file.log", "relative-to":"jboss.logging.dir"])
}
println groovy.xml.XmlUtil.serialize(xml)