15 Frage: Festlegen der Protokollebene der Nachricht zur Laufzeit in slf4j

Frage erstellt am Mon, Apr 12, 2010 12:00 AM

Bei Verwendung von log4j steht die Logger.log(Priority p, Object message)-Methode zur Verfügung, mit der eine Nachricht auf einer zur Laufzeit festgelegten Protokollebene protokolliert werden kann. Wir verwenden diesen Fakt und diesen Tipp um stderr auf einen Logger mit einer bestimmten Log-Ebene umzuleiten.

slf4j hat keine generische log()-Methode, die ich finden kann. Bedeutet das, dass es keine Möglichkeit gibt, das oben Gesagte umzusetzen?

    
85
  1. Es sieht so aus, als gäbe es eine Diskussion darüber, ob slf4j 2.0 auf der Dev-Mailingliste hinzugefügt werden könnte: qos.ch/pipermail/slf4j-dev/2010-March/002865.html
    2010-04-12 12: 42: 43Z
  2. Sehen Sie sich Marker an. Hierbei handelt es sich um benutzerdefinierte Daten, die Sie an die Protokollkette übergeben können.
    2013-07-15 11: 43: 28Z
  3. @tuxSlayer Können Sie bitte erläutern, wie Marker in diesem Fall verwendet wird?
    2013-09-05 02: 16: 03Z
  4. Wahrscheinlich ist es nicht die beste Idee zum "Protokollieren", aber Sie können mehrere Markierungen für den Protokolleintrag "priority" (hoch | niedrig | normal, info | warn | fatal) verwenden. und Filterung in Logback oder benutzerdefiniertem Appender verwenden, um Markierungen zu verbrauchen und Protokolleinträge in separate Kanäle zu verschieben (Protokollinformationen, E-Mail-Fehler usw.). Der direktere Weg ist jedoch, eine Fassade dafür zu haben, wie in den Antworten unten gezeigt wurde.
    2013-09-09 10: 06: 45Z
  5. Diese Funktion soll Teil von slf4j 2.0 sein. jira.qos.ch/browse/SLF4J-124 Siehe meine Antwort für Details und für eine mögliche slf4j 1.x-Problemumgehung.
    23.05.2019 06: 52: 22Z
15 Antworten                              15                         

Mit slf4j ist dies nicht möglich.

Ich stelle mir vor, dass der Grund dafür, dass diese Funktionalität fehlt, darin besteht, dass es so gut wie unmöglich ist, einen Level-Typ für slf4j zu erstellen, der effizient auf den Level-Typ (oder einen gleichwertigen Typ) abgebildet werden kann, der in allen möglichen Protokollierungsimplementierungen verwendet wird, die sich hinter dem befinden Fassade. Alternativ haben die Designer entschieden, dass Ihr Anwendungsfall zu ungewöhnlich ist , um den Mehraufwand für die Unterstützung zu rechtfertigen es.

In Bezug auf @ ripper234 's Anwendungsfall (Komponententest). Ich denke, die pragmatische Lösung besteht darin, die Komponententests zu modifizieren, um zu erkennen, welches Protokollierungssystem sich hinter der slf4j-Fassade befindet. ., wenn die Einheitentests ausgeführt werden.

    
40
2017-05-23 12: 34: 18Z
  1. Es ist wirklich keine Zuordnung erforderlich. In org.slf4j.Logger sind bereits fünf Ebenen implizit durch die Methoden definiert: Debug, Fehler, Info, Trace, Warnung.
    2010-04-12 12: 45: 35Z
  2. WTF? SLF4J wird als die Zukunft der Java-Protokollierung angekündigt, und dieser einfache Anwendungsfall wird nicht unterstützt? (Das erste, was ich nach der Integration von SLF4J versucht habe, um das Durcheinander bei Unit-Tests zu verringern.)
    30.11.2010 06: 34: 24Z
  3. hat Folgendes als Problem veröffentlicht: bugzilla.slf4j.org/show_bug.cgi?id=206
    30.11.2010 06: 43: 03Z
  4. @ ripper234 - Ich glaube nicht, dass Ihr Fehler dasselbe Problem wie die ursprüngliche Frage von scompt.com angesprochen hat. Sie haben gefragt, ob Sie die Ebene des zugrunde liegenden Protokollierungssystems über die SLF4J-API konfigurieren möchten. Was scompt.com suchte, war eine generische "Protokoll" -Methode in der SLF4J-API, die den Protokollierungsgrad der Nachricht als Parameter verwendet.
    2011-05-25 21: 24: 43Z
  5. Die RFE-Links werden nicht mehr aufgelöst. Die relevanten Links sind jetzt: jira.qos.ch/browse/SLF4J-124 und jira.qos.ch/browse/SLF4J-197 ... und beide waren es geschlossen. Lesen Sie die Kommentare für die Begründung.
    2015-04-23 12: 20: 59Z

