001/*
002 * Logback: the reliable, generic, fast and flexible logging framework.
003 * Copyright (C) 1999-2026, QOS.ch. All rights reserved.
004 *
005 * This program and the accompanying materials are dual-licensed under
006 * either the terms of the Eclipse Public License v2.0 as published by
007 * the Eclipse Foundation
008 *
009 *   or (per the licensee's choosing)
010 *
011 * under the terms of the GNU Lesser General Public License version 2.1
012 * as published by the Free Software Foundation.
013 */
014
015package ch.qos.logback.classic.spi;
016
017import org.slf4j.ILoggerFactory;
018import org.slf4j.IMarkerFactory;
019import org.slf4j.helpers.BasicMarkerFactory;
020import org.slf4j.helpers.Util;
021import org.slf4j.spi.MDCAdapter;
022import org.slf4j.spi.SLF4JServiceProvider;
023
024import ch.qos.logback.classic.LoggerContext;
025import ch.qos.logback.classic.util.ContextInitializer;
026import ch.qos.logback.classic.util.LogbackMDCAdapter;
027import ch.qos.logback.core.CoreConstants;
028import ch.qos.logback.core.joran.spi.JoranException;
029import ch.qos.logback.core.status.StatusUtil;
030import ch.qos.logback.core.util.StatusPrinter;
031
032public class LogbackServiceProvider implements SLF4JServiceProvider {
033
034    final static String NULL_CS_URL = CoreConstants.CODES_URL + "#null_CS";
035
036    /**
037     * Declare the version of the SLF4J API this implementation is compiled against.
038     * The value of this field is modified with each major release.
039     */
040    // to avoid constant folding by the compiler, this field must *not* be final
041    public static String REQUESTED_API_VERSION = "2.0.99"; // !final
042
043    private LoggerContext defaultLoggerContext = new LoggerContext();
044
045
046    // org.slf4j.LoggerFactory expects providers to initialize markerFactory as early as possible.
047    private IMarkerFactory markerFactory = new BasicMarkerFactory();
048
049    // org.slf4j.LoggerFactory expects providers to initialize their MDCAdapter field
050    // as early as possible, preferably at construction time.
051    private LogbackMDCAdapter mdcAdapter = new LogbackMDCAdapter();
052
053    @Override
054    public void initialize() {
055        defaultLoggerContext.setName(CoreConstants.DEFAULT_CONTEXT_NAME);
056        // set the MDCAdapter for the defaultLoggerContext immediately
057        defaultLoggerContext.setMDCAdapter(mdcAdapter);
058        initializeLoggerContext();
059        defaultLoggerContext.start();
060    }
061
062    private void initializeLoggerContext() {
063        try {
064            try {
065                new ContextInitializer(defaultLoggerContext).autoConfig();
066            } catch (JoranException je) {
067                Util.report("Failed to auto configure default logger context", je);
068            }
069            // LOGBACK-292
070            if (!StatusUtil.contextHasStatusListener(defaultLoggerContext)) {
071                StatusPrinter.printInCaseOfErrorsOrWarnings(defaultLoggerContext);
072            }
073            // contextSelectorBinder.init(defaultLoggerContext, KEY);
074
075        } catch (Exception t) { // see LOGBACK-1159
076            Util.report("Failed to instantiate [" + LoggerContext.class.getName() + "]", t);
077        }
078    }
079
080    @Override
081
082    public ILoggerFactory getLoggerFactory() {
083        return defaultLoggerContext;
084    }
085
086    @Override
087    public IMarkerFactory getMarkerFactory() {
088        return markerFactory;
089    }
090
091    @Override
092    public MDCAdapter getMDCAdapter() {
093        return mdcAdapter;
094    }
095
096    @Override
097    public String getRequestedApiVersion() {
098        return REQUESTED_API_VERSION;
099    }
100
101}