Skip to content

Commit ce46f2e

Browse files
committed
Merge remote-tracking branch 'apache/2.x' into feature/2.x/change-is-webapp
2 parents 51d0fb3 + 3236a0c commit ce46f2e

File tree

15 files changed

+335
-55
lines changed

15 files changed

+335
-55
lines changed

.github/workflows/build.yaml

+3-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ jobs:
3838

3939
build:
4040
if: github.actor != 'dependabot[bot]'
41-
uses: apache/logging-parent/.github/workflows/build-reusable.yaml@rel/11.0.0
41+
# Temporary switch to `@fix/macos-java-8` to see how the situation evolves with macOS runners
42+
uses: apache/logging-parent/.github/workflows/build-reusable.yaml@fix/macos-java-8
43+
# uses: apache/logging-parent/.github/workflows/build-reusable.yaml@rel/11.0.0
4244
with:
4345
java-version: |
4446
8

log4j-api/pom.xml

+10-2
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,25 @@
1616
~ limitations under the License.
1717
-->
1818
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
19+
1920
<modelVersion>4.0.0</modelVersion>
21+
2022
<parent>
2123
<groupId>org.apache.logging.log4j</groupId>
2224
<artifactId>log4j</artifactId>
2325
<version>${revision}</version>
2426
<relativePath>../log4j-parent</relativePath>
2527
</parent>
28+
2629
<artifactId>log4j-api</artifactId>
27-
<packaging>jar</packaging>
30+
2831
<name>Apache Log4j API</name>
29-
<description>The Apache Log4j API</description>
32+
33+
<description>The logging API of the Log4j project.
34+
Library and application code can log against this API.
35+
It contains a simple built-in implementation (`SimpleLogger`) for trivial use cases.
36+
Production applications are recommended to use it in combination with a fully-fledged implementation, such as Log4j Core.</description>
37+
3038
<properties>
3139
<maven.javadoc.skip>false</maven.javadoc.skip>
3240

log4j-api/src/main/java/org/apache/logging/log4j/message/ParameterFormatter.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ private static boolean appendDate(final Object o, final StringBuilder str) {
459459
if (!(o instanceof Date)) {
460460
return false;
461461
}
462-
str.append(DATE_FORMATTER.format(((Date) o).toInstant()));
462+
DATE_FORMATTER.formatTo(((Date) o).toInstant(), str);
463463
return true;
464464
}
465465

log4j-api/src/main/java/org/apache/logging/log4j/spi/AbstractLogger.java

+37-29
Original file line numberDiff line numberDiff line change
@@ -106,34 +106,57 @@ public abstract class AbstractLogger implements ExtendedLogger, LocationAwareLog
106106
private static final ThreadLocal<DefaultLogBuilder> logBuilder = ThreadLocal.withInitial(DefaultLogBuilder::new);
107107

108108
/**
109-
* Creates a new logger named after this class (or subclass).
109+
* Constructs an instance named after this class.
110110
*/
111111
public AbstractLogger() {
112-
final String canonicalName = getClass().getCanonicalName();
113-
this.name = canonicalName != null ? canonicalName : getClass().getName();
114-
this.messageFactory = createDefaultMessageFactory();
115-
this.flowMessageFactory = createDefaultFlowMessageFactory();
112+
this(null, null, null);
116113
}
117114

118115
/**
119-
* Creates a new named logger.
116+
* Constructs an instance using the provided name.
120117
*
121-
* @param name the logger name
118+
* @param name the logger name (if null, will be derived from this class or subclass)
122119
*/
123120
public AbstractLogger(final String name) {
124-
this(name, createDefaultMessageFactory());
121+
this(name, null, null);
125122
}
126123

127124
/**
128-
* Creates a new named logger with a particular {@link MessageFactory}.
125+
* Constructs an instance using the provided name and {@link MessageFactory}.
129126
*
130-
* @param name the logger name
131-
* @param messageFactory the message factory, if null then use the default message factory.
127+
* @param name the logger name (if null, will be derived from this class)
128+
* @param messageFactory the {@link Message} factory (if null, {@link ParameterizedMessageFactory} will be used)
132129
*/
133130
public AbstractLogger(final String name, final MessageFactory messageFactory) {
134-
this.name = name;
135-
this.messageFactory = messageFactory == null ? createDefaultMessageFactory() : narrow(messageFactory);
136-
this.flowMessageFactory = createDefaultFlowMessageFactory();
131+
this(name, messageFactory, null);
132+
}
133+
134+
/**
135+
* The canonical constructor.
136+
*
137+
* @param name the logger name (if null, will be derived from this class)
138+
* @param messageFactory the {@link Message} factory (if null, {@link ParameterizedMessageFactory} will be used)
139+
* @param flowMessageFactory the {@link org.apache.logging.log4j.message.FlowMessage} factory (if null, {@link DefaultFlowMessageFactory} will be used)
140+
*/
141+
protected AbstractLogger(
142+
final String name, final MessageFactory messageFactory, final FlowMessageFactory flowMessageFactory) {
143+
if (name != null) {
144+
this.name = name;
145+
} else {
146+
final Class<? extends AbstractLogger> clazz = getClass();
147+
final String canonicalName = clazz.getCanonicalName();
148+
this.name = canonicalName != null ? canonicalName : clazz.getName();
149+
}
150+
this.messageFactory =
151+
messageFactory != null ? adaptMessageFactory(messageFactory) : ParameterizedMessageFactory.INSTANCE;
152+
this.flowMessageFactory = flowMessageFactory != null ? flowMessageFactory : DefaultFlowMessageFactory.INSTANCE;
153+
}
154+
155+
private static MessageFactory2 adaptMessageFactory(final MessageFactory result) {
156+
if (result instanceof MessageFactory2) {
157+
return (MessageFactory2) result;
158+
}
159+
return new MessageFactory2Adapter(result);
137160
}
138161

