Log4j Transform contains tools for binary postprocessing of projects that use the Apache Log4j2 API.
Log4j Transform Maven Plugin
The Transform Plugin is used to postprocess the compiled classes of your project and replace all Log4j 2.x API calls with LogBuilder
calls with a statically precomputed location.
This allows you to use location information in your logs without incurring in the expensive runtime calls usually used to acquire it.
Why do we need it
Finding the location of a logging call is a very expensive operation (a couple of microseconds).
Running LocationBenchmark
on a Ryzen 7 2700U laptop with Java 17 gives the following results:
Logging interface | Sync/async logger | No. threads | Precomputed location | Score | Error | Units |
---|---|---|---|---|---|---|
sync |
1 |
yes |
202343,624 |
±719,875 |
ops/s |
|
sync |
1 |
no |
68449,813 |
±5086,148 |
ops/s |
|
sync |
1 |
yes |
202579,793 |
±547,961 |
ops/s |
|
sync |
1 |
no |
100105,246 |
±13748,554 |
ops/s |
|
async |
8 |
yes |
726877,012 |
±38214,575 |
ops/s |
|
async |
8 |
no |
440245,135 |
±4849,946 |
ops/s |
The figures show a performance bump of around 5 µs per logging statement when
Logger
is used and a bump of around 9 µs per logging statement when
LogBuilder
is used.
By comparison, disabling location information on the same machine gives:
Logging interface | Sync/async logger | No. threads | Precomputed location | Score | Error | Units |
---|---|---|---|---|---|---|
sync |
1 |
yes |
234666,556 |
±19759,779 |
ops/s |
|
sync |
1 |
no |
212562,315 |
±3631,670 |
ops/s |
|
sync |
1 |
yes |
210751,730 |
±1508,148 |
ops/s |
|
sync |
1 |
no |
220837,404 |
±13248,184 |
ops/s |
|
async |
8 |
yes |
743467,533 |
±38046,044 |
ops/s |
|
async |
8 |
no |
776778,635 |
±38878,794 |
ops/s |
How it works
The working principle is very simple: every call to the Log4j 2.x API like
public void helloLog() {
logger.info(MarkerManager.getMarker("NET"), "Sending {} bytes of data.", 1000);
}
is rewritten at a bytecode level into an equivalent LogBuilder
call:
private static final StackTraceElement[] locations = {
new StackTraceElement("org.apache.logging.log4j.HelloWorld", "HelloWorld.java", "helloLog", 1234)
};
public void helloLog() {
logger.atInfo()
.withLocation(locations[0])
.withMarker(MarkerManager.getMarker("NET"))
.log("Sending {} bytes of data.", 1000);
}
In the current implementation locations are stored in classes whose name ends in $$Log4j2$$Cache
, so they can not accidentally be used by XML/JSON serializers.
Goals
This plugin consists of a single goal:
log4j-transform:process-classes
-
is bound to the process-classes phase and weaves your classes to include precomputed location information.
log4j-transform:process-classes
- Full name
-
org.apache.logging.log4j:log4j-transform-maven-plugin:0.1.0:process-classes
- Description
-
Generates static location information of Log4j 2.x API calls in the project classes. The resulting bytecode will not rely on runtime resolution of the location information.
- Attributes
-
-
Requires a Maven project to be executed
-
Requires dependency resolution of artifacts in scope:
<code>compile</code>
-
The goal is thread-safe and supports parallel builds
-
Binds by default to the lifecycle phase:
process-classes
.
-
Required Parameters
Name | Type | Description |
---|---|---|
|
|
The directory containing classes to be processed.
It defaults to |
|
|
The directory where woven classes will be written.
It defaults to |
Optional Parameters
Name | Type | Description |
---|---|---|
|
|
Files to include. If empty all class files will be processed. |
|
|
Files to exclude. |
|
|
Sets the granularity in milliseconds of the last modification date for testing if a class file needs weaving.
It defaults to |
Usage
To use the plugin you need to declare a dependency on log4j-api
version 2.20.0 or newer.
Add the following configuration to your POM file:
<plugin>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-transform-maven-plugin</artifactId>
<version>0.1.0</version>
<executions>
<execution>
<goals>
<goal>process-classes</goal>
</goals>
</execution>
</executions>
</plugin>
Maven Shade Plugin Extensions
This project contains a collection of resource transformers for the Apache Maven Shade Plugin that allows you to use additional Log4j 2.x Core component modules.
Log4j Plugin Cache Transformer
A
resource transformer
for the
Apache Maven Shade Plugin
that merges Log4j2Plugins.dat
plugin caches from all the jars containing Log4j 2.x Core components.
This transformer was formerly available at edwgiz/maven-shaded-log4j-transformer and was donated to the Apache Software Foundation by its author.
Usage
This resource transformer is usually used together with the ManifestResourceTransformer
and ServicesResourceTransformer
to integrate Log4j 2.x libraries in a shaded JAR.
A typical configuration is:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-transform-maven-shade-plugin-extensions</artifactId>
<version>0.1.0</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>shade-jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.logging.log4j.maven.plugins.shade.transformer.Log4j2PluginCacheFileTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Multi-Release>true</Multi-Release>
</manifestEntries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
Development
Log4j Transform uses GitHub for source code management.
The project requires a Java compiler matching the [17,18)
range and targets Java 8
.
You can build and verify sources using:
./mvnw verify
You can build and view the website as follows:
./mvnw -N site
python -m http.server -d target/site
Distribution
In accordance with the Apache Software Foundation’s release distribution policy and creation process, project artifacts are officially accessible from the following locations:
-
ASF Release and snapshot repositories (mirrored to the Maven Central Repository)
See the release instructions for details.
Support
Please keep in mind that this project is intended for internal usage only. You can use GitHub Issues for feature requests and bug reports – not questions! See the Log4j support policy for details.
Security
If you have encountered an unlisted security vulnerability or other unexpected behaviour that has security impact, please report them privately to the Log4j security mailing list. See the Log4j Security page for further details.
Release Notes
0.x.x
This is the second release of the project.
Added
-
Started publishing the project website
Changed
-
Migrated to
logging-parent
10.1.1 and adopted its CI andpom.xml
infrastructure -
Update
org.ow2.asm:asm-bom
to version9.6
0.1.0
- Release date
-
2023-05-05
This is the first release of the project.
Added
-
Added
log4j-transform-maven-plugin
bytecode transformation tool to provide location information without reflection (LOG4J2-3638) -
Added
log4j-transform-maven-shade-plugin-extensions
resource transformer for the Maven Shade Plugin to mergeLog4j2Plugins.dat
plugin caches (LOG4J2-673)
Release instructions
Log4j Transform employs the CI/CD foundation provided by the logging-parent
.
You can simply use its release instructions.
License
Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.
See NOTICE.txt
distributed with this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at https://www.apache.org/licenses/LICENSE-2.0.
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.