Skip to content

qos-ch/logback-tyler

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

89 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

logback-tyler

Logback-tyler translates logback-classic XML configuration files into Java.

The resulting java class named TylerConfigurator implements the Configurator interface. It can thus be declared as a custom configuration provider using Java's standard service-provider meachanism. Custom configurators are searched by looking up a provider-configuration file resource located under the META-INF/services/ch.qos.logback.classic.spi.Configurator file in your project. This provider-configuration should contain a line with the fully qualified class name of your desired configurator.

Running TylerConfigurator does not require XML parsers and usually executes noticeably faster than JoranConfigurator, logback's XML configurator. Moreover, TylerConfigurator does not use reflection. In addition, given that it ships with your project's binaries, it is harder to modify and offers an even smaller attack surface.

At runtime, TylerConfigurator does not have any additional dependencies other than logback-classic version 1.5.10.

Online instance

A instance of logback-tyler translator is available online. Do not hesitate to experiment with it.

Running the translator locally

Logback-tyler is located at the following Maven coordinates:

 <groupId>ch.qos.logback.tyler</groupId>
 <artifactId>tyler-base</artifactId>
 <version>0.9</version>

Here is a sample program to translate a logback.xml as string into Java.

import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.model.Model;
import ch.qos.logback.core.util.StatusPrinter;

import java.io.IOException;

public class TylerExample {

    String xmlInput =
    """
            <configuration debug="true">
              <import class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"/>
              
              <property name="APP_NAME" value="myApp"/>
             
              <contextName>${APP_NAME}</contextName>
             
              <appender class="ch.qos.logback.core.FileAppender" name="TOTO">
                <file>toto.log</file>
                <append>true</append>
                <immediateFlush>true</immediateFlush>
                <encoder>
                  <pattern>%-4relative [%thread] %-5level %logger{35} -%kvp- %msg%n</pattern>
                </encoder>   
              </appender>         
             
             
              <root level="DEBUG">
                <appender-ref ref="TOTO"/>
              </root>             
            </configuration>                 
    """;
    
    public static void main(String[] args)  throws JoranException, IOException {
        ContextBase context = new ContextBase();
        ModelToJava m2j = new ModelToJava(context);
        Model model = m2j.extractModel(xmlInput);
        String result = m2j.toJava(model);
        System.out.println(result);
        // print any error messages occuring during the translation
        StatusPrinter.print(context);
    }
}

running the above program will produce the following output

import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.Configurator;
import ch.qos.logback.classic.tyler.TylerConfiguratorBase;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.FileAppender;
import ch.qos.logback.core.joran.spi.NoAutoStartUtil;
import ch.qos.logback.core.spi.ContextAware;
import ch.qos.logback.core.spi.LifeCycle;
import java.lang.Override;

/**
 *
 * <p>This file was generated by logback-tyler version 0.9.</p>
 *
 * <p>Eventual errors and warnings are appended at the end.</p>
 *
 * <p>You may experiment with logback.xml to Java translation, i.e.
 * TylerConfigurator generation, at the following URL:</p>
 *
 * <p>      https://logback.qos.ch/translator/services/xml2Java.html </p>
 *
 * <p>This generated TylerConfigurator class is intended to be copied and integrated
 * into the user's project as a custom configurator. It will configure logback
 * without XML. You are free to rename TylerConfigurator as you wish.</p>
 *
 * <p>It requires logback-classic version 1.5.11 or later at runtime.</p>
 *
 * <p>Custom configurators are looked up via Java's service-provide facility. If a
 * custom provider is found, it takes precedence over logback's own configurators,
 * e.g. DefaultJoranConfigurator.</p>
 *
 * <p>To install your custom configurator to your project, add a
 * provider-configuration file to the following path:</p>
 *
 * <pre>  META-INF/services/ch.qos.logback.classic.spi.Configurator</pre>
 *
 * <p>This provider-configuration file should contain a line with the fully
 * qualified class name of your tyler configurator.</p>
 *
 * <p>See also item 1 of 'Configuration at initialization' section at </p>
 *
 * <p>  https://logback.qos.ch/manual/configuration.html#auto_configuration</p>
 *
 * <p>With recent versions of logback and logback-tyler you can still
 * configure logger levels dynamically using properties files. Note that
 * configuration files in properties format can be watched for
 * changes. See the documentation on PropertiesConfigurator for more details.</p>
 *
 * <p>https://logback.qos.ch/manual/configuration.html#propertiesConfigurator</p>
 *
 * <p>Keep in mind that by integrating a .properties configuration file info
 * your tyler configurator, you can still change logger levels dynamically, without
 * redeploying your application.</p>
 *
 */
class TylerConfigurator extends TylerConfiguratorBase implements Configurator {
  /**
   * <p>This method performs configuration per {@link Configurator} interface.</p>
   *
   * <p>If <code>TylerConfigurator</code> is installed as a configurator service, this
   * method will be called by logback-classic during initialization.</p>
   */
  @Override
  public Configurator.ExecutionStatus configure(LoggerContext loggerCoontext) {
    setContext(loggerCoontext);
    addOnConsoleStatusListener();
    propertyModelHandlerHelper.handlePropertyModel(this, "APP_NAME", "myApp", "", "", "");
    setContextName(subst("${APP_NAME}"));
    Appender appenderRFILE = setupAppenderRFILE();
    logger_ROOT.addAppender(appenderRFILE);
    Logger logger_ROOT = setupLogger("ROOT", "DEBUG", null);
    return ExecutionStatus.DO_NOT_INVOKE_NEXT_IF_ANY;
  }

  Appender setupAppenderRFILE() {
    FileAppender appenderRFILE = new FileAppender();
    appenderRFILE.setContext(context);
    appenderRFILE.setName("RFILE");
    appenderRFILE.setFile("toto.log");
    appenderRFILE.setAppend(true);
    appenderRFILE.setImmediateFlush(true);

    // Configure component of type PatternLayoutEncoder
    PatternLayoutEncoder patternLayoutEncoder = new PatternLayoutEncoder();
    patternLayoutEncoder.setContext(context);
    
    patternLayoutEncoder.setPattern("%-4relative [%thread] %-5level %logger{35} -%kvp- %msg%n");
    patternLayoutEncoder.setParent(appenderRFILE);
    patternLayoutEncoder.start();
    
    // Inject component of type PatternLayoutEncoder into parent
    appenderRFILE.setEncoder(patternLayoutEncoder);

    appenderRFILE.start();
    return appenderRFILE;
  }
}

----------------
15:44:51,087 |-INFO in ch.qos.logback.tyler.base.handler.ImplicitModelHandler - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
15:44:51,092 |-INFO in ch.qos.logback.core.model.processor.DefaultProcessor@1f760b47 - End of configuration.

About

Logback XML configuration to Java translation project

Resources

License

Security policy

Stars

Watchers

Forks

Packages

No packages published

Languages