log4j2 the plug

Background: log4j version 2.11.0, and opened the asynchronous log

log4j2 context load

  1. Log4jContextFactory context factory creates a log context
  2. Asynchronous log AsyncLoggerContextSelector context selector get the context. locateContext positioning context, according classloader corresponding key (AsyncContext @ + hashcode (10 decimal)) for obtaining the context from the context Map; recursive parentClassLoader, if the context does not exist, create a log AsyncLoggerContext
  3. If there is an external context provided setExternalContext
  4. If the context is initialized status but have not yet started, ie _INITIALIZED. Start the context _
  5. Start loggerDisruptor. Callback parent (LoggerContext) start Method
  6. _Reconfigure configuration context and then if the current state is _INITIALIZED, the update state to a STARTING startup
  7. The log4j.configurationFactory configuration factory configuration obtaining, if not empty the corresponding factory class is added to the pending list

Plug-in Manager to load configuration

  1. Creating ConfigurationFactory class Plug-In Manager to obtain configuration PluginManager factory ConfigurationFactory. Plug-in Manager Plug-collectPlugins collection
  2. Plug registrar PluginRegistry load built-in plug-in collection loadFromMainClassLoader
  3. Gets a collection of plug-in cache, there is a direct return
  4. The class loader Loader File Cache deserialization
  5. Creating PluginCache plug-in cache instances
  6. Read data files: META-INF / org / apache / logging / log4j / core / config / plugins / Log4j2Plugins.dat
  7. Plug-in cache to load data files loadCacheFiles, the data deserialized into PluginEntry type of cache to cache plugin PluginCache.categories: configurationfactory, core, converter, lookup, fileconverter, typeconverter
  8. Traversing the list of categories, plug-in type package according to obtain PluginEntry configured PluginType type, returns a set of cache to pluginsByCategoryRef newPluginsByCategory
  9. If the built-plug set is empty, then the packet load path as built according org.apache.logging.log4j.core widget set, the scanning path Plugin annotation packet class. Or PluginAliases annotated classes (on behalf of a _Plugin, PluginAttribute or PluginBuilderAttribute_ collection), if the plug is empty Plugin._EMPTY annotation is used to rename _alias otherwise use elementType as aliasElementName
  10. According to merge categoryLowerCase lowercase names from the built-in plug-in to newPlugins: mergeByName
  11. The above is loaded plug-in from classLoader, _OSGi Bundles bundled plug-ins if there is the same load and merge mergeByName_
  12. According to the Plugin Manager _PACKAGES configured similarly loaded and merged _loadFromPackage
  13. If the parameter is not empty packages and merge the same load
  14. The new plug-newPlugins bound to the Plug-in Manager plugins property
  15. Plugin manager acquires ConfigurationFactory corresponding widget set according to the annotation Order and sorted according to the order (descending order according to order)
  16. Reflection ConfigurationFactory no arguments constructor call instance chemical plants and added to the collection _ _factories
  17. Return _configFactory instance of the default factory implementation _Factory

Configuring factory for Configuration

  1. If there is an external context and there configLocation configuration, for example, is acquired based on the profile configuration ConfigurationSource: XmlConfigurationFactory
  2. externalContext classloader does not exist outside the context of a null callback CL obtain the Factory default configuration getConfiguration
  3. If configLocation is empty read log4j.configurationFile configuration, if the configuration is not in accordance with the specified configuration file is empty sourceLocation obtain configuration.
  4. If the package is configured as a plurality of CompositeConfiguration type, single configuration otherwise
  5. If configLocation still empty, then traverse ConfigurationFactory type obtained from a collection of plug-in management _factories_
  6. If you configure factory support _ALL_TYPES _ = "*" type, the callback method to obtain the factory getConfiguration Configuration configuration, if the configuration is not null is returned, the back of the factory configuration does not continue to call, for example, the screenshot will automatically call the configurationimage.png

The custom log context Configuration

  1. Configuration Example of Configuration The configuration log LoggerContext.setConfiguration returned context
  2. If the configuration file is empty then return default configuration does not do anything. The default configuration DefaultConfiguration level ERROR console standard output pipe
  3. Obtaining the configuration file ContextProperties component properties getComponent, set the local context name and hostnameimage.png
  4. Start Configuration Configuration start
  5. The configuration is bound to the current context LoggerContext log
  6. Send configuration change events firePropertyChangeEvent: PropertyChangeEvent
  7. Callback event listener method PropertyChangeListener.propertyChange

At this point the log context loaded

Logger and Filter filter

@Override
protected Logger newInstance(final LoggerContext ctx, final String name, final MessageFactory messageFactory) {
    return new AsyncLogger(ctx, name, messageFactory, loggerDisruptor);
}
  1. According to the log context creation Logger
  2. Call the parent class constructor
