Skip to content

Commit a31881a

Browse files
committed
Add general ConfigurationExtension mechanism
We introduce a general `ConfigurationExtension` mechanism that would allow external Log4j plugins to add additional elements as children of the `<Configuration>` element. This mechanism is used to remove all direct references to async components in `AbstractConfiguration`. The `<AsyncWaitStrategyFactory>` configuration element is renamed to `<Disruptor>`, while maintaining backward compatibility.
1 parent 03f3aeb commit a31881a

File tree

15 files changed

+292
-213
lines changed

15 files changed

+292
-213
lines changed

log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,14 @@ public void testSingleFilterInvocation() {
101101
.setLevel(Level.INFO)
102102
.setFilter(filter)
103103
.build();
104+
config.initialize();
104105
final Appender appender = mock(Appender.class);
105106
when(appender.isStarted()).thenReturn(true);
106107
when(appender.getName()).thenReturn("test");
107108
config.addAppender(appender, null, null);
109+
final DisruptorConfiguration disruptorConfig = configuration.getExtension(DisruptorConfiguration.class);
108110
final AsyncLoggerConfigDisruptor disruptor =
109-
(AsyncLoggerConfigDisruptor) configuration.getAsyncLoggerConfigDelegate();
111+
(AsyncLoggerConfigDisruptor) disruptorConfig.getAsyncLoggerConfigDelegate();
110112
disruptor.start();
111113
try {
112114
config.log(FQCN, FQCN, null, Level.INFO, new SimpleMessage(), null);
Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,40 +16,34 @@
1616
*/
1717
package org.apache.logging.log4j.core.async;
1818

19+
import static org.assertj.core.api.Assertions.assertThat;
1920
import static org.junit.jupiter.api.Assertions.assertEquals;
20-
import static org.junit.jupiter.api.Assertions.assertNull;
21-
import static org.junit.jupiter.api.Assertions.assertTrue;
2221

23-
import org.apache.logging.log4j.LogManager;
2422
import org.apache.logging.log4j.core.LoggerContext;
25-
import org.apache.logging.log4j.core.impl.Log4jPropertyKey;
2623
import org.apache.logging.log4j.core.test.junit.ContextSelectorType;
24+
import org.apache.logging.log4j.core.test.junit.LoggerContextSource;
2725
import org.junit.jupiter.api.Tag;
2826
import org.junit.jupiter.api.Test;
29-
import org.junitpioneer.jupiter.SetSystemProperty;
3027

3128
@Tag("async")
3229
@ContextSelectorType(AsyncLoggerContextSelector.class)
33-
@SetSystemProperty(
34-
key = Log4jPropertyKey.Constant.CONFIG_LOCATION,
35-
value = "AsyncWaitStrategyIncorrectFactoryConfigGlobalLoggerTest.xml")
36-
public class AsyncWaitStrategyFactoryIncorrectConfigGlobalLoggersTest {
30+
@LoggerContextSource
31+
public class DisruptorConfigurationInvalidTest {
3732

3833
@Test
39-
public void testIncorrectConfigWaitStrategyFactory() throws Exception {
40-
final LoggerContext context = (LoggerContext) LogManager.getContext(false);
41-
assertTrue(context instanceof AsyncLoggerContext, "context is AsyncLoggerContext");
34+
public void testIncorrectConfigWaitStrategyFactory(final LoggerContext context) {
35+
assertThat(context).isInstanceOf(AsyncLoggerContext.class);
4236

43-
final AsyncWaitStrategyFactory asyncWaitStrategyFactory =
44-
context.getConfiguration().getAsyncWaitStrategyFactory();
45-
assertNull(asyncWaitStrategyFactory);
37+
final DisruptorConfiguration disruptorConfig =
38+
context.getConfiguration().getExtension(DisruptorConfiguration.class);
39+
assertThat(disruptorConfig).isNotNull();
40+
final AsyncWaitStrategyFactory asyncWaitStrategyFactory = disruptorConfig.getWaitStrategyFactory();
41+
assertThat(asyncWaitStrategyFactory).isNull();
4642

4743
final AsyncLogger logger = (AsyncLogger) context.getRootLogger();
4844
final AsyncLoggerDisruptor delegate = logger.getAsyncLoggerDisruptor();
4945
assertEquals(
5046
TimeoutBlockingWaitStrategy.class, delegate.getWaitStrategy().getClass());
51-
assertTrue(
52-
delegate.getWaitStrategy() instanceof TimeoutBlockingWaitStrategy,
53-
"waitstrategy is TimeoutBlockingWaitStrategy");
47+
assertThat(delegate.getWaitStrategy()).isInstanceOf(TimeoutBlockingWaitStrategy.class);
5448
}
5549
}
Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,29 @@
2828
import org.junit.jupiter.api.Test;
2929

3030
@Tag("async")
31-
public class AsyncWaitStrategyFactoryConfigTest {
31+
public class DisruptorConfigurationTest {
3232

3333
@Test
34-
@LoggerContextSource("AsyncWaitStrategyFactoryConfigTest.xml")
34+
void testAttributePriority() {
35+
final DisruptorConfiguration disruptorConfig = DisruptorConfiguration.newBuilder()
36+
.setFactoryClassName(DefaultAsyncWaitStrategyFactory.class.getName())
37+
.setWaitFactory(YieldingWaitStrategyFactory.class.getName())
38+
.build();
39+
assertThat(disruptorConfig.getWaitStrategyFactory()).isInstanceOf(YieldingWaitStrategyFactory.class);
40+
}
41+
42+
@Test
43+
@LoggerContextSource
3544
public void testConfigWaitStrategyFactory(final LoggerContext context) throws Exception {
36-
final AsyncWaitStrategyFactory asyncWaitStrategyFactory =
37-
context.getConfiguration().getAsyncWaitStrategyFactory();
45+
final DisruptorConfiguration disruptorConfig =
46+
context.getConfiguration().getExtension(DisruptorConfiguration.class);
47+
final AsyncWaitStrategyFactory asyncWaitStrategyFactory = disruptorConfig.getWaitStrategyFactory();
3848
assertThat(asyncWaitStrategyFactory.getClass()).isEqualTo(YieldingWaitStrategyFactory.class);
3949
assertThat(asyncWaitStrategyFactory).isInstanceOf(YieldingWaitStrategyFactory.class);
4050
}
4151

4252
@Test
43-
@LoggerContextSource("AsyncWaitStrategyFactoryConfigTest.xml")
53+
@LoggerContextSource
4454
public void testWaitStrategy(final LoggerContext context) throws Exception {
4555

4656
final org.apache.logging.log4j.Logger logger = context.getRootLogger();
@@ -56,8 +66,9 @@ public void testWaitStrategy(final LoggerContext context) throws Exception {
5666
@Test
5767
@LoggerContextSource("AsyncWaitStrategyIncorrectFactoryConfigTest.xml")
5868
public void testIncorrectConfigWaitStrategyFactory(final LoggerContext context) throws Exception {
59-
final AsyncWaitStrategyFactory asyncWaitStrategyFactory =
60-
context.getConfiguration().getAsyncWaitStrategyFactory();
69+
final DisruptorConfiguration disruptorConfig =
70+
context.getConfiguration().getExtension(DisruptorConfiguration.class);
71+
final AsyncWaitStrategyFactory asyncWaitStrategyFactory = disruptorConfig.getWaitStrategyFactory();
6172
assertThat(asyncWaitStrategyFactory).isNull(); // because invalid configuration
6273
}
6374

log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/QueueFullAbstractTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,9 @@ protected static void assertAsyncLoggerConfig(final LoggerContext ctx, final int
294294
final Configuration config = ctx.getConfiguration();
295295
assertThat(config).isNotNull();
296296
assertThat(config.getRootLogger()).isInstanceOf(AsyncLoggerConfig.class);
297-
final AsyncLoggerConfigDisruptor disruptor = (AsyncLoggerConfigDisruptor) config.getAsyncLoggerConfigDelegate();
297+
final DisruptorConfiguration disruptorConfig = config.getExtension(DisruptorConfiguration.class);
298+
final AsyncLoggerConfigDisruptor disruptor =
299+
(AsyncLoggerConfigDisruptor) disruptorConfig.getAsyncLoggerConfigDelegate();
298300
assertThat(disruptor.getRingBuffer().getBufferSize()).isEqualTo(expectedBufferSize);
299301
}
300302

log4j-core-test/src/test/resources/AsyncWaitStrategyIncorrectFactoryConfigGlobalLoggerTest.xml renamed to log4j-core-test/src/test/resources/org/apache/logging/log4j/core/async/DisruptorConfigurationInvalidTest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
~ See the License for the specific language governing permissions and
1616
~ limitations under the License.
1717
-->
18-
<Configuration name="asyncwait-global2">
18+
<Configuration name="AsyncWaitStrategyFactoryIncorrectConfigGlobalLoggerTest">
1919

2020
<AsyncWaitStrategyFactory
2121
class="nonexisting.Factory" />

log4j-core-test/src/test/resources/AsyncWaitStrategyFactoryConfigTest.xml renamed to log4j-core-test/src/test/resources/org/apache/logging/log4j/core/async/DisruptorConfigurationTest.xml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,7 @@
1515
~ See the License for the specific language governing permissions and
1616
~ limitations under the License.
1717
-->
18-
<Configuration name="async-wait-1" >
19-
20-
<AsyncWaitStrategyFactory
21-
class="org.apache.logging.log4j.core.async.AsyncWaitStrategyFactoryConfigTest$YieldingWaitStrategyFactory" />
22-
18+
<Configuration name="AsyncWaitStrategyFactoryConfigTest" >
2319
<Appenders>
2420
<List name="WaitStrategyAppenderList" />
2521
</Appenders>
@@ -29,4 +25,7 @@
2925
<AppenderRef ref="WaitStrategyAppenderList"/>
3026
</AsyncRoot>
3127
</Loggers>
28+
29+
<AsyncWaitStrategyFactory
30+
class="org.apache.logging.log4j.core.async.DisruptorConfigurationTest$YieldingWaitStrategyFactory" />
3231
</Configuration>

log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfig.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
public class AsyncLoggerConfig extends LoggerConfig {
6666

6767
private static final ThreadLocal<Boolean> ASYNC_LOGGER_ENTERED = ThreadLocal.withInitial(() -> Boolean.FALSE);
68-
private final AsyncLoggerConfigDelegate delegate;
68+
private AsyncLoggerConfigDelegate delegate;
6969

7070
@PluginFactory
7171
public static <B extends Builder<B>> B newAsyncBuilder() {
@@ -103,8 +103,19 @@ protected AsyncLoggerConfig(
103103
final boolean includeLocation,
104104
final LogEventFactory logEventFactory) {
105105
super(name, appenders, filter, level, additive, properties, config, includeLocation, logEventFactory);
106-
delegate = config.getAsyncLoggerConfigDelegate();
106+
}
107+
108+
@Override
109+
public void initialize() {
110+
final Configuration configuration = getConfiguration();
111+
DisruptorConfiguration disruptorConfig = configuration.getExtension(DisruptorConfiguration.class);
112+
if (disruptorConfig == null) {
113+
disruptorConfig = DisruptorConfiguration.newBuilder().build();
114+
configuration.addExtension(disruptorConfig);
115+
}
116+
delegate = disruptorConfig.getAsyncLoggerConfigDelegate();
107117
delegate.setLogEventFactory(getLogEventFactory());
118+
super.initialize();
108119
}
109120

110121
protected void log(final LogEvent event, final LoggerConfigPredicate predicate) {

log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerContext.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,20 +35,17 @@ public class AsyncLoggerContext extends LoggerContext {
3535

3636
public AsyncLoggerContext(final String name) {
3737
super(name);
38-
loggerDisruptor =
39-
new AsyncLoggerDisruptor(name, () -> getConfiguration().getAsyncWaitStrategyFactory());
38+
loggerDisruptor = new AsyncLoggerDisruptor(name, this::createAsyncWaitStrategyFactory);
4039
}
4140

4241
public AsyncLoggerContext(final String name, final Object externalContext) {
4342
super(name, externalContext);
44-
loggerDisruptor =
45-
new AsyncLoggerDisruptor(name, () -> getConfiguration().getAsyncWaitStrategyFactory());
43+
loggerDisruptor = new AsyncLoggerDisruptor(name, this::createAsyncWaitStrategyFactory);
4644
}
4745

4846
public AsyncLoggerContext(final String name, final Object externalContext, final URI configLocn) {
4947
super(name, externalContext, configLocn);
50-
loggerDisruptor =
51-
new AsyncLoggerDisruptor(name, () -> getConfiguration().getAsyncWaitStrategyFactory());
48+
loggerDisruptor = new AsyncLoggerDisruptor(name, this::createAsyncWaitStrategyFactory);
5249
}
5350

5451
public AsyncLoggerContext(
@@ -57,14 +54,12 @@ public AsyncLoggerContext(
5754
final URI configLocn,
5855
final ConfigurableInstanceFactory instanceFactory) {
5956
super(name, externalContext, configLocn, instanceFactory);
60-
loggerDisruptor =
61-
new AsyncLoggerDisruptor(name, () -> getConfiguration().getAsyncWaitStrategyFactory());
57+
loggerDisruptor = new AsyncLoggerDisruptor(name, this::createAsyncWaitStrategyFactory);
6258
}
6359

6460
public AsyncLoggerContext(final String name, final Object externalContext, final String configLocn) {
6561
super(name, externalContext, configLocn);
66-
loggerDisruptor =
67-
new AsyncLoggerDisruptor(name, () -> getConfiguration().getAsyncWaitStrategyFactory());
62+
loggerDisruptor = new AsyncLoggerDisruptor(name, this::createAsyncWaitStrategyFactory);
6863
}
6964

7065
public AsyncLoggerContext(
@@ -73,8 +68,13 @@ public AsyncLoggerContext(
7368
final String configLocn,
7469
final ConfigurableInstanceFactory instanceFactory) {
7570
super(name, externalContext, configLocn, instanceFactory);
76-
loggerDisruptor =
77-
new AsyncLoggerDisruptor(name, () -> getConfiguration().getAsyncWaitStrategyFactory());
71+
loggerDisruptor = new AsyncLoggerDisruptor(name, this::createAsyncWaitStrategyFactory);
72+
}
73+
74+
private AsyncWaitStrategyFactory createAsyncWaitStrategyFactory() {
75+
final DisruptorConfiguration disruptorConfiguration =
76+
getConfiguration().getExtension(DisruptorConfiguration.class);
77+
return disruptorConfiguration != null ? disruptorConfiguration.getWaitStrategyFactory() : null;
7878
}
7979

8080
@Override

log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncWaitStrategyFactoryConfig.java

Lines changed: 0 additions & 102 deletions
This file was deleted.

0 commit comments

Comments
 (0)