Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

slf4j/logback FileAppender writing in eclipse workspace

I have a eclipse RCP application using slf4j/logback to catch all the log messages.

Right now I have the following file appender configured:

<appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>softmodeler_client.log</file>
    <append>true</append>
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <pattern>[%date] %level: %logger - %m%n</pattern>
    </encoder>
</appender>

This writes the log file into the application installation directory.
Some customers do not permit write access in the installation directory.
In that case we redirect the workspace and configurations directory defining the following in the Applicationname.ini file:

-data
@user.home/AppData/Roaming/Applicationname/workspace
-configuration
@user.home/AppData/Roaming/Applicationname/configuration

Now I would like to configure the logback.xml like this, pointing the logfile to the writable workspace directory:

<file>${osgi.instance.area}softmodeler_client.log</file>

This results in a FileNotFoundException, because of the file:/ prefix of the osgi.instance.area system property. I did not find another property without the protocol.

My question is how can I configure logback to write into my workspace, without having to modify the logback.xml every time?

EDIT:
Maybe I can register a listener from where I can set some initial properties?
I would prefer to use an existing system property or programmatically pass a variable to the logging framework. The goal is, not having to configure an additional parameter/variable for every installation (since quite a few and might be missed during updates). Just somehow automatically always write the log file into the workspace directory.

like image 411
flavio.donze Avatar asked Aug 25 '15 09:08

flavio.donze


1 Answers

How can I configure logback to write into my workspace, without having to modify the logback.xml everytime?

I would like to suggest you that if any user wants to use his own specific location to write his log file, then it will be best to use a properties file.

dataLocation.properties file have a location. It may be changed per user.

logpathfile = d://logFiles

Then this path will be read from a java file and it will be sent to logback.xml file.


For example, I am using a sessionid as parameter. It is sent to logback.xml from java file. Hope you can adjust it with your code.

LoggerBySessionId.java

/**
 * 2    * Logback: the reliable, generic, fast and flexible logging framework.
 * 3    * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
 * 4    *
 * 5    * This program and the accompanying materials are dual-licensed under
 * 6    * either the terms of the Eclipse Public License v1.0 as published by
 * 7    * the Eclipse Foundation
 * 8    *
 * 9    *   or (per the licensee's choosing)
 * 10   *
 * 11   * under the terms of the GNU Lesser General Public License version 2.1
 * 12   * as published by the Free Software Foundation.
 * 13
 */
package com.waze.rr_logger;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

public class LoggerBySessionId {

    String configFile = "logback.xml";

    public LoggerBySessionId() {
    }

    public LoggerBySessionId(String configFile) {
        this.configFile = configFile;
    }

    public void log(String sessionId, String content) throws JoranException {

        LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
        JoranConfigurator configurator = new JoranConfigurator();
        lc.reset();
        configurator.setContext(lc);
        configurator.doConfigure(configFile);

        Logger logger = LoggerFactory.getLogger(LoggerBySessionId.class);
        MDC.put("sessionId", sessionId); // this sessionId is sent to logback.xml
        logger.debug(content);
    }

    static void usage(String msg) {
        System.err.println(msg);
        System.err.println("Usage: java " + LoggerBySessionId.class.getName() + " configFile\n" + "   configFile a logback " +
                "configuration file");
        System.exit(1);
    }
}

logback.xml

<configuration>
    <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
        <!-- in the absence of the class attribute, it is assumed that the
             desired discriminator type is
             ch.qos.logback.classic.sift.MDCBasedDiscriminator -->
        <discriminator>
            <key>userid</key>
            <defaultValue>no_session_id</defaultValue>
        </discriminator>
        <sift>
            <appender name="FILE-${sessionId}" class="ch.qos.logback.core.FileAppender">
                <file>${userid}.log</file>
                <append>true</append>
                <layout class="ch.qos.logback.classic.PatternLayout">
                    <pattern>%d [%thread] %level %mdc %logger{35} - %msg%n</pattern>
                </layout>
            </appender>
            <appender name="FILE-${sessionId}" class="ch.qos.logback.core.FileAppender">
                <file>${userid}.log</file>
                <append>false</append>
                <layout class="ch.qos.logback.classic.PatternLayout">
                    <pattern>%d [%thread] %level %mdc %logger{35} - %msg%n</pattern>
                </layout>
            </appender>
        </sift>
    </appender>

    <root level="DEBUG">
        <appender-ref ref="SIFT" />
    </root>
</configuration>
like image 66
SkyWalker Avatar answered Oct 21 '22 13:10

SkyWalker