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

org.atteo.moonshine.logging.Logback Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2013 Atteo.
 *
 * 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
 *
 *      http://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 org.atteo.moonshine.logging;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;
import java.util.logging.Handler;
import java.util.logging.LogManager;

import org.atteo.moonshine.directories.FileAccessor;
import org.slf4j.LoggerFactory;
import org.slf4j.bridge.SLF4JBridgeHandler;
import org.slf4j.impl.StaticLoggerBinder;

import ch.qos.logback.classic.ClassicConstants;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.classic.jul.LevelChangePropagator;
import ch.qos.logback.classic.selector.ContextSelector;
import ch.qos.logback.classic.util.ContextInitializer;
import ch.qos.logback.core.joran.spi.JoranException;

/**
 * Logging implementation using Logback.
 *
 * 

* Logging steps: * 1. At first logging is configured using Logback internal mechanism. It finds logback.xml on classpath * and reads configuration from there. We don't have yet any place for storage, so we log provide logback.xml * which will log WARNings and Moonshine startup messages to the console. * 2. During early bootstrap we disable default JUL logger which prints everything to the console * and we start SLF4J bridge which forwards all JUL logs to SLF4J * 3. Finally we load logback-moonshine.xml file which configures full logging. *

*/ public class Logback implements Logging { private final LoggingCommandLineParameters parameters = new LoggingCommandLineParameters(); public static class MoonshineContextSelector implements ContextSelector { private static final InheritableThreadLocal context = new InheritableThreadLocal<>(); public MoonshineContextSelector(LoggerContext c) { context.set(c); } /** * Starts new Logback context for this thread and all threads created from this thread. */ public static void initNewContext() { LoggerContext c= new LoggerContext(); c.setName(Thread.currentThread().getName()); // load logback.xml for a moment try { new ContextInitializer(c).autoConfig(); } catch (JoranException e) { throw new RuntimeException(e); } context.set(c); } @Override public LoggerContext getLoggerContext() { return context.get(); } @Override public LoggerContext getLoggerContext(String name) { LoggerContext c = context.get(); if (c.getName().equals(name)) { return c; } else { return null; } } @Override public LoggerContext getDefaultLoggerContext() { return context.get(); } @Override public LoggerContext detachLoggerContext(String loggerContextName) { return context.get(); } @Override public List getContextNames() { return Arrays.asList(context.get().getName()); } } static synchronized protected void newLogbackContextForThisThread() { if (!MoonshineContextSelector.class.getName().equals( System.getProperty(ClassicConstants.LOGBACK_CONTEXT_SELECTOR))) { System.setProperty(ClassicConstants.LOGBACK_CONTEXT_SELECTOR, MoonshineContextSelector.class.getName()); try { Method method = StaticLoggerBinder.class.getDeclaredMethod("reset"); method.setAccessible(true); method.invoke(null); } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { LoggerFactory.getLogger("Moonshine").warn( "Unrecognized Logback version, cannot install context selector", e); } } MoonshineContextSelector.initNewContext(); LoggerFactory.getILoggerFactory(); } /** * Disable JUL logging and redirect all logs though SLF4J. * * @see resources = this.getClass().getClassLoader().getResources("logback-moonshine.xml"); for (; resources.hasMoreElements();) { URL resource = resources.nextElement(); try (InputStream inputStream = resource.openStream()) { configurator.doConfigure(inputStream); } } for (Path path : fileAccessor.getConfigFiles("logback-moonshine.xml")) { try (InputStream inputStream = Files.newInputStream(path, StandardOpenOption.READ)) { configurator.doConfigure(inputStream); } } } catch (JoranException|IOException e) { throw new RuntimeException(e); } } @Override public void earlyBootstrap() { newLogbackContextForThisThread(); redirectLogsToSLF4J(); propagateLogbackLevelsToJul(); } @Override public Object getParameters() { return parameters; } @Override public void initialize(FileAccessor fileAccessor, Properties properties) { loadFinalLoggingConfiguration(fileAccessor, properties); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy