in log4j-api/src/main/java/org/apache/logging/log4j/util/ProviderUtil.java [180:263]
static Provider selectProvider(
final PropertiesUtil properties, final Collection<Provider> providers, final Logger statusLogger) {
Provider selected = null;
// 1. Select provider using "log4j.provider" property
final String providerClass = properties.getStringProperty(PROVIDER_PROPERTY_NAME);
if (providerClass != null) {
if (SimpleProvider.class.getName().equals(providerClass)) {
selected = new SimpleProvider();
} else {
try {
selected = LoaderUtil.newInstanceOf(providerClass);
} catch (final Exception e) {
statusLogger.error(
"Unable to create provider {}.\nFalling back to default selection process.", PROVIDER, e);
}
}
}
// 2. Use deprecated "log4j2.loggerContextFactory" property to choose the provider
final String factoryClassName = properties.getStringProperty(LogManager.FACTORY_PROPERTY_NAME);
if (factoryClassName != null) {
if (selected != null) {
statusLogger.warn(
"Ignoring {} system property, since {} was set.",
LogManager.FACTORY_PROPERTY_NAME,
PROVIDER_PROPERTY_NAME);
// 2a. Scan the known providers for one matching the logger context factory class name.
} else {
statusLogger.warn(
"Usage of the {} property is deprecated. Use the {} property instead.",
LogManager.FACTORY_PROPERTY_NAME,
PROVIDER_PROPERTY_NAME);
for (final Provider provider : providers) {
if (factoryClassName.equals(provider.getClassName())) {
selected = provider;
break;
}
}
}
// 2b. Instantiate
if (selected == null) {
statusLogger.warn(
"No provider found using {} as logger context factory. The factory will be instantiated directly.",
factoryClassName);
try {
final Class<?> clazz = LoaderUtil.loadClass(factoryClassName);
if (LoggerContextFactory.class.isAssignableFrom(clazz)) {
selected = new Provider(null, Strings.EMPTY, clazz.asSubclass(LoggerContextFactory.class));
} else {
statusLogger.error(
"Class {} specified in the {} system property does not extend {}",
factoryClassName,
LogManager.FACTORY_PROPERTY_NAME,
LoggerContextFactory.class.getName());
}
} catch (final Exception e) {
statusLogger.error(
"Unable to create class {} specified in the {} system property",
factoryClassName,
LogManager.FACTORY_PROPERTY_NAME,
e);
}
}
}
// 3. Select a provider automatically.
if (selected == null) {
final Comparator<Provider> comparator = Comparator.comparing(Provider::getPriority);
switch (providers.size()) {
case 0:
statusLogger.error("Log4j API could not find a logging provider.");
break;
case 1:
break;
default:
statusLogger.warn(providers.stream()
.sorted(comparator)
.map(Provider::toString)
.collect(Collectors.joining("\n", "Log4j API found multiple logging providers:\n", "")));
break;
}
selected = providers.stream().max(comparator).orElseGet(SimpleProvider::new);
}
statusLogger.info("Using provider:\n{}", selected);
return selected;
}