All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.micronaut.logging.impl.LogbackUtils Maven / Gradle / Ivy

There is a newer version: 4.7.9
Show newest version
/*
 * Copyright 2017-2023 original authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.micronaut.logging.impl;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.Configurator;
import ch.qos.logback.classic.util.ContextInitializer;
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.status.InfoStatus;
import io.micronaut.core.annotation.NonNull;
import io.micronaut.core.annotation.Nullable;
import io.micronaut.logging.LoggingSystemException;

import java.net.URL;
import java.util.Iterator;
import java.util.ServiceLoader;
import java.util.function.Supplier;

/**
 * Utility methods to configure {@link LoggerContext}.
 *
 * @author Sergio del Amo
 * @since 3.8.4
 */
public final class LogbackUtils {

    private LogbackUtils() {
    }

    /**
     * Configures a Logger Context.
     *
     * @param classLoader        Class Loader
     * @param context            Logger Context
     * @param logbackXmlLocation the location of the xml logback config file
     */
    public static void configure(@NonNull ClassLoader classLoader,
                                 @NonNull LoggerContext context,
                                 @NonNull String logbackXmlLocation) {
        configure(context, logbackXmlLocation, () -> classLoader.getResource(logbackXmlLocation));
    }

    /**
     * Configures a Logger Context.
     *
     * Searches fpr a custom {@link Configurator} via a service loader.
     * If not present it configures the context with the resource.
     *
     * @param context  Logger Context
     * @param logbackXmlLocation the location of the xml logback config file
     * @param resourceSupplier A resource for example logback.xml
     */
    private static void configure(
        @NonNull LoggerContext context,
        @NonNull String logbackXmlLocation,
        Supplier resourceSupplier
    ) {
        Configurator configurator = loadFromServiceLoader();
        if (configurator != null) {
            context.getStatusManager().add(new InfoStatus("Using " + configurator.getClass().getName(), context));
            programmaticConfiguration(context, configurator);
        } else {
            URL resource = resourceSupplier.get();
            if (resource != null) {
                try {
                    new ContextInitializer(context).configureByResource(resource);
                } catch (JoranException e) {
                    throw new LoggingSystemException("Error while refreshing Logback", e);
                }
            } else {
                throw new LoggingSystemException("Resource " + logbackXmlLocation + " not found");
            }
        }
    }

    /**
     * Taken from {@link ch.qos.logback.classic.util.ContextInitializer#autoConfig}.
     */
    private static void programmaticConfiguration(@NonNull LoggerContext context,
                                                  @NonNull Configurator configurator) {
        try {
            configurator.setContext(context);
            configurator.configure(context);
        } catch (Exception e) {
            throw new LoggingSystemException(String.format("Failed to initialize Configurator: %s using ServiceLoader", configurator.getClass().getCanonicalName()), e);
        }
    }

    /**
     * Find a Logback Configurator service.
     * We can't use {@link ch.qos.logback.classic.util.EnvUtil#loadFromServiceLoader} because the class moved in v1.3.0
     */
    @Nullable
    private static Configurator loadFromServiceLoader() {
        Iterator it = ServiceLoader.load(Configurator.class).iterator();
        return it.hasNext() ? it.next() : null;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy