A follow-on feature could be a Kotlin DSL. Kotlin is fully typed, but
with a lot of Groovy-like features that enable elegant DSLs. The
Gradle team, for example, has created a Kotlin DSL that can be used
instead of their Groovy DSL. I don't know the details of how it works,
but IntelliJ is able to provide type-safe validation and code
completion for the Gradle Kotlin DSL. I suspect a Kotlin DSL for Log4j
could benefit from the same capabilities.

Regards,
Raman

On Fri, May 3, 2019 at 1:08 PM 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]>

Reply via email to