log4j 2.x --LogManager
阿新 • • 發佈:2018-12-23
LogManager啟動主要類
LogManager
LoggerContextFactory
LogManager啟動入口是以下static程式碼
static { //繫結一個LoggerContextFactory,獲取配置檔案 //private static final PropertiesUtil LOG4J_PROPERTIES = new PropertiesUtil("log4j2.component.properties"); //中的屬性【log4j2.loggerContextFactory】 final PropertiesUtil managerProps = PropertiesUtil.getProperties(); final String factoryClassName = managerProps.getStringProperty(FACTORY_PROPERTY_NAME); if (factoryClassName != null) { try { // factory = LoaderUtil.newCheckedInstanceOf(factoryClassName, LoggerContextFactory.class); } catch (final ClassNotFoundException cnfe) { LOGGER.error("Unable to locate configured LoggerContextFactory {}", factoryClassName); } catch (final Exception ex) { LOGGER.error("Unable to create configured LoggerContextFactory {}", factoryClassName, ex); } } if (factory == null) { final SortedMap<Integer, LoggerContextFactory> factories = new TreeMap<>(); // note that the following initial call to ProviderUtil may block until a Provider has been installed when // running in an OSGi environment /* 通過provider例項化LoggerContextFactory物件 log4j2是通過META-INF中的log4j-provider.properties檔案獲取具體的LoggerContextFactory file:/user/home/.m2/repository/org/apache/logging/log4j/log4j-core/2.8.2/log4j-core-2.8.2.jar!/META-INF/log4j-provider.properties LoggerContextFactory = org.apache.logging.log4j.core.impl.Log4jContextFactory Log4jAPIVersion = 2.6.0 FactoryPriority= 10 因此預設的 LoggerContextFactory是Log4jContextFactory */ if (ProviderUtil.hasProviders()) { for (final Provider provider : ProviderUtil.getProviders()) { final Class<? extends LoggerContextFactory> factoryClass = provider.loadLoggerContextFactory(); if (factoryClass != null) { try { factories.put(provider.getPriority(), factoryClass.newInstance()); } catch (final Exception e) { LOGGER.error("Unable to create class {} specified in {}", factoryClass.getName(), provider .getUrl().toString(), e); } } } if (factories.isEmpty()) { LOGGER.error("Log4j2 could not find a logging implementation. " + "Please add log4j-core to the classpath. Using SimpleLogger to log to the console..."); factory = new SimpleLoggerContextFactory(); } else if (factories.size() == 1) { factory = factories.get(factories.lastKey()); } else { final StringBuilder sb = new StringBuilder("Multiple logging implementations found: \n"); for (final Map.Entry<Integer, LoggerContextFactory> entry : factories.entrySet()) { sb.append("Factory: ").append(entry.getValue().getClass().getName()); sb.append(", Weighting: ").append(entry.getKey()).append('\n'); } factory = factories.get(factories.lastKey()); sb.append("Using factory: ").append(factory.getClass().getName()); LOGGER.warn(sb.toString()); } } else { LOGGER.error("Log4j2 could not find a logging implementation. " + "Please add log4j-core to the classpath. Using SimpleLogger to log to the console..."); factory = new SimpleLoggerContextFactory(); } } }
配置檔案解析
public static ConfigurationFactory getInstance() { // volatile works in Java 1.6+, so double-checked locking also works properly //noinspection DoubleCheckedLocking if (factories == null) { LOCK.lock(); try { if (factories == null) { final List<ConfigurationFactory> list = new ArrayList<>(); //CONFIGURATION_FACTORY_PROPERTY = "log4j.configurationFactory"; final String factoryClass = PropertiesUtil.getProperties().getStringProperty(CONFIGURATION_FACTORY_PROPERTY); if (factoryClass != null) { addFactory(list, factoryClass); } final PluginManager manager = new PluginManager(CATEGORY); manager.collectPlugins(); final Map<String, PluginType<?>> plugins = manager.getPlugins(); final List<Class<? extends ConfigurationFactory>> ordered = new ArrayList<>(plugins.size()); for (final PluginType<?> type : plugins.values()) { try { ordered.add(type.getPluginClass().asSubclass(ConfigurationFactory.class)); } catch (final Exception ex) { LOGGER.warn("Unable to add class {}", type.getPluginClass(), ex); } } Collections.sort(ordered, OrderComparator.getInstance()); for (final Class<? extends ConfigurationFactory> clazz : ordered) { addFactory(list, clazz); } // see above comments about double-checked locking //noinspection NonThreadSafeLazyInitialization factories = Collections.unmodifiableList(list); } } finally { LOCK.unlock(); } } LOGGER.debug("Using configurationFactory {}", configFactory); return configFactory; }
public Configuration getConfiguration(final LoggerContext loggerContext, final String name, final URI configLocation) { if (configLocation == null) { /* //CONFIGURATION_FILE_PROPERTY = "log4j.configurationFile"; 1、log4j.configurationFile---ConfigurationFactory */ final String configLocationStr = this.substitutor.replace(PropertiesUtil.getProperties() .getStringProperty(CONFIGURATION_FILE_PROPERTY)); if (configLocationStr != null) { final String[] sources = configLocationStr.split(","); if (sources.length > 1) { final List<AbstractConfiguration> configs = new ArrayList<>(); for (final String sourceLocation : sources) { final Configuration config = getConfiguration(loggerContext, sourceLocation.trim()); if (config != null && config instanceof AbstractConfiguration) { configs.add((AbstractConfiguration) config); } else { LOGGER.error("Failed to created configuration at {}", sourceLocation); return null; } } return new CompositeConfiguration(configs); } return getConfiguration(loggerContext, configLocationStr); } /* 2、log4j2-test.properties---PropertiesConfigurationFactory 3、log4j2-test.yaml/log4j2-test.yml---YAMLConfigurationFactory 4、log4j2-test.json/log4j2-test.jsn---JsonConfigurationFactory 5、log4j2-test.xml---XMLConfigurationFactory 6、log4j2.properties---PropertiesConfigurationFactory 7、log4j2.yaml/log4j2.yml---YAMLConfigurationFactory 8、log4j2.json/log4j2.jsn---JSONConfigurationFactory 9、log4j2.xml---XMLConfigurationFactory 10、console控制檯---DefaultConfiguration */ for (final ConfigurationFactory factory : getFactories()) { final String[] types = factory.getSupportedTypes(); if (types != null) { for (final String type : types) { if (type.equals(ALL_TYPES)) { final Configuration config = factory.getConfiguration(loggerContext, name, configLocation); if (config != null) { return config; } } } } } } else { // configLocation != null final String configLocationStr = configLocation.toString(); for (final ConfigurationFactory factory : getFactories()) { final String[] types = factory.getSupportedTypes(); if (types != null) { for (final String type : types) { if (type.equals(ALL_TYPES) || configLocationStr.endsWith(type)) { final Configuration config = factory.getConfiguration(loggerContext, name, configLocation); if (config != null) { return config; } } } } } } Configuration config = getConfiguration(loggerContext, true, name); if (config == null) { config = getConfiguration(loggerContext, true, null); if (config == null) { config = getConfiguration(loggerContext, false, name); if (config == null) { config = getConfiguration(loggerContext, false, null); } } } if (config != null) { return config; } LOGGER.error("No Log4j 2 configuration file found. " + "Using default configuration (logging only errors to the console), " + "or user programmatically provided configurations. " + "Set system property 'log4j2.debug' " + "to show Log4j 2 internal initialization logging. " + "See https://logging.apache.org/log4j/2.x/manual/configuration.html for instructions on how to configure Log4j 2"); return new DefaultConfiguration(); }