Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public abstract class AbstractConfiguration extends AbstractFilterable implement
private LoggerConfig root = new LoggerConfig();
private final ConcurrentMap<String, Object> componentMap = new ConcurrentHashMap<>();
private final ConfigurationSource configurationSource;
private ScriptManager scriptManager;
protected ScriptManager scriptManager;
private final ConfigurationScheduler configurationScheduler = new ConfigurationScheduler();
private final WatchManager watchManager = new WatchManager(configurationScheduler);
private AsyncLoggerConfigDisruptor asyncLoggerConfigDisruptor;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package org.apache.logging.log4j.core.config;

import org.apache.logging.log4j.core.Filter;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;

public class CompositeConfiguration
extends AbstractConfiguration
{

private List<? extends AbstractConfiguration> configurations;

private static final List<String> names = new ArrayList<>();

private static final String APPENDERS = "appenders";

private static final String PROPERTIES = "properties";

private static final String LOGGERS = "loggers";


static
{
names.add( APPENDERS );
names.add( PROPERTIES );
names.add( LOGGERS );
}

/**
* Constructor.
*/
public CompositeConfiguration( List<? extends AbstractConfiguration> configurations )
{
super( ConfigurationSource.NULL_SOURCE );
this.configurations = configurations;
}

@Override
protected void setup()
{
AbstractConfiguration primaryConfiguration = configurations.get( 0 );
staffChildConfiguration( primaryConfiguration );
rootNode = primaryConfiguration.rootNode;
for ( AbstractConfiguration amendingConfiguration : configurations.subList( 1, configurations.size() ) )
{
staffChildConfiguration( amendingConfiguration );
Node currentRoot = amendingConfiguration.rootNode;
for ( Node childNode : currentRoot.getChildren() )
{
mergeNodes( rootNode, childNode );
}
}
}

private void staffChildConfiguration( AbstractConfiguration childConfiguration )
{
childConfiguration.pluginManager = pluginManager;
childConfiguration.scriptManager = scriptManager;
childConfiguration.setup();
}

private void mergeNodes( Node rootNode, Node childNode )
{
// first find the right rootNode child we will merge with
boolean isFilter = Filter.class.isAssignableFrom(childNode.getType().getPluginClass());
for ( Node rootChildNode : rootNode.getChildren() )
{
if (isFilter && Filter.class.isAssignableFrom(rootChildNode.getType().getPluginClass())) {
//for filters we have a simple replace, as only one filter can exist
rootNode.getChildren().remove(rootChildNode);
rootNode.getChildren().add(childNode);
return;
}
if ( rootChildNode.getType() != childNode.getType()
|| !names.contains( rootChildNode.getName().toLowerCase() ) )
{
continue;
}

List<Node> grandChilds = rootChildNode.getChildren();

switch ( rootChildNode.getName().toLowerCase() )
{
case LOGGERS: /** fallthrough */
case PROPERTIES:
grandChilds.addAll( childNode.getChildren() );
break;
case APPENDERS:
for ( Node appender : childNode.getChildren() )
{
Iterator<Node> it = grandChilds.iterator();
while ( it.hasNext() )
{
Node currentAppender = it.next();
// check if there's already an appender with the very same name. If so remove it
if ( Objects.equals( currentAppender.getAttributes().get( "name" ),
appender.getAttributes().get( "name" ) ) )
{
it.remove();
break;
}
}
// add appender (might actually be replace with one with the same name was previously found
grandChilds.add( appender );
}
break;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package org.apache.logging.log4j.core.config;

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

import org.apache.logging.log4j.Level;
Expand Down Expand Up @@ -109,8 +111,30 @@ public static LoggerContext initialize(final String name, final ClassLoader load
*/
public static LoggerContext initialize(final String name, final ClassLoader loader, final String configLocation,
final Object externalContext) {
final URI uri = Strings.isBlank(configLocation) ? null : NetUtils.toURI(configLocation);
return initialize(name, loader, uri, externalContext);
if ( Strings.isBlank( configLocation ) )
{
return initialize( name, loader, (URI) null, externalContext );
}
if ( configLocation.contains( ";" ) )
{
String[] parts = configLocation.split( ";" );
String scheme = null;
List<URI> uris = new ArrayList<>( parts.length );
for ( String part : parts )
{
URI uri = NetUtils.toURI( scheme != null ? scheme + ":" + part : part );
if ( scheme == null && uri.getScheme() != null )
{
scheme = uri.getScheme();
}
uris.add( uri );
}
return initialize( name, loader, uris, externalContext );
}
else
{
return initialize( name, loader, NetUtils.toURI( configLocation ), externalContext );
}
}

/**
Expand Down Expand Up @@ -146,6 +170,23 @@ public static LoggerContext initialize(final String name, final ClassLoader load
return null;
}

public static LoggerContext initialize( final String name, final ClassLoader loader,
final List<URI> configLocations, final Object externalContext )
{
try
{
final Log4jContextFactory factory = getFactory();
return factory == null ? null
: factory.getContext( FQCN, loader, externalContext, false, configLocations, name );
}
catch ( final Exception ex )
{
LOGGER.error( "There was a problem initializing the LoggerContext [{}] using configurations at [{}].", name,
configLocations, ex );
}
return null;
}

/**
* Initializes the Logging Context.
* @param name The Context name.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,17 @@
package org.apache.logging.log4j.core.impl;

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

import org.apache.logging.log4j.core.LifeCycle;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.AbstractConfiguration;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.ConfigurationFactory;
import org.apache.logging.log4j.core.config.ConfigurationSource;
import org.apache.logging.log4j.core.config.CompositeConfiguration;
import org.apache.logging.log4j.core.selector.ClassLoaderContextSelector;
import org.apache.logging.log4j.core.selector.ContextSelector;
import org.apache.logging.log4j.core.util.Cancellable;
Expand Down Expand Up @@ -241,6 +245,54 @@ public LoggerContext getContext(final String fqcn, final ClassLoader loader, fin
return ctx;
}

public LoggerContext getContext( final String fqcn, final ClassLoader loader, final Object externalContext,
final boolean currentContext, final List<URI> configLocations, final String name )
{
final LoggerContext ctx =
selector.getContext( fqcn, loader, currentContext, null/*this probably needs to change*/ );
if ( externalContext != null && ctx.getExternalContext() == null )
{
ctx.setExternalContext( externalContext );
}
if ( name != null )
{
ctx.setName( name );
}
if ( ctx.getState() == LifeCycle.State.INITIALIZED )
{
if ( ( configLocations != null && !configLocations.isEmpty() ) )
{
ContextAnchor.THREAD_CONTEXT.set( ctx );
List<AbstractConfiguration> configurations = new ArrayList<>( configLocations.size() );
for ( URI configLocation : configLocations )
{
Configuration currentReadConfiguration =
ConfigurationFactory.getInstance().getConfiguration( name, configLocation );
if ( currentReadConfiguration instanceof AbstractConfiguration )
{
configurations.add( (AbstractConfiguration) currentReadConfiguration );
}
else
{
LOGGER.error(
"Found configuration {}, which is no AbstractConfiguration and can't be handled by CompositeConfiguration",
configLocation );
}
}
CompositeConfiguration compositeConfiguration = new CompositeConfiguration( configurations );
LOGGER.debug( "Starting LoggerContext[name={}] from configurations at {}", ctx.getName(),
configLocations );
ctx.start( compositeConfiguration );
ContextAnchor.THREAD_CONTEXT.remove();
}
else
{
ctx.start();
}
}
return ctx;
}

/**
* Returns the ContextSelector.
* @return The ContextSelector.
Expand Down
Loading