Status
Current state: Under Discussion
Discussion thread: thread
Please keep the discussion on the mailing list rather than commenting on the wiki (wiki discussions get unwieldy fast).
Motivation
Kafka has been using log4j and providing a log4j appender also. KIP-653 upgrades log4j to log4j2, but some modules (log4j-appender, tools, and trogdor) were omitted, since providing log4j2 appender was beyond the scope of the proposal. As of the KIP-653 was passed (before 2.8.0), trogdor was not separated from tools yet, and tools depended upon log4j-appender, since VerifiableLog4jAppender uses it. It is why those three modules were excluded from the upgrade, and both log4j and log4j2 artifacts came to co-exist after the upgrade.
However, as the preview build is released and tested, this approach turned out to be wrong: some users reported that when running Kafka with log4j configuration file (which is allowed for backward compatibility), the logging message is sometimes not appended properly to the logger file. This problem was resolved after removing the log4j artifacts from the classpath.
This proposal aims to entirely remove the log4j artifact from the classpath by providing a log4j2 equivalent of log4j-appender, and upgrading all the omitted modules (i.e., tools and trogdor) into log4j2 to avoid the problem above. Plus, it can also allow the users of the deprecated log4j-appender to upgrade.
Public Interfaces
The users will be able to use org.apache.kafka:log4j2-appender:{kafka-version}
dependency with log4j2 configuration syntax, like:
name=ExampleConfig status=OFF packages=org.apache.kafka.log4j2appender appenders=kafkaAppender appender.kafkaAppender.type=KafkaAppender appender.kafkaAppender.name=kafkaAppender appender.kafkaAppender.topic=test-topic appender.kafkaAppender.brokerList=broker-0:9092,broker-1:9092,broker-2:9092 appender.kafkaAppender.layout.type=PatternLayout appender.kafkaAppender.layout.pattern=[%d] %p %m (%c:%L)%n rootLogger.level=INFO rootLogger.appenderRefs=kafkaAppender rootLogger.appenderRef.kafkaAppender.ref=kafkaAppender
Proposed Changes
The goal of this proposal is to provide a log4j2-equivalent of traditional log4j appender, following the principles below:
- All configuration properties in log4j-appender must be supported in its log4j2 successor.
- It should run by only converting legacy log4j syntax into log4j2.
- It should provide a way to run legacy configuration for backward-compatibility.
- It should have the same semantic as log4j-appender.
- It should have the same format with log4j-appender for backward-compatibility. That is, the key must always be null, and the value must have a log message. The records produced by log4j-appender and its log4j2 successor should not be distinguishable.
- It should reflect the recent changes made to the Producer.
- If there is a change in Producer property, it should also be applied to the log4j2 appender.
- If the name of the log4j-appender property and Producer property is different, it should support the latter one.
With log4j2-appender, the leaving modules (tools, trogdor) 's slf4j, log4j 1.x dependencies will be upgraded into log4j2 and additional log4j2 configuration file will be provided. For backward compatibility, these tools will use the log4j configuration file (tools-log4j2.properties) by default. But for informational purpose, the following message will be shown when user launches kafka-run-class.sh:
DEPRECATED: using log4j 1.x configuration. To use log4j 2.x configuration, run with: 'export KAFKA_LOG4J_OPTS="-Dlog4j.configurationFile=file:$base_dir/config/tools-log4j2.properties"'
As the message above states, the user can run the tools with log4j2 config file by setting `export KAFKA_LOG4J_OPTS="-Dlog4j.configurationFile={log4j2-config-file-path}"`. Thanks to log4j12-api, a compatibility bridge between log4j and log4j2, the tools can be run without any changes.
Compatibility, Deprecation, and Migration Plan
Since this module is a new one, there is no Deprecation or Migration Plan.
If a user hopes to use log4j2-appender with legacy log4j configuration, they can do it by:
- Add a bridge dependency,
org.apache.logging.log4j:log4j-1.2-api:{log4j2-version}
, to the project. - Run java application with
`-Dlog4j.configuration={log4j-config-path}`
JVM parameter.
Rejected Alternatives
Leave the omitted modules (tools, trogdor) to use log4j 1.x.
This approach has the following problems:
- Inconsistency: if a user wants to change the logging of tools or trogdor, they have to deal with the deprecated log4j configuration syntax; KIP-653 still supports to use of log4j configuration for backward compatibility, but it will be removed in the future.
- Complexity: it makes the classpath generation logic in shell scripts complex.
Instead of providing log4j2-appender, make use of the already-existing log4j2 appender provided by the community.
As far as I know, all of the major community appenders have a different format with log4j-appender; For example, the Kafka appender provided by log4j2 community stores log message in the Record key; in contrast, log4j-appender fixes the key to null and stores log message in the Record value. For this reason, the projects depending on log4j-appender are not compatible with those community implementations, not transparently replaceable.
Remove VerifiableLog4jAppender from tools, and upgrade the omitted modules (tools, trogdor) to use log4j2.
To remove any existing tool, regardless of whether it is used frequently or not, we have to deprecate it first and remove it after a reasonable period of time. This approach will make the adoption of log4j2 too late.