protected Logger(final LoggerContext context, final String name, final MessageFactory messageFactory) {
    super(name, messageFactory);
    this.context = context;
    privateConfig = new PrivateConfig(context.getConfiguration(), this);
}
  1. Profiles and context get the current instance according to the log logger create log configuration PrivateConfig
public PrivateConfig(final Configuration config, final Logger logger) {
    this.config = config;
    this.loggerConfig = config.getLoggerConfig(getName());
    this.loggerConfigLevel = this.loggerConfig.getLevel();
    this.intLevel = this.loggerConfigLevel.intLevel();
    this.logger = logger;
}
  1. Configuration acquired from the corresponding name of the log according to configuration LoggerConfig Logger
public LoggerConfig getLoggerConfig(final String loggerName) {
    LoggerConfig loggerConfig = loggerConfigs.get(loggerName);
    if (loggerConfig != null) {
        return loggerConfig;
    }
    String substr = loggerName;
    //按照"."符号一层层向上查找匹配的日志配置,如果不存在则返回默认root配置
    while ((substr = NameUtil.getSubName(substr)) != null) {
        loggerConfig = loggerConfigs.get(substr);
        if (loggerConfig != null) {
            return loggerConfig;
        }
    }
    return root;
}
//默认DefaultConfiguration配置对应的默认LoggerConfig配置
protected void setToDefault() {
    // LOG4J2-1176 facilitate memory leak investigation
    setName(DefaultConfiguration.DEFAULT_NAME + "@" + Integer.toHexString(hashCode()));
    final Layout<? extends Serializable> layout = PatternLayout.newBuilder()
            .withPattern(DefaultConfiguration.DEFAULT_PATTERN)
            .withConfiguration(this)
            .build();
    final Appender appender = ConsoleAppender.createDefaultAppenderForLayout(layout);
    appender.start();
    addAppender(appender);
    final LoggerConfig rootLoggerConfig = getRootLogger();
    //配置Appender、level(为空则代表记录所有事件)、filter(为空代表不存在过滤器)
    rootLoggerConfig.addAppender(appender, null, null);

    final Level defaultLevel = Level.ERROR;
    final String levelName = PropertiesUtil.getProperties().getStringProperty(DefaultConfiguration.DEFAULT_LEVEL,
            defaultLevel.name());
    final Level level = Level.valueOf(levelName);
    rootLoggerConfig.setLevel(level != null ? level : defaultLevel);
}
  1. Before we talk about such as custom configuration CustomXmlConfigurationFactory
  2. Common filtering configuration also ThresholdFilter, LevelRangeFilter injected through plug-in management
@Plugin(
    name = "CustomXmlConfigurationFactory",
    category = "ConfigurationFactory"
)
@Order(10)
public class CustomXmlConfigurationFactory extends ConfigurationFactory {
    private static final String[] SUFFIXES = new String[]{".xml", "*"};

    public CustomXmlConfigurationFactory() {
    }

    public String[] getSupportedTypes() {
        return SUFFIXES;
    }

    public Configuration getConfiguration(LoggerContext loggerContext, ConfigurationSource source) {
        XmlConfiguration template = new XmlConfiguration(loggerContext, ConfigurationSource.fromResource("log4j2-template.xml", this.getClass().getClassLoader()));
        XmlConfiguration specific = new XmlConfiguration(loggerContext, source);
        return new CompositeConfiguration(Lists.newArrayList(new XmlConfiguration[]{template, specific}));
    }
}

XmlConfiguration

  1. Creating LoggerContext weak reference, rootNode, Plugin Manager (core directory), ContextProperties assembly map, set the initialization state
  2. Xml parsing the configuration of the dom tree
  3. Creating StatusConfiguration configure individual property Binding dom configuration example: logger
  4. Startup configuration start, LoggerContext start configuration after obtaining configuration
  5. Initial Configuration initialize
  6. Create a ScriptManager
  7. Gets core plug
  8. Get class class level plug, plug-initialization level, the use of plug-class classloader to load plug-ins
  9. All child elements rootNode associate dom tree rootElement elements: Configuration setup
  10. doConfigure configuration, create a configuration createConfiguration, if it is set to create a list of the type corresponding to the type of binding Node.object property; otherwise use PluginBuilder builders to build plug-in instance is bound to the corresponding property Node.object
  11. If the child node is then bound to the appenders Appenders
  12. If the child node is added to the Filter type configuration, the filter chain if the chain is added to the filter
  13. If the child node is acquired Loggers configuration corresponding to bind loggerConfigs
  14. Start loggerConfigs
  15. Start appenders
  16. Start filter filters the current configuration bindings

to sum up

log4j plugin Plugin Manager plug-in configuration management PluginManager scan reads all supported plug-class configuration. Injecting and attribute instantiates the corresponding plugin PluginBuilder. There are many advantages jdk official spi relative, such as support kv way to inject. The injection plug-in type. But the disadvantage is somewhat complicated to achieve, and the profile of poor readability, use is also more complicated

Guess you like

Origin blog.csdn.net/u010597819/article/details/92429838