Richard Fearn hat die richtige Idee, also habe ich die gesamte Klasse basierend auf seinem Skeleton-Code geschrieben. Es ist hoffentlich kurz genug, um hier zu posten. Kopieren & Paste zum Genießen. Ich sollte wahrscheinlich auch eine magische Beschwörung hinzufügen: "Dieser Code ist gemeinfrei"

 
import org.slf4j.Logger;

public class LogLevel {

    /**
     * Allowed levels, as an enum. Import using "import [package].LogLevel.Level"
     * Every logging implementation has something like this except SLF4J.
     */

    public static enum Level {
        TRACE, DEBUG, INFO, WARN, ERROR
    }

    /**
     * This class cannot be instantiated, why would you want to?
     */

    private LogLevel() {
        // Unreachable
    }

    /**
     * Log at the specified level. If the "logger" is null, nothing is logged.
     * If the "level" is null, nothing is logged. If the "txt" is null,
     * behaviour depends on the SLF4J implementation.
     */

    public static void log(Logger logger, Level level, String txt) {
        if (logger != null && level != null) {
            switch (level) {
            case TRACE:
                logger.trace(txt);
                break;
            case DEBUG:
                logger.debug(txt);
                break;
            case INFO:
                logger.info(txt);
                break;
            case WARN:
                logger.warn(txt);
                break;
            case ERROR:
                logger.error(txt);
                break;
            }
        }
    }

    /**
     * Log at the specified level. If the "logger" is null, nothing is logged.
     * If the "level" is null, nothing is logged. If the "format" or the "argArray"
     * are null, behaviour depends on the SLF4J-backing implementation.
     */

    public static void log(Logger logger, Level level, String format, Object[] argArray) {
        if (logger != null && level != null) {
            switch (level) {
            case TRACE:
                logger.trace(format, argArray);
                break;
            case DEBUG:
                logger.debug(format, argArray);
                break;
            case INFO:
                logger.info(format, argArray);
                break;
            case WARN:
                logger.warn(format, argArray);
                break;
            case ERROR:
                logger.error(format, argArray);
                break;
            }
        }
    }

    /**
     * Log at the specified level, with a Throwable on top. If the "logger" is null,
     * nothing is logged. If the "level" is null, nothing is logged. If the "format" or
     * the "argArray" or the "throwable" are null, behaviour depends on the SLF4J-backing
     * implementation.
     */

    public static void log(Logger logger, Level level, String txt, Throwable throwable) {
        if (logger != null && level != null) {
            switch (level) {
            case TRACE:
                logger.trace(txt, throwable);
                break;
            case DEBUG:
                logger.debug(txt, throwable);
                break;
            case INFO:
                logger.info(txt, throwable);
                break;
            case WARN:
                logger.warn(txt, throwable);
                break;
            case ERROR:
                logger.error(txt, throwable);
                break;
            }
        }
    }

    /**
     * Check whether a SLF4J logger is enabled for a certain loglevel. 
     * If the "logger" or the "level" is null, false is returned.
     */

    public static boolean isEnabledFor(Logger logger, Level level) {
        boolean res = false;
        if (logger != null && level != null) {
            switch (level) {
            case TRACE:
                res = logger.isTraceEnabled();
                break;
            case DEBUG:
                res = logger.isDebugEnabled();
                break;
            case INFO:
                res = logger.isInfoEnabled();
                break;
            case WARN:
                res = logger.isWarnEnabled();
                break;
            case ERROR:
                res = logger.isErrorEnabled();
                break;
            }
        }
        return res;
    }
}
    
