I like the first syntax with the map-like API. 

About Ralph’s concern, would it not be possible for the DSL to create actual 
Appender and Layout objects? What prevents us from doing this?

Remko

> On May 4, 2019, at 3:25, Matt Sicker <[email protected]> wrote:
> 
> Second example was a typo it looks like.
> 
> On Fri, May 3, 2019 at 12:57, Ralph Goers <[email protected]>
> wrote:
> 
>> My only concern is that people might be expecting a DSL to create the
>> actual Appenders, Layouts, etc. where this will just be creating
>> configuration Nodes. That said, I don’t have a problem with it. I am not
>> sure that your second example is valid since you are declaring an appender
>> without an appenders node. The first syntax looks more concise to me.
>> 
>> Ralph
>> 
>>> On May 3, 2019, at 10:08 AM, Matt Sicker <[email protected]> wrote:
>>> 
>>> I believe Ralph has brought up a feature request in the past, though I
>>> don't remember where. Anyways, Logback has a Groovy DSL [1] as an
>>> option to configure itself, and we could introduce a similar feature
>>> built on top of the existing ConfigurationBuilder code from the Java
>>> DSL in log4j-core. After seeing how easily Groovy integrates with Java
>>> to form DSLs in Jenkins [2] (more so in the web framework than in
>>> pipelines, but both are valid), I've been considering working on such
>>> a feature.
>>> 
>>> Let's take a random configuration sample from the manual [3]:
>>> 
>>> <?xml version="1.0" encoding="UTF-8"?>
>>> <Configuration status="WARN">
>>> <Appenders>
>>>   <Console name="Console" target="SYSTEM_OUT">
>>>     <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level
>>> %logger{36} - %msg%n"/>
>>>   </Console>
>>> </Appenders>
>>> <Loggers>
>>>   <Logger name="com.foo.Bar" level="trace">
>>>     <AppenderRef ref="Console"/>
>>>   </Logger>
>>>   <Root level="error">
>>>     <AppenderRef ref="Console"/>
>>>   </Root>
>>> </Loggers>
>>> </Configuration>
>>> 
>>> If I were to translate this to the equivalent Groovy DSL, here is one
>>> example of how that might look:
>>> 
>>> configuration(status: 'warn') {
>>> appenders {
>>>   console(name: 'Console', target: 'SYSTEM_OUT') {
>>>     patternLayout(pattern: '%d{HH:mm:ss.SSS} [%t] %-5level
>>> %logger{36} - %msg%n')
>>>   }
>>> }
>>> loggers {
>>>   logger(name: 'com.foo.Bar', level: 'trace') {
>>>     appenderRef(ref: 'Console')
>>>   }
>>>   root(level: 'error') {
>>>     appenderRef(ref: 'Console')
>>>   }
>>> }
>>> }
>>> 
>>> An alternative syntax would be to switch from using method parameters
>>> to properties of the closure. For example, that might look like:
>>> 
>>> configuration {
>>> status = 'warn'
>>> console {
>>>   name = 'Console'
>>>   target = 'SYSTEM_OUT'
>>>   patternLayout {
>>>     pattern = '%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n'
>>>   }
>>> }
>>> // ...
>>> }
>>> 
>>> Are there any preferences on syntax? I don't think we can get super
>>> fancy with the DSL due to the underlying APIs (i.e., we can't provide
>>> much in the way of code completion AFAIK), but supporting a dynamic
>>> DSL like that is fairly easy with Groovy. This does open a question of
>>> configuration being scripted versus declarative since we'd be offering
>>> a full script engine technically in order to write your configuration.
>>> I do not expect this feature to offer a programmatic way of
>>> manipulating the underlying plugin objects (i.e., this would be for
>>> building a Configuration, not manipulating a running one); that might
>>> make more sense with a more standardized plugin API which is a
>>> wishlist item I have for 3.0.
>>> 
>>> [1]: https://logback.qos.ch/manual/groovy.html
>>> [2]:
>> https://github.com/stapler/stapler/blob/master/groovy/src/main/java/org/kohsuke/stapler/jelly/groovy/JellyBuilder.java
>>> [3]: https://logging.apache.org/log4j/2.x/manual/configuration.html
>>> 
>>> --
>>> Matt Sicker <[email protected]>
>>> 
>> 
>> 
>> --
> Matt Sicker <[email protected]>

Reply via email to