From dcd09d25094e7515e14437eedb4c525ca7d2a93e Mon Sep 17 00:00:00 2001 From: hojooo Date: Tue, 2 Dec 2025 23:16:01 +0900 Subject: [PATCH] Change SpringBootTriggeringPolicy to Abstract Class Signed-off-by: hojooo --- .../log4j2/SpringBootTriggeringPolicy.java | 90 +++---------------- .../boot/logging/log4j2/log4j2-file.xml | 4 +- .../log4j2/Log4J2LoggingSystemTests.java | 42 ++++----- 3 files changed, 30 insertions(+), 106 deletions(-) diff --git a/core/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/SpringBootTriggeringPolicy.java b/core/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/SpringBootTriggeringPolicy.java index d23692d8864..35383b1ae34 100644 --- a/core/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/SpringBootTriggeringPolicy.java +++ b/core/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/SpringBootTriggeringPolicy.java @@ -16,12 +16,7 @@ package org.springframework.boot.logging.log4j2; -import java.util.concurrent.TimeUnit; - -import org.apache.logging.log4j.core.LifeCycle; -import org.apache.logging.log4j.core.LifeCycle2; import org.apache.logging.log4j.core.LogEvent; -import org.apache.logging.log4j.core.appender.rolling.AbstractTriggeringPolicy; import org.apache.logging.log4j.core.appender.rolling.CompositeTriggeringPolicy; import org.apache.logging.log4j.core.appender.rolling.CronTriggeringPolicy; import org.apache.logging.log4j.core.appender.rolling.RollingFileManager; @@ -34,78 +29,34 @@ import org.apache.logging.log4j.core.config.plugins.Plugin; import org.apache.logging.log4j.core.config.plugins.PluginAttribute; import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory; import org.apache.logging.log4j.core.config.plugins.PluginConfiguration; -import org.apache.logging.log4j.core.config.plugins.PluginFactory; import org.apache.logging.log4j.core.util.Builder; import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; /** - * {@link TriggeringPolicy} that selects one of several standard Log4j2 - * {@link TriggeringPolicy TriggeringPolicies} based on configuration attributes. The - * supported strategies are {@code size}, {@code time}, {@code size-and-time}, and - * {@code cron}. + * Factory for creating a standard Log4j2 {@link TriggeringPolicy} based on configuration + * attributes. The supported strategies are {@code size}, {@code time}, + * {@code size-and-time}, and {@code cron}. * * @author HoJoo Moon * @since 4.0.0 */ @Plugin(name = "SpringBootTriggeringPolicy", category = Node.CATEGORY, elementType = "TriggeringPolicy", deferChildren = true, printObject = true) -public final class SpringBootTriggeringPolicy extends AbstractTriggeringPolicy { - - private final TriggeringPolicy delegate; - - private SpringBootTriggeringPolicy(TriggeringPolicy delegate) { - this.delegate = delegate; - } +public abstract class SpringBootTriggeringPolicy implements TriggeringPolicy { - TriggeringPolicy getDelegate() { - return this.delegate; + private SpringBootTriggeringPolicy() { } @Override public void initialize(RollingFileManager manager) { - this.delegate.initialize(manager); - } - - @Override - public boolean isTriggeringEvent(LogEvent event) { - return this.delegate.isTriggeringEvent(event); - } - - @Override - public void start() { - super.start(); - if (this.delegate instanceof LifeCycle lifecycle) { - lifecycle.start(); - } + throw new UnsupportedOperationException("This class should not be instantiated"); } @Override - public boolean stop(long timeout, TimeUnit timeUnit) { - setStopping(); - boolean result = true; - if (this.delegate instanceof LifeCycle2 lifecycle2) { - result = lifecycle2.stop(timeout, timeUnit); - } - else if (this.delegate instanceof LifeCycle lifecycle) { - lifecycle.stop(); - } - setStopped(); - return result; - } - - @Override - public boolean isStarted() { - if (this.delegate instanceof LifeCycle lifecycle) { - return lifecycle.isStarted(); - } - return super.isStarted(); - } - - @Override - public String toString() { - return "SpringBootTriggeringPolicy{" + this.delegate + "}"; + public boolean isTriggeringEvent(LogEvent logEvent) { + throw new UnsupportedOperationException("This class should not be instantiated"); } @PluginBuilderFactory @@ -113,26 +64,10 @@ public final class SpringBootTriggeringPolicy extends AbstractTriggeringPolicy { return new SpringBootTriggeringPolicyBuilder(); } - @PluginFactory - public static SpringBootTriggeringPolicy createPolicy(@PluginAttribute("strategy") @Nullable String strategy, - @PluginAttribute("maxFileSize") @Nullable String maxFileSize, - @PluginAttribute("timeInterval") @Nullable Integer timeInterval, - @PluginAttribute("timeModulate") @Nullable Boolean timeModulate, - @PluginAttribute("cronExpression") @Nullable String cronExpression, - @PluginConfiguration Configuration configuration) { - return newBuilder().setStrategy(strategy) - .setMaxFileSize(maxFileSize) - .setTimeInterval(timeInterval) - .setTimeModulate(timeModulate) - .setCronExpression(cronExpression) - .setConfiguration(configuration) - .build(); - } - /** - * Builder for {@link SpringBootTriggeringPolicy}. + * Builder for creating a {@link TriggeringPolicy}. */ - public static class SpringBootTriggeringPolicyBuilder implements Builder { + public static class SpringBootTriggeringPolicyBuilder implements Builder { private static final String DEFAULT_STRATEGY = "size"; @@ -161,13 +96,13 @@ public final class SpringBootTriggeringPolicy extends AbstractTriggeringPolicy { private @Nullable Configuration configuration; @Override - public SpringBootTriggeringPolicy build() { + public TriggeringPolicy build() { // Read strategy from system properties first, then from attributes String resolvedStrategy = System.getProperty("LOG4J2_ROLLINGPOLICY_STRATEGY"); if (resolvedStrategy == null) { resolvedStrategy = (this.strategy != null) ? this.strategy : DEFAULT_STRATEGY; } - TriggeringPolicy policy = switch (resolvedStrategy) { + return switch (resolvedStrategy) { case "time" -> createTimePolicy(); case "size-and-time" -> CompositeTriggeringPolicy.createPolicy(createSizePolicy(), createTimePolicy()); case "cron" -> createCronPolicy(); @@ -175,7 +110,6 @@ public final class SpringBootTriggeringPolicy extends AbstractTriggeringPolicy { default -> throw new IllegalArgumentException( "Unsupported rolling policy strategy '%s'".formatted(resolvedStrategy)); }; - return new SpringBootTriggeringPolicy(policy); } private TriggeringPolicy createSizePolicy() { diff --git a/core/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2-file.xml b/core/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2-file.xml index a9cbcd0cbc7..73e2b224048 100644 --- a/core/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2-file.xml +++ b/core/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2-file.xml @@ -41,9 +41,7 @@ timeModulate="${sys:LOG4J2_ROLLINGPOLICY_TIME_MODULATE:-false}" cronExpression="${sys:LOG4J2_ROLLINGPOLICY_CRON_SCHEDULE}"/> - + diff --git a/core/spring-boot/src/test/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystemTests.java b/core/spring-boot/src/test/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystemTests.java index 4cb3ae2d003..19a5357a87b 100644 --- a/core/spring-boot/src/test/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystemTests.java +++ b/core/spring-boot/src/test/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystemTests.java @@ -820,10 +820,9 @@ class Log4J2LoggingSystemTests extends AbstractLoggingSystemTests { void rollingPolicyTimeStrategyIsApplied() { this.environment.setProperty("logging.log4j2.rollingpolicy.strategy", "time"); this.environment.setProperty("logging.log4j2.rollingpolicy.time-based.interval", "2"); - SpringBootTriggeringPolicy policy = getTriggeringPolicy(); - TriggeringPolicy delegate = policy.getDelegate(); - assertThat(delegate).isInstanceOf(TimeBasedTriggeringPolicy.class); - TimeBasedTriggeringPolicy timePolicy = (TimeBasedTriggeringPolicy) delegate; + TriggeringPolicy policy = getTriggeringPolicy(); + TimeBasedTriggeringPolicy timePolicy = findPolicy(policy, TimeBasedTriggeringPolicy.class); + assertThat(timePolicy).isNotNull(); assertThat(timePolicy.getInterval()).isEqualTo(2); } @@ -832,49 +831,42 @@ class Log4J2LoggingSystemTests extends AbstractLoggingSystemTests { this.environment.setProperty("logging.log4j2.rollingpolicy.strategy", "size-and-time"); this.environment.setProperty("logging.log4j2.rollingpolicy.max-file-size", "5MB"); this.environment.setProperty("logging.log4j2.rollingpolicy.time-based.interval", "3"); - SpringBootTriggeringPolicy policy = getTriggeringPolicy(); - TriggeringPolicy delegate = policy.getDelegate(); - assertThat(delegate).isInstanceOf(CompositeTriggeringPolicy.class); - CompositeTriggeringPolicy composite = (CompositeTriggeringPolicy) delegate; - TriggeringPolicy[] policies = composite.getTriggeringPolicies(); - assertThat(policies).anyMatch(TimeBasedTriggeringPolicy.class::isInstance); - assertThat(policies).anyMatch(SizeBasedTriggeringPolicy.class::isInstance); + TriggeringPolicy policy = getTriggeringPolicy(); + assertThat(findPolicy(policy, TimeBasedTriggeringPolicy.class)).isNotNull(); + assertThat(findPolicy(policy, SizeBasedTriggeringPolicy.class)).isNotNull(); } @Test void rollingPolicyCronStrategyIsApplied() { this.environment.setProperty("logging.log4j2.rollingpolicy.strategy", "cron"); this.environment.setProperty("logging.log4j2.rollingpolicy.cron.schedule", "0 0 0 * * ?"); - SpringBootTriggeringPolicy policy = getTriggeringPolicy(); - TriggeringPolicy delegate = policy.getDelegate(); - assertThat(delegate).isInstanceOf(CronTriggeringPolicy.class); - CronTriggeringPolicy cronPolicy = (CronTriggeringPolicy) delegate; + TriggeringPolicy policy = getTriggeringPolicy(); + CronTriggeringPolicy cronPolicy = findPolicy(policy, CronTriggeringPolicy.class); + assertThat(cronPolicy).isNotNull(); assertThat(cronPolicy.getCronExpression().getCronExpression()).isEqualTo("0 0 0 * * ?"); } - private SpringBootTriggeringPolicy getTriggeringPolicy() { + private TriggeringPolicy getTriggeringPolicy() { File file = new File(tmpDir(), "target-file.log"); LogFile logFile = getLogFile(file.getPath(), null); this.loggingSystem.beforeInitialize(); this.loggingSystem.initialize(this.initializationContext, "classpath:org/springframework/boot/logging/log4j2/log4j2-file.xml", logFile); - LoggerContext loggerContext = (LoggerContext) LogManager.getContext(false); + LoggerContext loggerContext = this.loggingSystem.getLoggerContext(); Configuration configuration = loggerContext.getConfiguration(); RollingFileAppender appender = (RollingFileAppender) configuration.getAppenders().get("File"); assertThat(appender).isNotNull(); - TriggeringPolicy topPolicy = appender.getManager().getTriggeringPolicy(); - SpringBootTriggeringPolicy policy = findSpringBootTriggeringPolicy(topPolicy); - assertThat(policy).isNotNull(); - return policy; + return appender.getManager().getTriggeringPolicy(); } - private @Nullable SpringBootTriggeringPolicy findSpringBootTriggeringPolicy(TriggeringPolicy policy) { - if (policy instanceof SpringBootTriggeringPolicy springBoot) { - return springBoot; + @SuppressWarnings("unchecked") + private @Nullable T findPolicy(TriggeringPolicy policy, Class type) { + if (type.isInstance(policy)) { + return (T) policy; } if (policy instanceof CompositeTriggeringPolicy composite) { for (TriggeringPolicy child : composite.getTriggeringPolicies()) { - SpringBootTriggeringPolicy found = findSpringBootTriggeringPolicy(child); + T found = findPolicy(child, type); if (found != null) { return found; }