Link to home
Start Free TrialLog in
Avatar of CEHJ
CEHJFlag for United Kingdom of Great Britain and Northern Ireland

asked on

Logback programmatic configuration logging twice

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.core.ConsoleAppender;
import ch.qos.logback.core.rolling.RollingFileAppender;
import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;

import org.slf4j.LoggerFactory;
import org.slf4j.ILoggerFactory;

public class LogbackConfigurer {

  public static Logger getDefaultLoggerWithLevel(Level level) {
    LoggerContext logCtx = (LoggerContext)LoggerFactory.getILoggerFactory();

    PatternLayoutEncoder logEncoder = new PatternLayoutEncoder();
    logEncoder.setContext(logCtx);
    logEncoder.setPattern("%-12date{YYYY-MM-dd HH:mm:ss.SSS} %-5level - %msg%n");
    logEncoder.start();

    ConsoleAppender logConsoleAppender = new ConsoleAppender();
    logConsoleAppender.setContext(logCtx);
    logConsoleAppender.setName("console");
    logConsoleAppender.setEncoder(logEncoder);
    logConsoleAppender.start();
    Logger log = logCtx.getLogger("Main");
    log.setAdditive(false);
    log.setLevel(level);
    log.addAppender(logConsoleAppender);
    return log;
  }
}


Open in new window



Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

ASKER

There is unfortunately seemingly little information around about configuring programmatically.

Unfortunately the Logger returned from the above logs twice to the console, despite the fact that additivity is meant to be false.

Please test any hypotheses before posting

Sorry about the formatting – I find the interface almost impossible to use
I can't/haven't tested hypotheses, sry, but allow me to ask whether your call to setAdditive(boolean) (line 28) shouldn't possibly be setAdditivity(boolean) instead ? i.e. a typo ?
Avatar of CEHJ

ASKER

No, it's correct
Avatar of CEHJ

ASKER

    private Logger getLoggerWithLevel(Level level) {
        // Programmatic configuration
        System.setProperty("java.util.logging.SimpleFormatter.format",
                "%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%1$tL %4$-7s [%3$s] (%2$s) %5$s %6$s%n");

        final ConsoleHandler consoleHandler = new ConsoleHandler();
        consoleHandler.setLevel(level);
        consoleHandler.setFormatter(new SimpleFormatter());

        final Logger log = Logger.getLogger("log");
        log.setLevel(level);
        log.addHandler(consoleHandler);
        log.setUseParentHandlers(false);
        return log;
    }

Open in new window

called with
        if (cmd.hasOption("ld")) {
            setLogDebug(true);
            setLogLevel(Level.FINE);
            setLogger(getLoggerWithLevel(Level.FINE));
            System.out.println("LOGGING");
            log.fine(String.format("Logging at level %s for the whole application", getLogLevel()));
        }

Open in new window

Does exactly the same thing: log.fine prints twice whereas "LOGGING" prints once. And this is with java.util.logging, not logback
Avatar of CEHJ

ASKER

import java.util.logging.Logger;

import java.util.logging.Level;
import java.util.logging.ConsoleHandler;
import java.util.logging.SimpleFormatter;

public class Test {
    private Logger log = null;

    private boolean noAct;
    private boolean logDebug;
    private Level logLevel;
    private Integer maxDepth;

    public boolean getNoAct() {
        return this.noAct;
    }

    public Integer getMaxDepth() {
        return this.maxDepth;
    }

    public boolean getLogDebug() {
        return this.logDebug;
    }

    public void setNoAct(boolean noAct) {
        this.noAct = noAct;
    }

    public void setMaxDepth(Integer maxDepth) {
        this.maxDepth = maxDepth;
    }

    public void setLogDebug(boolean logDebug) {
        this.logDebug = logDebug;
    }

    public Logger getLogger() {
        return this.log;
    }

    public Level getLogLevel() {
        return this.logLevel;
    }

    public void setLogger(Logger log) {
        this.log = log;
    }

    public void setLogLevel(Level logLevel) {
        this.logLevel = logLevel;
    }

    private Logger getLoggerWithLevel(Level level) {
        // Programmatic configuration
        System.setProperty("java.util.logging.SimpleFormatter.format",
                "%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%1$tL %4$-7s [%3$s] (%2$s) %5$s %6$s%n");

        final ConsoleHandler consoleHandler = new ConsoleHandler();
        consoleHandler.setLevel(level);
        consoleHandler.setFormatter(new SimpleFormatter());

        final Logger log = Logger.getLogger("log");
        log.setLevel(level);
        log.addHandler(consoleHandler);
        log.setUseParentHandlers(false);
        return log;
    }

    @Override
    public String toString() {
        return String.format("%s=%s,%s=%d,%s=%s", "noAct", noAct, "maxDepth", maxDepth, "logDebug", logDebug);
    }

    // Testing only
    public static void main(String[] args) {
        Test t = new Test();
        Logger log = t.getLoggerWithLevel(Level.FINE);
        log.fine("Testing...");
    }

}

Open in new window

The above is ok, iow just prints once
ASKER CERTIFIED SOLUTION
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Well I suppose answering your own question is testimony, if any were needed, as to why you are where you are on the board ! : )    ;)