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

org.mule.module.launcher.log4j2.ArtifactAwareContextSelector Maven / Gradle / Ivy

There is a newer version: 3.9.0
Show newest version
/*
 * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 * The software in this package is published under the terms of the CPAL v1.0
 * license, a copy of which has been included with this distribution in the
 * LICENSE.txt file.
 */
package org.mule.module.launcher.log4j2;

import org.mule.api.lifecycle.Disposable;
import org.mule.module.launcher.artifact.ArtifactClassLoader;

import java.net.URI;
import java.util.List;

import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.selector.ContextSelector;
import org.apache.logging.log4j.status.StatusLogger;

/**
 * Implementation of {@link org.apache.logging.log4j.core.selector.ContextSelector}
 * which is used to implement log separation based on provided or current
 * {@link java.lang.ClassLoader}
 * 

* This component is responsible for managing the {@link org.apache.logging.log4j.core.LoggerContext} * that corresponds to each artifact (aka applications, domains, container), using its classloader as * an identifier. The same classloader always gets the same {@link org.apache.logging.log4j.core.LoggerContext} *

* This component also overrides log4j2's default algorithm for locating configuration files, although it * does it in a way consistent with the replaced behavior: *

    *
  • A file called log4j2-test.xml is fetched from the corresponding search path
  • *
  • If log4j2-test.xml is not found, then log4j2.xml is attempted
  • *
  • If not found, a default configuration consisting of a single rolling file appender is used
  • *
  • The search path is derived from the artifact for which a logging context is being requested, following * a child first strategy (artifact - domain - container). Each artifact starts looking in the phase that makes * sense for it
  • *
*

* If the classloader is an artifact one, then it adds a {@link org.mule.module.launcher.artifact.ShutdownListener} * to destroy the logging context when the app is undeployed, preventing memory leaks. *

* If mule is running in embedded mode, then all of this logic described above is discarded and it simply logs * to a file called mule-main.log * * @since 3.6.0 */ class ArtifactAwareContextSelector implements ContextSelector, Disposable { static final StatusLogger logger = StatusLogger.getLogger(); private LoggerContextCache cache = new LoggerContextCache(this, getClass().getClassLoader()); private final MuleLoggerContextFactory loggerContextFactory = new MuleLoggerContextFactory(); ArtifactAwareContextSelector() { } @Override public LoggerContext getContext(String fqcn, ClassLoader loader, boolean currentContext) { return getContext(fqcn, loader, currentContext, null); } @Override public LoggerContext getContext(String fqcn, ClassLoader classLoader, boolean currentContext, URI configLocation) { return cache.getLoggerContext(resolveLoggerContextClassLoader(classLoader)); } @Override public List getLoggerContexts() { return cache.getAllLoggerContexts(); } @Override public void removeContext(LoggerContext context) { cache.remove(context); } /** * Given a {@code classLoader} this method will resolve which is the {@code classLoader} * associated with the logger context to use for this {@code classLoader} . *

* When the provided {@code classLoader} is from an application or a domain it will return * the {@code classLoader} associated with the logger context of the application or domain. * So far the artifact (domain or app) {@code classLoader} will be resolved to it self. *

* If the {@code classLoader} belongs to the container or any other {@code classLoader} created from a * library running outside the context of an artifact then the system {@code classLoader} will be used. * * @param classLoader {@link ClassLoader} running the code where the logging was done * @return the {@link ClassLoader} owner of the logger context */ static ClassLoader resolveLoggerContextClassLoader(ClassLoader classLoader) { ClassLoader loggerClassLoader = classLoader == null ? Thread.currentThread().getContextClassLoader() : classLoader; if (!(loggerClassLoader instanceof ArtifactClassLoader)) { loggerClassLoader = loggerClassLoader.getSystemClassLoader(); } return loggerClassLoader; } @Override public void dispose() { cache.dispose(); } public void destroyLoggersFor(ClassLoader classLoader) { cache.remove(classLoader); } LoggerContext buildContext(final ClassLoader classLoader) { return loggerContextFactory.build(classLoader, this); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy