Skip to content

Commit 4772ad8

Browse files
authored
Add support for log4j 1.2.4 (#101)
1 parent f069958 commit 4772ad8

File tree

11 files changed

+200
-10
lines changed

11 files changed

+200
-10
lines changed

ecs-logging-core/src/main/java/co/elastic/logging/EcsJsonSerializer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ public static void serializeOrigin(StringBuilder builder, String fileName, Strin
153153
}
154154

155155
public static void serializeMDC(StringBuilder builder, Map<String, ?> properties) {
156-
if (!properties.isEmpty()) {
156+
if (properties != null && !properties.isEmpty()) {
157157
for (Map.Entry<String, ?> entry : properties.entrySet()) {
158158
builder.append('\"');
159159
String key = entry.getKey();

log4j-ecs-layout/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Log4j ECS Layout
22
🚧
33

4+
The minimum required logback version is 1.2.4.
5+
46
## Step 1: add dependency
57
Latest version: [![Maven Central](https://img.shields.io/maven-central/v/co.elastic.logging/log4j-ecs-layout.svg)](https://search.maven.org/search?q=g:co.elastic.logging%20AND%20a:log4j-ecs-layout)
68

log4j-ecs-layout/pom.xml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,23 @@
1414
<parent.base.dir>${project.basedir}/..</parent.base.dir>
1515
</properties>
1616

17+
<build>
18+
<plugins>
19+
<plugin>
20+
<groupId>org.apache.maven.plugins</groupId>
21+
<artifactId>maven-jar-plugin</artifactId>
22+
<version>3.1.2</version>
23+
<executions>
24+
<execution>
25+
<goals>
26+
<goal>test-jar</goal>
27+
</goals>
28+
</execution>
29+
</executions>
30+
</plugin>
31+
</plugins>
32+
</build>
33+
1734
<dependencies>
1835
<dependency>
1936
<groupId>${project.groupId}</groupId>
@@ -23,6 +40,9 @@
2340
<dependency>
2441
<groupId>log4j</groupId>
2542
<artifactId>log4j</artifactId>
43+
<!-- min supported version
44+
<version>1.2.4</version>
45+
-->
2646
<version>1.2.17</version>
2747
<scope>provided</scope>
2848
</dependency>

log4j-ecs-layout/src/main/java/co/elastic/logging/log4j/EcsLayout.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232

3333
public class EcsLayout extends Layout {
3434

35+
private static final MdcAccess MDC_ACCESS = MdcAccess.Resolver.resolve();
36+
3537
private boolean stackTraceAsArray = false;
3638
private String serviceName;
3739
private boolean includeOrigin;
@@ -40,14 +42,14 @@ public class EcsLayout extends Layout {
4042
@Override
4143
public String format(LoggingEvent event) {
4244
StringBuilder builder = new StringBuilder();
43-
EcsJsonSerializer.serializeObjectStart(builder, event.getTimeStamp());
44-
EcsJsonSerializer.serializeLogLevel(builder, event.getLevel().toString());
45+
EcsJsonSerializer.serializeObjectStart(builder, event.timeStamp);
46+
EcsJsonSerializer.serializeLogLevel(builder, event.level.toString());
4547
EcsJsonSerializer.serializeFormattedMessage(builder, event.getRenderedMessage());
4648
EcsJsonSerializer.serializeServiceName(builder, serviceName);
4749
EcsJsonSerializer.serializeEventDataset(builder, eventDataset);
4850
EcsJsonSerializer.serializeThreadName(builder, event.getThreadName());
49-
EcsJsonSerializer.serializeLoggerName(builder, event.getLoggerName());
50-
EcsJsonSerializer.serializeMDC(builder, event.getProperties());
51+
EcsJsonSerializer.serializeLoggerName(builder, event.categoryName);
52+
EcsJsonSerializer.serializeMDC(builder, MDC_ACCESS.getMDC(event));
5153
EcsJsonSerializer.serializeTag(builder, event.getNDC());
5254
if (includeOrigin) {
5355
LocationInfo locationInformation = event.getLocationInformation();
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*-
2+
* #%L
3+
* Java ECS logging
4+
* %%
5+
* Copyright (C) 2019 - 2020 Elastic and contributors
6+
* %%
7+
* Licensed to Elasticsearch B.V. under one or more contributor
8+
* license agreements. See the NOTICE file distributed with
9+
* this work for additional information regarding copyright
10+
* ownership. Elasticsearch B.V. licenses this file to you under
11+
* the Apache License, Version 2.0 (the "License"); you may
12+
* not use this file except in compliance with the License.
13+
* You may obtain a copy of the License at
14+
*
15+
* http://www.apache.org/licenses/LICENSE-2.0
16+
*
17+
* Unless required by applicable law or agreed to in writing,
18+
* software distributed under the License is distributed on an
19+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20+
* KIND, either express or implied. See the License for the
21+
* specific language governing permissions and limitations
22+
* under the License.
23+
* #L%
24+
*/
25+
package co.elastic.logging.log4j;
26+
27+
import org.apache.log4j.MDC;
28+
import org.apache.log4j.pattern.LogEvent;
29+
import org.apache.log4j.spi.LoggingEvent;
30+
31+
import java.util.Collections;
32+
import java.util.Map;
33+
34+
public interface MdcAccess {
35+
36+
Map<String, ?> getMDC(LoggingEvent event);
37+
38+
class Resolver {
39+
public static MdcAccess resolve() {
40+
try {
41+
LoggingEvent.class.getMethod("getProperties");
42+
return (MdcAccess) Class.forName("co.elastic.logging.log4j.MdcAccess$GetPropertiesCapable").getEnumConstants()[0];
43+
} catch (Exception ignore) {
44+
} catch (LinkageError ignore) {
45+
}
46+
return ForLegacyLog4j.INSTANCE;
47+
}
48+
}
49+
50+
/**
51+
* For log4j versions {@code >=} 1.2.15 that have the {@link LogEvent#getProperties()} method
52+
*/
53+
enum GetPropertiesCapable implements MdcAccess {
54+
INSTANCE;
55+
56+
@Override
57+
public Map<String, ?> getMDC(LoggingEvent event) {
58+
if (Thread.currentThread().getName().equals(event.getThreadName())) {
59+
// avoids copying the properties if the appender is synchronous
60+
return MDC.getContext();
61+
}
62+
return event.getProperties();
63+
}
64+
}
65+
66+
/**
67+
* Fallback for log4j versions {@code <} 1.2.15
68+
*/
69+
enum ForLegacyLog4j implements MdcAccess {
70+
INSTANCE;
71+
72+
@Override
73+
public Map<String, ?> getMDC(LoggingEvent event) {
74+
if (Thread.currentThread().getName().equals(event.getThreadName())) {
75+
return MDC.getContext();
76+
}
77+
// can't access MDC in async appenders
78+
return Collections.emptyMap();
79+
}
80+
}
81+
}

log4j-ecs-layout/src/test/java/co/elastic/logging/log4j/Log4jEcsLayoutTest.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@
2727
import co.elastic.logging.AbstractEcsLoggingTest;
2828
import co.elastic.logging.ParameterizedLogSupport;
2929
import com.fasterxml.jackson.databind.JsonNode;
30-
import org.apache.log4j.*;
30+
import org.apache.log4j.LogManager;
31+
import org.apache.log4j.Logger;
32+
import org.apache.log4j.MDC;
33+
import org.apache.log4j.NDC;
3134
import org.junit.jupiter.api.AfterEach;
3235
import org.junit.jupiter.api.Assumptions;
3336
import org.junit.jupiter.api.BeforeEach;
@@ -58,7 +61,11 @@ void setUp() {
5861
@BeforeEach
5962
@AfterEach
6063
void tearDown() {
61-
MDC.clear();
64+
try {
65+
// available since 1.2.16
66+
MDC.class.getMethod("clear").invoke(null);
67+
} catch (Exception ignore) {
68+
}
6269
NDC.clear();
6370
}
6471

log4j-legacy-tests/pom.xml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<artifactId>ecs-logging-java-parent</artifactId>
7+
<groupId>co.elastic.logging</groupId>
8+
<version>0.5.3-SNAPSHOT</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
12+
<artifactId>log4j-legacy-tests</artifactId>
13+
14+
<properties>
15+
<parent.base.dir>${project.basedir}/..</parent.base.dir>
16+
<maven-deploy-plugin.skip>true</maven-deploy-plugin.skip>
17+
</properties>
18+
19+
<dependencies>
20+
<dependency>
21+
<groupId>${project.groupId}</groupId>
22+
<artifactId>ecs-logging-core</artifactId>
23+
<version>${project.version}</version>
24+
<type>test-jar</type>
25+
<scope>test</scope>
26+
</dependency>
27+
<dependency>
28+
<groupId>${project.groupId}</groupId>
29+
<artifactId>log4j-ecs-layout</artifactId>
30+
<version>${project.version}</version>
31+
<scope>test</scope>
32+
</dependency>
33+
<dependency>
34+
<groupId>${project.groupId}</groupId>
35+
<artifactId>log4j-ecs-layout</artifactId>
36+
<version>${project.version}</version>
37+
<type>test-jar</type>
38+
<scope>test</scope>
39+
</dependency>
40+
<dependency>
41+
<groupId>log4j</groupId>
42+
<artifactId>log4j</artifactId>
43+
<version>1.2.4</version>
44+
<scope>test</scope>
45+
</dependency>
46+
</dependencies>
47+
</project>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*-
2+
* #%L
3+
* Java ECS logging
4+
* %%
5+
* Copyright (C) 2019 - 2020 Elastic and contributors
6+
* %%
7+
* Licensed to Elasticsearch B.V. under one or more contributor
8+
* license agreements. See the NOTICE file distributed with
9+
* this work for additional information regarding copyright
10+
* ownership. Elasticsearch B.V. licenses this file to you under
11+
* the Apache License, Version 2.0 (the "License"); you may
12+
* not use this file except in compliance with the License.
13+
* You may obtain a copy of the License at
14+
*
15+
* http://www.apache.org/licenses/LICENSE-2.0
16+
*
17+
* Unless required by applicable law or agreed to in writing,
18+
* software distributed under the License is distributed on an
19+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20+
* KIND, either express or implied. See the License for the
21+
* specific language governing permissions and limitations
22+
* under the License.
23+
* #L%
24+
*/
25+
package co.elastic.logging.log4j;
26+
27+
public class LegacyLog4jEcsLayoutTest extends Log4jEcsLayoutTest {
28+
}

log4j2-ecs-layout/src/main/java/co/elastic/logging/log4j2/MultiFormatHandler.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ static MultiFormatHandler resolve() {
4646
}
4747

4848
/**
49-
* For log4j2 >= 2.10
49+
* For log4j2 {@code >=} 2.10
5050
* Never reference directly in prod code so avoid linkage errors when {@link MultiFormatStringBuilderFormattable} is not available
5151
*/
5252
enum MultiFormatStringBuilderFormattableAware implements MultiFormatHandler {
@@ -64,7 +64,7 @@ public void formatJsonTo(MultiformatMessage message, StringBuilder builder) {
6464
}
6565

6666
/**
67-
* Fallback for log4j2 < 2.10
67+
* Fallback for log4j2 {@code <} 2.10
6868
*/
6969
enum ForLegacyLog4j implements MultiFormatHandler {
7070
INSTANCE;

log4j2-legacy-tests/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<properties>
1515
<version.log4j.legacy>2.6</version.log4j.legacy>
1616
<parent.base.dir>${project.basedir}/..</parent.base.dir>
17-
<maven-deploy-plugin.skip>false</maven-deploy-plugin.skip>
17+
<maven-deploy-plugin.skip>true</maven-deploy-plugin.skip>
1818
</properties>
1919

2020
<dependencies>

0 commit comments

Comments
 (0)