Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring-XD does not read logback.xml

I am trying to run a job in Spring-XD, located under the following path:

/spring-xd/xd/modules/job/MyJobName (I'll call this path MyJobName below)

My jar, located under MyJobName/lib, contains in its root path the file logback.xml. Unfortunately, Spring-XD seems to be completely ignoring that file. When I run the job through my IDE (IntelliJ), the logging works fine, but when I run it using Spring-XD it completely ignores my SiftingAppender.

Here is what my logback.xml file looks like:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%5p %-25logger{25} %m %n</pattern>
        </encoder>
    </appender>

    <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
        <discriminator>
            <key>publication.run.id</key>
            <defaultValue>unknown</defaultValue>
        </discriminator>
        <sift>
            <appender name="FILE-${publication.run.id}" class="ch.qos.logback.core.FileAppender">
                <file>/data/${publication.run.id}/logs/process.log</file>
                <append>true</append>
                <layout class="ch.qos.logback.classic.PatternLayout">
                    <pattern>%5p %-25logger{25} %m %n</pattern>
                </layout>
            </appender>
        </sift>
    </appender>

    <logger name="com.bitwiseor">
        <level value="INFO" />
    </logger>

    <logger name="org.springframework">
        <level value="INFO" />
    </logger>

    <root>
        <level value="INFO" />
        <appender-ref ref="SIFT" />
        <appender-ref ref="CONSOLE" />
    </root>
</configuration>

I want to put this logback.xml file under /spring-xd/xd/config, or under another configuration folder, but nothing I try works. I tried looking through the Spring-XD docs, but found nothing.

Any insight would be appreciated.

like image 758
Jonathan Pitre Avatar asked Aug 20 '15 19:08

Jonathan Pitre


2 Answers

You have to put Logback directly in the classpath. See here:

Logback can be configured either programmatically or with a configuration script expressed in XML or Groovy format. By the way, existing log4j users can convert their log4j.properties files to logback.xml using our PropertiesTranslator web-application.

Let us begin by discussing the initialization steps that logback follows to try to configure itself:

  • Logback tries to find a file called logback.groovy in the classpath.

  • If no such file is found, logback tries to find a file called logback-test.xml in the classpath.

  • If no such file is found, it checks for the file logback.xml in the classpath.

  • If no such file is found, and the executing JVM has the ServiceLoader (JDK 6 and above) the ServiceLoader will be used to resolve an implementation of com.qos.logback.classic.spi.Configurator. The first implementation found will be used. See ServiceLoader documentation for more details.

  • If none of the above succeeds, logback configures itself automatically using the BasicConfigurator which will cause logging output to be directed to the console.

It sounds to me like your configuration file is not in the classpath. Generally the config directory is not in the classpath by default in most frameworks, in many cases it's /config/<files> that are in the class path, and you have to specify them with /config/name when loading them with the ClassLoader. However, Logback doesn't do that, so if you want to store the files in the config directory, you have to load them manually.

Essentially, you can tell JoranConfigurator to load the file from a custom location in your classpath, handle the errors, and so forth to make sure you've found your file. See here for more details.

Here is how I load my Logback config, you can probably adapt this to your system. In this case resource is the path within your classpath to wherever you've decided to put your logback.xml file. In this case it would probably be /spring-xd/xd/config/logback.xml.

public class LogbackConfigurator {
    private static final Logger LOG =
            LoggerFactory.getLogger(LogbackConfigurator.class);
    
    public static boolean configure(String resource) throws JoranException {
        final InputStream configInputStream = LogbackConfigurator.class.getResourceAsStream(resource);
        final LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
        
        JoranConfigurator configurator = new JoranConfigurator();
        configurator.setContext(loggerContext);
        //  the context was probably already configured by default configuration rules
        loggerContext.reset();
        
        if(configInputStream != null) {
            try {
                configurator.doConfigure(configInputStream);
            } catch (JoranException e) {
                e.printStackTrace();
            }
            StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext);
            return true;
        } else {
            LOG.error("Unable to find logback file: {}", resource);
            StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext);
            return false;
        }
    }
}

Typically, this method would be called as one of the first lines in main with something like:

LogbackConfigurator.configure(path);

Once this class has been run, your logback should be configured as if the system had been able to find the configuration file normally. Note that you can also use -Dproperty=value and System.getProperties().get(keyname) to specify an alternate location for the path to the logback file dynamically if you don't want to hardcode the location into your system.

You can also configure the location to be injected in your Spring configuration, but I personally don't recommend that as you would normally like logging to be configured before injection occurs, so that if any logging events occur during injection, they will be logged appropriately.

like image 188
durron597 Avatar answered Oct 06 '22 15:10

durron597


Seems like your logback configuration is having some minor issues.

Try putting the below configuration into your application classpath; should resolve the problem.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%5p %-25logger{25} %m %n</pattern>
        </encoder>
    </appender>
    <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
        <discriminator>
            <key>publication.run.id</key>
            <defaultValue>unknown</defaultValue>
        </discriminator>
        <sift>
            <appender name="FILE-${publication.run.id}" class="ch.qos.logback.core.FileAppender">
                <file>/data/${publication.run.id}/logs/process.log</file>
                <append>true</append>
                <layout class="ch.qos.logback.classic.PatternLayout">
                    <pattern>%5p %-25logger{25} %m %n</pattern>
                </layout>
            </appender>
        </sift>
    </appender>
    <logger name="com.bitwiseor" level="INFO" />
    <logger name="org.springframework" level="INFO" />
    <root level="INFO">
        <appender-ref ref="SIFT" />
        <appender-ref ref="CONSOLE" />
    </root>
</configuration>

Note below part is changed according to the logback configuration reference:

<logger name="com.bitwiseor" level="INFO" />
<logger name="org.springframework" level="INFO" />
<root level="INFO">
    <appender-ref ref="SIFT" />
    <appender-ref ref="CONSOLE" />
</root>
like image 38
Ahsan Shah Avatar answered Oct 06 '22 16:10

Ahsan Shah