139162
/**
@@ -196,21 +219,6 @@ protected Message catchingMsg(final Throwable throwable) {
196219
return messageFactory.newMessage(CATCHING);
197220
}
198221

199-
private static MessageFactory2 createDefaultMessageFactory() {
200-
return ParameterizedMessageFactory.INSTANCE;
201-
}
202-
203-
private static MessageFactory2 narrow(final MessageFactory result) {
204-
if (result instanceof MessageFactory2) {
205-
return (MessageFactory2) result;
206-
}
207-
return new MessageFactory2Adapter(result);
208-
}
209-
210-
private static FlowMessageFactory createDefaultFlowMessageFactory() {
211-
return DefaultFlowMessageFactory.INSTANCE;
212-
}
213-
214222
@Override
215223
public void debug(final Marker marker, final CharSequence message) {
216224
logIfEnabled(FQCN, Level.DEBUG, marker, message, null);

log4j-api/src/main/java/org/apache/logging/log4j/status/StatusData.java

+3-5
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ public class StatusData implements Serializable {
3838

3939
private final Instant instant;
4040

41-
@Nullable
4241
private final DateTimeFormatter instantFormatter;
4342

4443
@Nullable
@@ -79,7 +78,8 @@ public StatusData(
7978
@Nullable final String threadName,
8079
@Nullable final DateTimeFormatter instantFormatter,
8180
final Instant instant) {
82-
this.instantFormatter = instantFormatter;
81+
// DateTimeFormatter.ISO_INSTANT is the default used in instant.toString()
82+
this.instantFormatter = instantFormatter != null ? instantFormatter : DateTimeFormatter.ISO_INSTANT;
8383
this.instant = instant;
8484
this.caller = caller;
8585
this.level = requireNonNull(level, "level");
@@ -167,9 +167,7 @@ public Throwable getThrowable() {
167167
@SuppressWarnings("DefaultCharset")
168168
public String getFormattedStatus() {
169169
final StringBuilder sb = new StringBuilder();
170-
final String formattedInstant =
171-
instantFormatter != null ? instantFormatter.format(instant) : instant.toString();
172-
sb.append(formattedInstant);
170+
instantFormatter.formatTo(instant, sb);
173171
sb.append(SPACE);
174172
sb.append(getThreadName());
175173
sb.append(SPACE);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to you under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.logging.log4j.core;
18+
19+
import static org.assertj.core.api.Assertions.assertThat;
20+
21+
import org.apache.logging.log4j.message.AbstractMessageFactory;
22+
import org.apache.logging.log4j.message.DefaultFlowMessageFactory;
23+
import org.apache.logging.log4j.message.Message;
24+
import org.apache.logging.log4j.message.MessageFactory;
25+
import org.apache.logging.log4j.message.ParameterizedMessageFactory;
26+
import org.junit.jupiter.api.Test;
27+
import org.junitpioneer.jupiter.ClearSystemProperty;
28+
import org.junitpioneer.jupiter.SetSystemProperty;
29+
30+
class LoggerMessageFactoryCustomizationTest {
31+
32+
@Test
33+
@ClearSystemProperty(key = "log4j2.messageFactory")
34+
@ClearSystemProperty(key = "log4j2.flowMessageFactory")
35+
void arguments_should_be_honored() {
36+
final LoggerContext loggerContext =
37+
new LoggerContext(LoggerMessageFactoryCustomizationTest.class.getSimpleName());
38+
final Logger logger = new Logger(
39+
loggerContext, "arguments_should_be_honored", new TestMessageFactory(), new TestFlowMessageFactory());
40+
assertTestMessageFactories(logger);
41+
}
42+
43+
@Test
44+
@SetSystemProperty(
45+
key = "log4j2.messageFactory",
46+
value = "org.apache.logging.log4j.core.LoggerMessageFactoryCustomizationTest$TestMessageFactory")
47+
@SetSystemProperty(
48+
key = "log4j2.flowMessageFactory",
49+
value = "org.apache.logging.log4j.core.LoggerMessageFactoryCustomizationTest$TestFlowMessageFactory")
50+
void properties_should_be_honored() {
51+
final LoggerContext loggerContext =
52+
new LoggerContext(LoggerMessageFactoryCustomizationTest.class.getSimpleName());
53+
final Logger logger = new Logger(loggerContext, "properties_should_be_honored", null, null);
54+
assertTestMessageFactories(logger);
55+
}
56+
57+
private static void assertTestMessageFactories(Logger logger) {
58+
assertThat((MessageFactory) logger.getMessageFactory()).isInstanceOf(TestMessageFactory.class);
59+
assertThat(logger.getFlowMessageFactory()).isInstanceOf(TestFlowMessageFactory.class);
60+
}
61+
62+
public static final class TestMessageFactory extends AbstractMessageFactory {
63+
64+
@Override
65+
public Message newMessage(final String message, final Object... params) {
66+
return ParameterizedMessageFactory.INSTANCE.newMessage(message, params);
67+
}
68+
}
69+
70+
public static final class TestFlowMessageFactory extends DefaultFlowMessageFactory {}
71+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to you under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.logging.log4j.core;
18+
19+
import static org.assertj.core.api.Assertions.assertThat;
20+
21+
import org.apache.logging.log4j.core.util.Constants;
22+
import org.apache.logging.log4j.message.DefaultFlowMessageFactory;
23+
import org.apache.logging.log4j.message.MessageFactory;
24+
import org.apache.logging.log4j.message.ParameterizedMessageFactory;
25+
import org.junit.jupiter.api.Test;
26+
import org.junitpioneer.jupiter.SetSystemProperty;
27+
28+
class LoggerMessageFactoryDefaultsTlaDisabledTest {
29+
30+
@Test
31+
@SetSystemProperty(key = "log4j2.enableThreadLocals", value = "false")
32+
void defaults_should_match_when_thread_locals_disabled() {
33+
assertThat(Constants.ENABLE_THREADLOCALS).isFalse();
34+
final LoggerContext loggerContext =
35+
new LoggerContext(LoggerMessageFactoryDefaultsTlaDisabledTest.class.getSimpleName());
36+
final Logger logger =
37+
new Logger(loggerContext, "defaults_should_match_when_thread_locals_disabled", null, null);
38+
assertThat((MessageFactory) logger.getMessageFactory()).isSameAs(ParameterizedMessageFactory.INSTANCE);
39+
assertThat(logger.getFlowMessageFactory()).isSameAs(DefaultFlowMessageFactory.INSTANCE);
40+
}
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to you under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.logging.log4j.core;
18+
19+
import static org.assertj.core.api.Assertions.assertThat;
20+
21+
import org.apache.logging.log4j.core.util.Constants;
22+
import org.apache.logging.log4j.message.DefaultFlowMessageFactory;
23+
import org.apache.logging.log4j.message.MessageFactory;
24+
import org.apache.logging.log4j.message.ReusableMessageFactory;
25+
import org.junit.jupiter.api.Test;
26+
import org.junitpioneer.jupiter.SetSystemProperty;
27+
28+
class LoggerMessageFactoryDefaultsTlaEnabledTest {
29+
30+
@Test
31+
@SetSystemProperty(key = "log4j2.is.webapp", value = "false")
32+
@SetSystemProperty(key = "log4j2.enableThreadLocals", value = "true")
33+
void defaults_should_match_when_thread_locals_enabled() {
34+
assertThat(Constants.ENABLE_THREADLOCALS).isTrue();
35+
final LoggerContext loggerContext =
36+
new LoggerContext(LoggerMessageFactoryDefaultsTlaEnabledTest.class.getSimpleName());
37+
final Logger logger = new Logger(loggerContext, "defaults_should_match_when_thread_locals_enabled", null, null);
38+
assertThat((MessageFactory) logger.getMessageFactory()).isSameAs(ReusableMessageFactory.INSTANCE);
39+
assertThat(logger.getFlowMessageFactory()).isSameAs(DefaultFlowMessageFactory.INSTANCE);
40+
}
41+
}

log4j-core/pom.xml

+7-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,13 @@
2929
<artifactId>log4j-core</artifactId>
3030

3131
<name>Apache Log4j Core</name>
32-
<description>The Apache Log4j Implementation</description>
32+
33+
<description>A versatile, industrial-grade, and reference implementation of the Log4j API.
34+
It bundles a rich set of components to assist various use cases:
35+
Appenders targeting files, network sockets, databases, SMTP servers;
36+
Layouts that can render CSV, HTML, JSON, Syslog, etc. formatted outputs;
37+
Filters that can be configured using log event rates, regular expressions, scripts, time; etc.
38+
It contains several extension points to introduce custom components, if needed.</description>
3339

3440
<properties>
3541

0 commit comments

Comments
 (0)