org.mule.module.launcher.log4j2.MuleLoggerContext Maven / Gradle / Ivy
/*
* 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.module.launcher.application.ApplicationClassLoader;
import org.mule.module.launcher.artifact.ArtifactClassLoader;
import java.net.URI;
import org.apache.logging.log4j.core.Logger;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.selector.ContextSelector;
import org.apache.logging.log4j.message.MessageFactory;
/**
* Subclass of {@link org.apache.logging.log4j.core.LoggerContext}
* which adds some information about the mule artifact being logged.
*
* The most important function of this class though is to override the
* {@link #reconfigure()} method to to its inherited purpose plus
* invoking {@link org.mule.module.launcher.log4j2.LoggerContextConfigurer#configure(MuleLoggerContext)}.
*
* The {@link org.mule.module.launcher.log4j2.LoggerContextConfigurer} needs to be invoked here so
* that it's invoked each time the configuration is reloaded.
*
* This class must not hold any reference to a {@link java.lang.ClassLoader} since otherwise
* {@link org.apache.logging.log4j.core.Logger} instances held on static fields will make
* that class loader GC unreachable
*
* @since 3.6.0
*/
class MuleLoggerContext extends LoggerContext
{
protected static final int NO_CCL_CLASSLOADER = 0;
private final URI configFile;
private final boolean standlone;
private final ContextSelector contextSelector;
private final boolean artifactClassloader;
private final boolean applicationClassloader;
private final String artifactName;
private final int ownerClassLoaderHash;
MuleLoggerContext(String name, ContextSelector contextSelector, boolean standalone)
{
this(name, null, null, contextSelector, standalone);
}
MuleLoggerContext(String name, URI configLocn, ClassLoader ownerClassLoader, ContextSelector contextSelector, boolean standalone)
{
super(name, null, configLocn);
configFile = configLocn;
this.contextSelector = contextSelector;
this.standlone = standalone;
ownerClassLoaderHash = ownerClassLoader != null ? ownerClassLoader.hashCode() : NO_CCL_CLASSLOADER;
if (ownerClassLoader instanceof ArtifactClassLoader)
{
artifactClassloader = true;
artifactName = ((ArtifactClassLoader) ownerClassLoader).getArtifactName();
applicationClassloader = ownerClassLoader instanceof ApplicationClassLoader;
}
else
{
artifactClassloader = false;
applicationClassloader = false;
artifactName = null;
}
}
@Override
public synchronized void reconfigure()
{
super.reconfigure();
new LoggerContextConfigurer().configure(this);
}
/**
* Override to return a {@link DispatchingLogger}
* instead of a simple logger
* {@inheritDoc}
*
* @return a {@link DispatchingLogger}
*/
@Override
protected Logger newInstance(LoggerContext ctx, final String name, final MessageFactory messageFactory)
{
return new DispatchingLogger(super.newInstance(ctx, name, messageFactory), ownerClassLoaderHash, this, contextSelector, messageFactory)
{
// force the name due to log4j2's cyclic constructor dependencies
// aren't a friend of the wrapper pattern
@Override
public String getName()
{
return name;
}
};
}
protected URI getConfigFile()
{
return configFile;
}
protected boolean isStandlone()
{
return standlone;
}
protected boolean isArtifactClassloader()
{
return artifactClassloader;
}
protected boolean isApplicationClassloader()
{
return applicationClassloader;
}
protected String getArtifactName()
{
return artifactName;
}
}