You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@logging.apache.org by "ASF subversion and git services (Jira)" <ji...@apache.org> on 2022/02/14 06:22:00 UTC

[jira] [Commented] (LOG4J2-2803) Create standardized scopes and dependency injection API

    [ https://issues.apache.org/jira/browse/LOG4J2-2803?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17491811#comment-17491811 ] 

ASF subversion and git services commented on LOG4J2-2803:
---------------------------------------------------------

Commit fb954c5d37c7e2832d8c4f724c4b56df8bdd528b in logging-log4j2's branch refs/heads/master from Matt Sicker
[ https://gitbox.apache.org/repos/asf?p=logging-log4j2.git;h=fb954c5 ]

Delete previous attempt at LOG4J2-2803

This helps the diff a bit.


> Create standardized scopes and dependency injection API
> -------------------------------------------------------
>
>                 Key: LOG4J2-2803
>                 URL: https://issues.apache.org/jira/browse/LOG4J2-2803
>             Project: Log4j 2
>          Issue Type: Epic
>          Components: Configuration, Core, Plugins
>            Reporter: Matt Sicker
>            Assignee: Matt Sicker
>            Priority: Major
>             Fix For: 3.0.0
>
>
> h2. Context
> The existing plugin system revolves around {{@Plugin}} annotations which group together configurable interfaces into categories. The category of a plugin typically determines the configuration and instantiation strategy for the plugin classes involved which leads to some ad hoc methods for different plugins to obtain or configure different aspects of the system. All classes that are included in the plugin system can be queried at runtime by constructing a {{PluginManager}} with the category name as its constructor argument. To date, there are a few plugin categories (case-insensitive):
>  * {{{}Core{}}}: used for configuration elements in config files for general core plugins like appenders, filters, layouts, etc. These are provided values from parsed configuration nodes and can also obtain the {{Configuration}} instance to access other services.
>  * {{{}Level{}}}: used for specifying custom log levels so that they can be instantiated early enough for configurations to make use of it.
>  * {{{}ConfigurationFactory{}}}: used for parsing and validating configuration sources in some format into a configuration node tree which is transformed into a {{{}Configuration{}}}. Also useful for programmatic configuration.
>  * {{{}Lookup{}}}: used for variable interpolation in strings via {{StrLookup}} classes.
>  * {{{}TypeConverter{}}}: used for converting strings into other objects. Mostly useful for conversion of plugin attributes into common types along with use in certain core plugins such as database column mappers.
>  * {{{}Converter{}}}: used for pattern layout conversion keys. These are used for formatting log event info into a layout.
>  * {{{}Watcher{}}}: used for watching configuration sources for changes in order to allow for reconfiguration.
> Then there are some system-wide plugin-like classes that can be specified via system properties including:
>  * {{{}ClockFactory{}}}: controls {{Clock}} instances for obtaining the current time. Mostly useful in testing and scenarios where approximate time is more useful than exact time.
>  * {{{}LogEventFactory{}}}: constructs {{LogEvent}} instances for a given log message and parameters. Useful for implementing different allocation strategies for log events.
>  * {{{}MergeStrategy{}}}: used for composite configurations.
>  * {{{}ContextSelector{}}}: used for obtaining a {{LoggerContext}} for an invocation context when initializing or obtaining {{Logger}} instances. By default, this maps contexts to class loaders, and additional strategies are available including async loggers, a singleton context, a JNDI-lookup-based context, and an OSGi bundle context.
>  * {{{}LoggerContextFactory{}}}: used for binding a logging implementation to the Logging API.
>  * {{{}ShutdownCallbackRegistry{}}}: used for registering a logging system cleanup shutdown callback in various systems. The default strategy hooks in to the {{Runtime}} shutdown threads API.
>  * {{{}ContextDataInjector{}}}: used for adding initial context data into the {{ThreadContext}} of a {{{}LogEvent{}}}.
> h2. Proposal
> This system grew organically over time, and after identifying various duplicated plugin functionality around the codebase, the plugin system should be overhauled along the lines of a more standard {{{}@Inject{}}}-style dependency injection framework. By adopting more conventional DI patterns, this will remove the need for ad hoc plugin mechanisms in different subsystems, allow for more flexible declarations of plugins by specifying direct classes needed by plugins rather than doing manual lookups on the {{Configuration}} instance, allow for smarter initialization strategies to minimize startup time and resource usage based on configurations rather than eagerly loading plugins, make it simpler to write unit tests, and make it generally simpler to write and maintain plugins without requiring deep expertise of esoteric subsystems.
> [Proposal details in Confluence|https://cwiki.apache.org/confluence/display/LOGGING/Dependency+Injection+and+Configuration]
> h2. Additional Details
>  
> Beyond the dependency injection API itself, this epic is motivated by the following goals:
>  * Simplify plugin classes that currently require manual method calls to {{Configuration}} or {{{}Node{}}}.
>  * Unify the various ad hoc dependency injection for configuration-scoped or singleton-scoped classes (the latter which are overridden via system properties) including:
>  ** {{StrSubstitutor}}
>  ** {{ConfigurationScheduler}} (or scheduled tasks in general)
>  ** {{ScriptManager}}
>  ** {{WatchManager}}
>  ** {{NanoClock}}
>  ** {{ShutdownCallbackRegistry}}
>  ** {{Clock}}
>  ** {{ContextSelector}}
>  ** {{ConfigurationFactory}}
>  ** {{LogEventFactory}}
>  ** {{ContextDataFactory}}
>  * Make dependencies between classes more explicit via inversion of control which allows for easier testing and modularity.
>  * Avoid the use of manual configuration handling at the API level of any plugins including basic string parsing (as currently supported through the {{TypeConverter}} API), class loading from strings, and ad hoc reflection. This relates to the changes made in LOG4J2-2621 and LOG4J2-1917.
>  * Provide smart initialization logic to continue (or maintain) improvements to startup time and avoid loading plugins that aren't referenced in the loaded configuration.



--
This message was sent by Atlassian Jira
(v8.20.1#820001)