Browse Source

Change SpringBootTriggeringPolicy to Abstract Class

Signed-off-by: hojooo <ghwn5833@gmail.com>
pull/47260/head
hojooo 2 weeks ago
parent
commit
dcd09d2509
  1. 90
      core/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/SpringBootTriggeringPolicy.java
  2. 4
      core/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2-file.xml
  3. 42
      core/spring-boot/src/test/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystemTests.java

90
core/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/SpringBootTriggeringPolicy.java

@ -16,12 +16,7 @@
package org.springframework.boot.logging.log4j2; 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.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.CompositeTriggeringPolicy;
import org.apache.logging.log4j.core.appender.rolling.CronTriggeringPolicy; import org.apache.logging.log4j.core.appender.rolling.CronTriggeringPolicy;
import org.apache.logging.log4j.core.appender.rolling.RollingFileManager; 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.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory; 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.PluginConfiguration;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.util.Builder; import org.apache.logging.log4j.core.util.Builder;
import org.jspecify.annotations.Nullable; import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
* {@link TriggeringPolicy} that selects one of several standard Log4j2 * Factory for creating a standard Log4j2 {@link TriggeringPolicy} based on configuration
* {@link TriggeringPolicy TriggeringPolicies} based on configuration attributes. The * attributes. The supported strategies are {@code size}, {@code time},
* supported strategies are {@code size}, {@code time}, {@code size-and-time}, and * {@code size-and-time}, and {@code cron}.
* {@code cron}.
* *
* @author HoJoo Moon * @author HoJoo Moon
* @since 4.0.0 * @since 4.0.0
*/ */
@Plugin(name = "SpringBootTriggeringPolicy", category = Node.CATEGORY, elementType = "TriggeringPolicy", @Plugin(name = "SpringBootTriggeringPolicy", category = Node.CATEGORY, elementType = "TriggeringPolicy",
deferChildren = true, printObject = true) deferChildren = true, printObject = true)
public final class SpringBootTriggeringPolicy extends AbstractTriggeringPolicy { public abstract class SpringBootTriggeringPolicy implements TriggeringPolicy {
private final TriggeringPolicy delegate;
private SpringBootTriggeringPolicy(TriggeringPolicy delegate) {
this.delegate = delegate;
}
TriggeringPolicy getDelegate() { private SpringBootTriggeringPolicy() {
return this.delegate;
} }
@Override @Override
public void initialize(RollingFileManager manager) { public void initialize(RollingFileManager manager) {
this.delegate.initialize(manager); throw new UnsupportedOperationException("This class should not be instantiated");
}
@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();
}
} }
@Override @Override
public boolean stop(long timeout, TimeUnit timeUnit) { public boolean isTriggeringEvent(LogEvent logEvent) {
setStopping(); throw new UnsupportedOperationException("This class should not be instantiated");
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 + "}";
} }
@PluginBuilderFactory @PluginBuilderFactory
@ -113,26 +64,10 @@ public final class SpringBootTriggeringPolicy extends AbstractTriggeringPolicy {
return new SpringBootTriggeringPolicyBuilder(); 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<SpringBootTriggeringPolicy> { public static class SpringBootTriggeringPolicyBuilder implements Builder<TriggeringPolicy> {
private static final String DEFAULT_STRATEGY = "size"; private static final String DEFAULT_STRATEGY = "size";
@ -161,13 +96,13 @@ public final class SpringBootTriggeringPolicy extends AbstractTriggeringPolicy {
private @Nullable Configuration configuration; private @Nullable Configuration configuration;
@Override @Override
public SpringBootTriggeringPolicy build() { public TriggeringPolicy build() {
// Read strategy from system properties first, then from attributes // Read strategy from system properties first, then from attributes
String resolvedStrategy = System.getProperty("LOG4J2_ROLLINGPOLICY_STRATEGY"); String resolvedStrategy = System.getProperty("LOG4J2_ROLLINGPOLICY_STRATEGY");
if (resolvedStrategy == null) { if (resolvedStrategy == null) {
resolvedStrategy = (this.strategy != null) ? this.strategy : DEFAULT_STRATEGY; resolvedStrategy = (this.strategy != null) ? this.strategy : DEFAULT_STRATEGY;
} }
TriggeringPolicy policy = switch (resolvedStrategy) { return switch (resolvedStrategy) {
case "time" -> createTimePolicy(); case "time" -> createTimePolicy();
case "size-and-time" -> CompositeTriggeringPolicy.createPolicy(createSizePolicy(), createTimePolicy()); case "size-and-time" -> CompositeTriggeringPolicy.createPolicy(createSizePolicy(), createTimePolicy());
case "cron" -> createCronPolicy(); case "cron" -> createCronPolicy();
@ -175,7 +110,6 @@ public final class SpringBootTriggeringPolicy extends AbstractTriggeringPolicy {
default -> throw new IllegalArgumentException( default -> throw new IllegalArgumentException(
"Unsupported rolling policy strategy '%s'".formatted(resolvedStrategy)); "Unsupported rolling policy strategy '%s'".formatted(resolvedStrategy));
}; };
return new SpringBootTriggeringPolicy(policy);
} }
private TriggeringPolicy createSizePolicy() { private TriggeringPolicy createSizePolicy() {

4
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}" timeModulate="${sys:LOG4J2_ROLLINGPOLICY_TIME_MODULATE:-false}"
cronExpression="${sys:LOG4J2_ROLLINGPOLICY_CRON_SCHEDULE}"/> cronExpression="${sys:LOG4J2_ROLLINGPOLICY_CRON_SCHEDULE}"/>
</Policies> </Policies>
<DefaultRolloverStrategy max="${sys:LOG4J2_ROLLINGPOLICY_MAX_HISTORY:-7}" <DefaultRolloverStrategy max="${sys:LOG4J2_ROLLINGPOLICY_MAX_HISTORY:-7}"/>
cleanHistoryOnStart="${sys:LOG4J2_ROLLINGPOLICY_CLEAN_HISTORY_ON_START:-false}"
totalSizeCap="${sys:LOG4J2_ROLLINGPOLICY_TOTAL_SIZE_CAP:-0}"/>
</RollingFile> </RollingFile>
</Appenders> </Appenders>
<Loggers> <Loggers>

42
core/spring-boot/src/test/java/org/springframework/boot/logging/log4j2/Log4J2LoggingSystemTests.java

@ -820,10 +820,9 @@ class Log4J2LoggingSystemTests extends AbstractLoggingSystemTests {
void rollingPolicyTimeStrategyIsApplied() { void rollingPolicyTimeStrategyIsApplied() {
this.environment.setProperty("logging.log4j2.rollingpolicy.strategy", "time"); this.environment.setProperty("logging.log4j2.rollingpolicy.strategy", "time");
this.environment.setProperty("logging.log4j2.rollingpolicy.time-based.interval", "2"); this.environment.setProperty("logging.log4j2.rollingpolicy.time-based.interval", "2");
SpringBootTriggeringPolicy policy = getTriggeringPolicy(); TriggeringPolicy policy = getTriggeringPolicy();
TriggeringPolicy delegate = policy.getDelegate(); TimeBasedTriggeringPolicy timePolicy = findPolicy(policy, TimeBasedTriggeringPolicy.class);
assertThat(delegate).isInstanceOf(TimeBasedTriggeringPolicy.class); assertThat(timePolicy).isNotNull();
TimeBasedTriggeringPolicy timePolicy = (TimeBasedTriggeringPolicy) delegate;
assertThat(timePolicy.getInterval()).isEqualTo(2); 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.strategy", "size-and-time");
this.environment.setProperty("logging.log4j2.rollingpolicy.max-file-size", "5MB"); this.environment.setProperty("logging.log4j2.rollingpolicy.max-file-size", "5MB");
this.environment.setProperty("logging.log4j2.rollingpolicy.time-based.interval", "3"); this.environment.setProperty("logging.log4j2.rollingpolicy.time-based.interval", "3");
SpringBootTriggeringPolicy policy = getTriggeringPolicy(); TriggeringPolicy policy = getTriggeringPolicy();
TriggeringPolicy delegate = policy.getDelegate(); assertThat(findPolicy(policy, TimeBasedTriggeringPolicy.class)).isNotNull();
assertThat(delegate).isInstanceOf(CompositeTriggeringPolicy.class); assertThat(findPolicy(policy, SizeBasedTriggeringPolicy.class)).isNotNull();
CompositeTriggeringPolicy composite = (CompositeTriggeringPolicy) delegate;
TriggeringPolicy[] policies = composite.getTriggeringPolicies();
assertThat(policies).anyMatch(TimeBasedTriggeringPolicy.class::isInstance);
assertThat(policies).anyMatch(SizeBasedTriggeringPolicy.class::isInstance);
} }
@Test @Test
void rollingPolicyCronStrategyIsApplied() { void rollingPolicyCronStrategyIsApplied() {
this.environment.setProperty("logging.log4j2.rollingpolicy.strategy", "cron"); this.environment.setProperty("logging.log4j2.rollingpolicy.strategy", "cron");
this.environment.setProperty("logging.log4j2.rollingpolicy.cron.schedule", "0 0 0 * * ?"); this.environment.setProperty("logging.log4j2.rollingpolicy.cron.schedule", "0 0 0 * * ?");
SpringBootTriggeringPolicy policy = getTriggeringPolicy(); TriggeringPolicy policy = getTriggeringPolicy();
TriggeringPolicy delegate = policy.getDelegate(); CronTriggeringPolicy cronPolicy = findPolicy(policy, CronTriggeringPolicy.class);
assertThat(delegate).isInstanceOf(CronTriggeringPolicy.class); assertThat(cronPolicy).isNotNull();
CronTriggeringPolicy cronPolicy = (CronTriggeringPolicy) delegate;
assertThat(cronPolicy.getCronExpression().getCronExpression()).isEqualTo("0 0 0 * * ?"); assertThat(cronPolicy.getCronExpression().getCronExpression()).isEqualTo("0 0 0 * * ?");
} }
private SpringBootTriggeringPolicy getTriggeringPolicy() { private TriggeringPolicy getTriggeringPolicy() {
File file = new File(tmpDir(), "target-file.log"); File file = new File(tmpDir(), "target-file.log");
LogFile logFile = getLogFile(file.getPath(), null); LogFile logFile = getLogFile(file.getPath(), null);
this.loggingSystem.beforeInitialize(); this.loggingSystem.beforeInitialize();
this.loggingSystem.initialize(this.initializationContext, this.loggingSystem.initialize(this.initializationContext,
"classpath:org/springframework/boot/logging/log4j2/log4j2-file.xml", logFile); "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(); Configuration configuration = loggerContext.getConfiguration();
RollingFileAppender appender = (RollingFileAppender) configuration.getAppenders().get("File"); RollingFileAppender appender = (RollingFileAppender) configuration.getAppenders().get("File");
assertThat(appender).isNotNull(); assertThat(appender).isNotNull();
TriggeringPolicy topPolicy = appender.getManager().getTriggeringPolicy(); return appender.getManager().getTriggeringPolicy();
SpringBootTriggeringPolicy policy = findSpringBootTriggeringPolicy(topPolicy);
assertThat(policy).isNotNull();
return policy;
} }
private @Nullable SpringBootTriggeringPolicy findSpringBootTriggeringPolicy(TriggeringPolicy policy) { @SuppressWarnings("unchecked")
if (policy instanceof SpringBootTriggeringPolicy springBoot) { private <T extends TriggeringPolicy> @Nullable T findPolicy(TriggeringPolicy policy, Class<T> type) {
return springBoot; if (type.isInstance(policy)) {
return (T) policy;
} }
if (policy instanceof CompositeTriggeringPolicy composite) { if (policy instanceof CompositeTriggeringPolicy composite) {
for (TriggeringPolicy child : composite.getTriggeringPolicies()) { for (TriggeringPolicy child : composite.getTriggeringPolicies()) {
SpringBootTriggeringPolicy found = findSpringBootTriggeringPolicy(child); T found = findPolicy(child, type);
if (found != null) { if (found != null) {
return found; return found;
} }

Loading…
Cancel
Save