25
2011-10-19 23: 48: 05Z
  1. Dies ist einfacher mit einem variadischen (Object ...) args-Parameter zu verwenden.
    2012-06-27 21: 54: 55Z
  2. "org.slf4j.Logger" verfügt über eine Reihe von Signaturen für Protokollierungsmethoden, die in der obigen Klasse nicht behandelt werden. Daher ist wahrscheinlich eine Erweiterung erforderlich: slf4j.org/api/org/slf4j/Logger.html
    2013-12-20 17: 17: 38Z
  3. Ich denke, dass diese Implementierung eine nicht gewünschte Änderung hinzufügen wird. Wenn Sie den Aufruf logger.info verwenden (...), hat der Logger Zugriff auf die Anruferklasse und -methode und kann automatisch zum Protokolleintrag hinzugefügt werden. Mit dieser Implementierung erstellt das Anrufprotokoll (Logger, Level, TXT) einen Protokolleintrag, der immer den gleichen Aufrufer hat: Loglevel.log. Habe ich recht?
    12.08.2015 06: 51: 52Z
  4. @ Domin Hallo, Sie meinen, der Logger könnte den aktuellen Aufrufstapel untersuchen und dann den letzten Eintrag für die automatische Protokollierung extrahieren, was hier nicht der Fall ist? Im Prinzip ja, aber tatsächlich wächst der Stack danach noch ein bisschen weiter, bis die eigentliche Nachricht ausgeschrieben ist (insbesondere muss irgendwann ein Logback aufgerufen werden, dann der eigentliche Appender). Ich denke, es sollte die Rolle des Appenders sein, nicht interessante Stack-Zeilen wegzuwerfen, so dass Sie es anpassen können, um alles bis einschließlich des Aufrufs dieser Loglevel-Klasse wegzuwerfen.
    2015-08-12 18: 07: 19Z
  5. @ David, ja, du hast recht :-). Ich bin mir nicht sicher, ob dies eine Aufgabe für den Appender ist, da Sie in diesem Fall eine harte Abhängigkeit zwischen dem Appender und dem Logger definieren ... aber ... es ist eine Lösung. Vielen Dank, David
    2015-08-14 14: 10: 45Z

    Wechseln Sie zu Logback und verwenden Sie

     
    ch.qos.logback.classic.Logger rootLogger = (ch.qos.logback.classic.Logger)LoggerFactory.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
    rootLogger.setLevel(Level.toLevel("info"));
    

    Ich glaube, dies ist der einzige Aufruf von Logback, und der Rest Ihres Codes bleibt unverändert. Logback verwendet SLF4J und die Migration ist problemlos, lediglich die XML-Konfigurationsdateien müssen geändert werden.

    Vergessen Sie nicht, die Protokollebene zurückzusetzen, nachdem Sie fertig sind.

        
    12
    2017-01-14 00: 20: 30Z
    1. Ich habe bereits Logback-gesichertes slf4j verwendet und konnte meine Komponententests sofort bereinigen. Vielen Dank!
      18.03.2014 23: 51: 06Z
    2. - 1 Darum geht es in dieser Frage nicht.
      28.03.2014 10: 54: 23Z
    3. Dies war mein erster -1, danke. Ich glaube du liegst falsch. Logback verwendet SLF4J, daher ist die Antwort relevant.
      2014-04-02 08: 18: 36Z
    4. @ AlexandrosGelbessis Sie sollten die Frage noch einmal lesen. Es wurde nach einer Methode gefragt, die programmgesteuert eine Protokollnachricht auf jeder Ebene protokollieren kann. Sie ändern die Ebene des Root-Loggers für alle Nachrichten, nicht nur für eine.
      2014-04-03 07: 16: 55Z
    5. + 1 für Jan, ich entschuldige mich.
      2014-04-15 09: 17: 55Z

    Sie können dies mit Java 8-Lambdas implementieren.

     
    import java.util.HashMap;
    import java.util.Map;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.slf4j.event.Level;
    
    public class LevelLogger {
        private static final Logger LOGGER = LoggerFactory.getLogger(LevelLogger.class);
        private static final Map<Level, LoggingFunction> map;
    
        static {
            map = new HashMap<>();
            map.put(Level.TRACE, (o) -> LOGGER.trace(o));
            map.put(Level.DEBUG, (o) -> LOGGER.debug(o));
            map.put(Level.INFO, (o) -> LOGGER.info(o));
            map.put(Level.WARN, (o) -> LOGGER.warn(o));
            map.put(Level.ERROR, (o) -> LOGGER.error(o));
        }
    
        public static void log(Level level, String s) {
            map.get(level).log(s);
        }
    
        @FunctionalInterface
        private interface LoggingFunction {
            public void log(String arg);
        }
    }
    
        
    11
    2016-03-10 17: 01: 06Z
    1. Nun ja ... aber jetzt müssen Sie Ihre Codebasis ändern, um diese API sowie oder anstelle von slf4j zu verwenden. Wenn Sie es anstelle von slf4j verwenden 1) muss es wahrscheinlich umfangreicher sein, 2) müssen viele (mindestens) Importe geändert werden, und 3) diese neue Ebene vor slf4j fügt einen zusätzlichen Protokollierungsaufwand hinzu.
      2018-10-07 23: 17: 03Z
    2. Beachten Sie auch, dass bei dieser Lösung die Klasse, die die eigentliche Protokollierung durchführt, nicht protokolliert wird (da der Logger mit LevelLogger initialisiert ist), was nicht der Fall ist Eine gute Sache, da es sich im Allgemeinen um sehr nützliche Informationen handelt.
      2018-10-19 11: 32: 07Z

    Dies kann mit einer enum und einer Hilfsmethode durchgeführt werden:

     
    enum LogLevel {
        TRACE,
        DEBUG,
        INFO,
        WARN,
        ERROR,
    }
    
    public static void log(Logger logger, LogLevel level, String format, Object[] argArray) {
        switch (level) {
            case TRACE:
                logger.trace(format, argArray);
                break;
            case DEBUG:
                logger.debug(format, argArray);
                break;
            case INFO:
                logger.info(format, argArray);
                break;
            case WARN:
                logger.warn(format, argArray);
                break;
            case ERROR:
                logger.error(format, argArray);
                break;
        }
    }
    
    // example usage:
    private static final Logger logger = ...
    final LogLevel level = ...
    log(logger, level, "Something bad happened", ...);
    

    Sie können weitere Varianten von log hinzufügen, beispielsweise, wenn Sie generische Entsprechungen von SLF4Js 1-Parameter- oder 2-Parameter-warn/error /etc. wünschen. Methoden.

        
    6
    2011-05-25 21: 46: 53Z
    1. Stimmt, aber slf4j soll keine Protokollwrapper schreiben.
      20.06.2014 00: 35: 17Z
    2. Der Zweck von SLF4J besteht darin, eine Abstraktion für verschiedene Protokollierungsframeworks bereitzustellen. Wenn diese Abstraktion nicht genau das bietet, was Sie benötigen, haben Sie keine andere Wahl, als eine Hilfsmethode zu schreiben. Die einzige andere Alternative besteht darin, eine Methode wie die in meiner Antwort auf das SLF4J-Projekt beschriebene beizusteuern.
      2014-06-20 08: 49: 21Z
    3. Ich stimme zu, aber in diesem Fall gibt es Vorbehalte, so dass Sie Datei- und Zeilennummer nicht mehr angeben können, es sei denn, Sie haben eine weitere Problemumgehung implementiert . In diesem Fall wäre ich bei log4j geblieben, bis das Framework die Funktion unterstützt hat - was schließlich durch eine Erweiterung geschehen ist, siehe die aktuellere Antwort von Robert Elliot.
      2014-06-20 18: 46: 02Z

    Wer eine voll SLF4J-kompatible Lösung für dieses Problem haben möchte, sollte Lidalia SLF4J Extensions - es ist auf Maven Central.

        
    5
    2014-03-28 13: 14: 48Z

    Ich habe so etwas nur gebraucht und bin gekommenp mit:

     
    @RequiredArgsConstructor //lombok annotation
    public enum LogLevel{
    
        TRACE(l -> l::trace),
        INFO (l -> l::info),
        WARN (l -> l::warn),
        ERROR(l -> l::error);
    
        private final Function<Logger, Consumer<String>> function;
    
        public void log(Logger logger, String message) {
            function.apply(logger).accept(message);
        }
    }
    

    Nutzung:

     
        LogLevel level = LogLevel.TRACE;
        level.log(logger, "message");
    

    Logger wird während des Aufrufs übergeben, daher sollten die Klasseninformationen in Ordnung sein und es funktioniert gut mit der @ Slf4j lombok-Annotation.

        
    2
    25.04.2019 10: 36: 30Z
    1. Vielen Dank für diesen großartigen Ansatz - ich habe eine ähnliche Antwort veröffentlicht, die auf Ihrer Idee basiert.
      21.05.2019, 09: 53: 33Z
    2. DEBUG fehlt als Konstante.
      2019-05-22 08: 10: 50Z
    3. Diese Lösung protokolliert immer LogLevel als Klasse und log als Methode, wodurch die Protokolle weniger aussagekräftig werden.
      2019-05-22 08: 12: 03Z

    Es ist nicht möglich, in sjf4j 1.x eine Standardprotokollierungsstufe anzugeben. Es besteht jedoch die Hoffnung, dass slf4j 2.0 das Problem behebt. In 2.0 könnte es so aussehen:

     
    // POTENTIAL 2.0 SOLUTION
    import org.slf4j.helpers.Util;
    import static org.slf4j.spi.LocationAwareLogger.*;
    
    // does not work with slf4j 1.x
    Util.log(logger, DEBUG_INT, "hello world!");
    

    In der Zwischenzeit können Sie für slf4j 1.x die folgende Problemumgehung verwenden:

    Kopieren Sie diese Klasse in Ihren Klassenpfad:

     
    import org.slf4j.Logger;
    import java.util.function.Function;
    
    public enum LogLevel {
    
        TRACE(l -> l::trace, Logger::isTraceEnabled),
        DEBUG(l -> l::debug, Logger::isDebugEnabled),
        INFO(l -> l::info, Logger::isInfoEnabled),
        WARN(l -> l::warn, Logger::isWarnEnabled),
        ERROR(l -> l::error, Logger::isErrorEnabled);
    
        interface LogMethod {
            void log(String format, Object... arguments);
        }
    
        private final Function<Logger, LogMethod> logMethod;
        private final Function<Logger, Boolean> isEnabledMethod;
    
        LogLevel(Function<Logger, LogMethod> logMethod, Function<Logger, Boolean> isEnabledMethod) {
            this.logMethod = logMethod;
            this.isEnabledMethod = isEnabledMethod;
        }
    
        public LogMethod prepare(Logger logger) {
            return logMethod.apply(logger);
        }
    
        public boolean isEnabled(Logger logger) {
            return isEnabledMethod.apply(logger);
        }
    }
    

    Dann können Sie es wie folgt verwenden:

     
    Logger logger = LoggerFactory.getLogger(Application.class);
    
    LogLevel level = LogLevel.ERROR;
    level.prepare(logger).log("It works!"); // just message, without parameter
    level.prepare(logger).log("Hello {}!", "world"); // with slf4j's parameter replacing
    
    try {
        throw new RuntimeException("Oops");
    } catch (Throwable t) {
        level.prepare(logger).log("Exception", t);
    }
    
    if (level.isEnabled(logger)) {
        level.prepare(logger).log("logging is enabled");
    }
    

    Dies gibt ein Protokoll wie das folgende aus:

     
    [main] ERROR Application - It works!
    [main] ERROR Application - Hello world!
    [main] ERROR Application - Exception
    java.lang.RuntimeException: Oops
        at Application.main(Application.java:14)
    [main] ERROR Application - logging is enabled
    

    Lohnt es sich?

    • Pro Der Quellcode wird beibehalten (Klassennamen, Methodennamen, Zeilennummern verweisen auf Ihren Code)
    • Pro Sie können ganz einfach Variablen , Parameter und Rückgabetypen als LogLevel definieren
    • Pro Ihr Geschäftscode bleibt kurz und einfach zu lesen und es sind keine zusätzlichen Abhängigkeiten erforderlich.

    Der Quellcode als minimales Beispiel wird auf GitHub gehostet >.

        
    1
    23.05.2019 10: 05: 16Z

    Ich bin gerade auf ein ähnliches Bedürfnis gestoßen. In meinem Fall ist slf4j mit dem Java-Protokollierungsadapter (dem jdk14-Adapter) konfiguriert. Mit dem folgenden Code-Snippet habe ich es geschafft, die Debug-Ebene zur Laufzeit zu ändern:

     
    Logger logger = LoggerFactory.getLogger("testing");
    java.util.logging.Logger julLogger = java.util.logging.Logger.getLogger("testing");
    julLogger.setLevel(java.util.logging.Level.FINE);
    logger.debug("hello world");
    
        
    0
    2014-06-11 03: 33: 07Z
    1. Wie bei anderen Antworten wird auch hier nicht die ursprüngliche Frage beantwortet, sondern ein anderes Problem.
      2016-10-28 13: 06: 38Z

    Basierend auf der Antwort von massimo virgilio habe ich es auch geschafft, mit slf4j-log4j Introspektion zu verwenden. HTH.

     
    Logger LOG = LoggerFactory.getLogger(MyOwnClass.class);
    
    org.apache.logging.slf4j.Log4jLogger LOGGER = (org.apache.logging.slf4j.Log4jLogger) LOG;
    
    try {
        Class loggerIntrospected = LOGGER.getClass();
        Field fields[] = loggerIntrospected.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            String fieldName = fields[i].getName();
            if (fieldName.equals("logger")) {
                fields[i].setAccessible(true);
                org.apache.logging.log4j.core.Logger loggerImpl = (org.apache.logging.log4j.core.Logger) fields[i].get(LOGGER);
                loggerImpl.setLevel(Level.DEBUG);
            }
        }
    } catch (Exception e) {
        System.out.println("ERROR :" + e.getMessage());
    }
    
        
    0
    2016-02-24 12: 39: 51Z

    Hier ist eine Lambda-Lösung, die in einer Hinsicht nicht so benutzerfreundlich ist wie die von @Paul Croarkin (das Level wird effektiv zweimal bestanden). Aber ich denke, (a) der Benutzer sollte den Logger übergeben; und (b) AFAIU in der ursprünglichen Frage wurde nicht überall in der Anwendung nach einem geeigneten Weg gefragt, sondern nur nach einer Situation mit wenigen Verwendungsmöglichkeiten in einer Bibliothek.

     
    package test.lambda;
    import java.util.function.*;
    import org.slf4j.*;
    
    public class LoggerLambda {
        private static final Logger LOG = LoggerFactory.getLogger(LoggerLambda.class);
    
        private LoggerLambda() {}
    
        public static void log(BiConsumer<? super String, ? super Object[]> logFunc, Supplier<Boolean> logEnabledPredicate, 
                String format, Object... args) {
            if (logEnabledPredicate.get()) {
                logFunc.accept(format, args);
            }
        }
    
        public static void main(String[] args) {
            int a = 1, b = 2, c = 3;
            Throwable e = new Exception("something went wrong", new IllegalArgumentException());
            log(LOG::info, LOG::isInfoEnabled, "a = {}, b = {}, c = {}", a, b, c);
    
            // warn(String, Object...) instead of warn(String, Throwable), but prints stacktrace nevertheless
            log(LOG::warn, LOG::isWarnEnabled, "error doing something: {}", e, e);
        }
    }
    

    Da slf4j ein Throwable (dessen Stack-Trace protokolliert werden soll) im varargs-Parameter zulässt Ich glaube, es ist nicht erforderlich, die log-Hilfsmethode für andere Verbraucher als (String, Object[]) zu überladen.

        
    0
    2016-07-29 09: 30: 45Z

    Ich konnte dies für die JDK14-Bindung tun, indem ich zuerst die SLF4J-Logger-Instanz anforderte und dann die Stufe für die Bindung festlegte.

    Sie können dies für die Log4J-Bindung versuchen  
    private void setLevel(Class loggerClass, java.util.logging.Level level) {
      org.slf4j.LoggerFactory.getLogger(loggerClass);
      java.util.logging.Logger.getLogger(loggerClass.getName()).setLevel(level);
    }
    
        
    0
    2017-06-21 00: 50: 05Z

    Die von mir verwendete Methode besteht darin, die ch.qos.logback-Module zu importieren und dann die slf4j-Logger-Instanz in eine ch.qos.logback.classic.Logger-Instanz umzuwandeln. Diese Instanz enthält eine setLevel () -Methode.

     
    import ch.qos.logback.classic.Level;
    import ch.qos.logback.classic.Logger;
    
    Logger levelSet = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
    
    // Now you can set the desired logging-level
    levelSet.setLevel( Level.OFF );
    

    Um die möglichen Protokollierungsstufen herauszufinden, können Sie die Klasse ch.qos.logback auflösen, um alle möglichen Werte für Stufe anzuzeigen:

     
    prompt$ javap -cp logback-classic-1.2.3.jar ch.qos.logback.classic.Level
    

    Die Ergebnisse lauten wie folgt:

     
    {
       // ...skipping
       public static final ch.qos.logback.classic.Level OFF;
       public static final ch.qos.logback.classic.Level ERROR;
       public static final ch.qos.logback.classic.Level WARN;
       public static final ch.qos.logback.classic.Level INFO;
       public static final ch.qos.logback.classic.Level DEBUG;
       public static final ch.qos.logback.classic.Level TRACE;
       public static final ch.qos.logback.classic.Level ALL;
    }
    
        
    0
    2016-02-16 00: 46: 51Z

    Mit Java Introspection können Sie dies tun, zum Beispiel:

     
    private void changeRootLoggerLevel(int level) {
    
        if (logger instanceof org.slf4j.impl.Log4jLoggerAdapter) {
            try {
                Class loggerIntrospected = logger.getClass();
                Field fields[] = loggerIntrospected.getDeclaredFields();
                for (int i = 0; i < fields.length; i++) {
                    String fieldName = fields[i].getName();
                    if (fieldName.equals("logger")) {
                        fields[i].setAccessible(true);
                        org.apache.log4j.Logger loggerImpl = (org.apache.log4j.Logger) fields[i]
                                .get(logger);
    
                        if (level == DIAGNOSTIC_LEVEL) {
                            loggerImpl.setLevel(Level.DEBUG);
                        } else {
                            loggerImpl.setLevel(org.apache.log4j.Logger.getRootLogger().getLevel());
                        }
    
                        // fields[i].setAccessible(false);
                    }
                }
            } catch (Exception e) {
                org.apache.log4j.Logger.getLogger(LoggerSLF4JImpl.class).error("An error was thrown while changing the Logger level", e);
            }
        }
    
    }
    
        
    - 2
    2012-04-27 15: 45: 10Z
    1. Dies bezieht sich explizit auf log4j und nicht generisch auf slf4j
      2012-07-13 01: 53: 23Z

    nein, es gibt eine Reihe von Methoden, info (), debug (), warn () usw. (dies ersetzt das Prioritätsfeld)

    werfen Sie einen Blick auf http://www.slf4j.org/api /org/slf4j/Logger.html für die vollständige Logger-API.

        
    - 6
    2010-04-12 11: 42: 45Z
    1. Entschuldigung, ich sehe, was Sie jetzt fragen. Nein, es gibt keine generische Möglichkeit, die Protokollstufe zur Laufzeit zu ändern. Sie können jedoch problemlos eine Hilfsmethode mit einer switch-Anweisung implementieren.
      2010-04-12 11: 47: 33Z
    2. Ja, aber das müssen Sie einmal für jede überladene Version der "log" -Methode tun.
      2014-12-04 04: 23: 41Z
Quelle platziert Hier