Polish "Add property to control log exporting"

See gh-42813
This commit is contained in:
Moritz Halbritter 2024-10-22 11:28:55 +02:00
parent e9b3b97d81
commit 0ce4dbd49f
7 changed files with 50 additions and 35 deletions

View File

@ -25,7 +25,7 @@ import java.lang.annotation.Target;
import org.springframework.context.annotation.Conditional;
/**
* {@link Conditional @Conditional} that checks whether logging exporter is enabled. It
* {@link Conditional @Conditional} that checks whether logging export is enabled. It
* matches if the value of the {@code management.logging.export.enabled} property is
* {@code true} or if it is not configured. If the {@link #value() logging exporter name}
* is set, the {@code management.<name>.logging.export.enabled} property can be used to
@ -39,8 +39,8 @@ import org.springframework.context.annotation.Conditional;
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Documented
@Conditional(OnEnabledLoggingCondition.class)
public @interface ConditionalOnEnabledLogging {
@Conditional(OnEnabledLoggingExportCondition.class)
public @interface ConditionalOnEnabledLoggingExport {
/**
* Name of the logging exporter.

View File

@ -30,9 +30,9 @@ import org.springframework.util.StringUtils;
*
* @author Moritz Halbritter
* @author Dmytro Nosan
* @see ConditionalOnEnabledLogging
* @see ConditionalOnEnabledLoggingExport
*/
class OnEnabledLoggingCondition extends SpringBootCondition {
class OnEnabledLoggingExportCondition extends SpringBootCondition {
private static final String GLOBAL_PROPERTY = "management.logging.export.enabled";
@ -46,22 +46,23 @@ class OnEnabledLoggingCondition extends SpringBootCondition {
.getProperty(EXPORTER_PROPERTY.formatted(loggingExporter), Boolean.class);
if (exporterLoggingEnabled != null) {
return new ConditionOutcome(exporterLoggingEnabled,
ConditionMessage.forCondition(ConditionalOnEnabledLogging.class)
ConditionMessage.forCondition(ConditionalOnEnabledLoggingExport.class)
.because(EXPORTER_PROPERTY.formatted(loggingExporter) + " is " + exporterLoggingEnabled));
}
}
Boolean globalLoggingEnabled = context.getEnvironment().getProperty(GLOBAL_PROPERTY, Boolean.class);
if (globalLoggingEnabled != null) {
return new ConditionOutcome(globalLoggingEnabled,
ConditionMessage.forCondition(ConditionalOnEnabledLogging.class)
ConditionMessage.forCondition(ConditionalOnEnabledLoggingExport.class)
.because(GLOBAL_PROPERTY + " is " + globalLoggingEnabled));
}
return ConditionOutcome.match(ConditionMessage.forCondition(ConditionalOnEnabledLogging.class)
.because("logging is enabled by default"));
return ConditionOutcome.match(ConditionMessage.forCondition(ConditionalOnEnabledLoggingExport.class)
.because("is enabled by default"));
}
private static String getExporterName(AnnotatedTypeMetadata metadata) {
Map<String, Object> attributes = metadata.getAnnotationAttributes(ConditionalOnEnabledLogging.class.getName());
Map<String, Object> attributes = metadata
.getAnnotationAttributes(ConditionalOnEnabledLoggingExport.class.getName());
if (attributes == null) {
return null;
}

View File

@ -20,7 +20,6 @@ import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter;
import io.opentelemetry.sdk.logs.SdkLoggerProvider;
import org.springframework.boot.actuate.autoconfigure.logging.ConditionalOnEnabledLogging;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
@ -37,7 +36,6 @@ import org.springframework.context.annotation.Import;
@ConditionalOnClass({ SdkLoggerProvider.class, OpenTelemetry.class, OtlpHttpLogRecordExporter.class })
@EnableConfigurationProperties(OtlpLoggingProperties.class)
@Import({ OtlpLoggingConfigurations.ConnectionDetails.class, OtlpLoggingConfigurations.Exporters.class })
@ConditionalOnEnabledLogging("otlp")
public class OtlpLoggingAutoConfiguration {
}

View File

@ -23,6 +23,7 @@ import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder
import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter;
import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder;
import org.springframework.boot.actuate.autoconfigure.logging.ConditionalOnEnabledLoggingExport;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@ -76,6 +77,7 @@ final class OtlpLoggingConfigurations {
@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingBean({ OtlpGrpcLogRecordExporter.class, OtlpHttpLogRecordExporter.class })
@ConditionalOnBean(OtlpLoggingConnectionDetails.class)
@ConditionalOnEnabledLoggingExport("otlp")
static class Exporters {
@Bean

View File

@ -312,7 +312,7 @@
{
"name": "management.logging.export.enabled",
"type": "java.lang.Boolean",
"description": "Whether the auto-configuration for exporting log record data is enabled",
"description": "Whether auto-configuration of logging is enabled to export logs.",
"defaultValue": true
},
{
@ -2076,7 +2076,7 @@
{
"name": "management.otlp.logging.export.enabled",
"type": "java.lang.Boolean",
"description": "Whether auto-configuration for exporting OTLP log records is enabled."
"description": "Whether auto-configuration of logging is enabled to export OTLP logs."
},
{
"name": "management.otlp.tracing.export.enabled",

View File

@ -31,81 +31,81 @@ import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link OnEnabledLoggingCondition}.
* Tests for {@link OnEnabledLoggingExportCondition}.
*
* @author Moritz Halbritter
* @author Dmytro Nosan
*/
class OnEnabledLoggingConditionTests {
class OnEnabledLoggingExportConditionTests {
@Test
void shouldMatchIfNoPropertyIsSet() {
OnEnabledLoggingCondition condition = new OnEnabledLoggingCondition();
OnEnabledLoggingExportCondition condition = new OnEnabledLoggingExportCondition();
ConditionOutcome outcome = condition.getMatchOutcome(mockConditionContext(), mockMetadata(""));
assertThat(outcome.isMatch()).isTrue();
assertThat(outcome.getMessage()).isEqualTo("@ConditionalOnEnabledLogging logging is enabled by default");
assertThat(outcome.getMessage()).isEqualTo("@ConditionalOnEnabledLoggingExport is enabled by default");
}
@Test
void shouldNotMatchIfGlobalPropertyIsFalse() {
OnEnabledLoggingCondition condition = new OnEnabledLoggingCondition();
OnEnabledLoggingExportCondition condition = new OnEnabledLoggingExportCondition();
ConditionOutcome outcome = condition.getMatchOutcome(
mockConditionContext(Map.of("management.logging.export.enabled", "false")), mockMetadata(""));
assertThat(outcome.isMatch()).isFalse();
assertThat(outcome.getMessage())
.isEqualTo("@ConditionalOnEnabledLogging management.logging.export.enabled is false");
.isEqualTo("@ConditionalOnEnabledLoggingExport management.logging.export.enabled is false");
}
@Test
void shouldMatchIfGlobalPropertyIsTrue() {
OnEnabledLoggingCondition condition = new OnEnabledLoggingCondition();
OnEnabledLoggingExportCondition condition = new OnEnabledLoggingExportCondition();
ConditionOutcome outcome = condition.getMatchOutcome(
mockConditionContext(Map.of("management.logging.export.enabled", "true")), mockMetadata(""));
assertThat(outcome.isMatch()).isTrue();
assertThat(outcome.getMessage())
.isEqualTo("@ConditionalOnEnabledLogging management.logging.export.enabled is true");
.isEqualTo("@ConditionalOnEnabledLoggingExport management.logging.export.enabled is true");
}
@Test
void shouldNotMatchIfExporterPropertyIsFalse() {
OnEnabledLoggingCondition condition = new OnEnabledLoggingCondition();
OnEnabledLoggingExportCondition condition = new OnEnabledLoggingExportCondition();
ConditionOutcome outcome = condition.getMatchOutcome(
mockConditionContext(Map.of("management.otlp.logging.export.enabled", "false")), mockMetadata("otlp"));
assertThat(outcome.isMatch()).isFalse();
assertThat(outcome.getMessage())
.isEqualTo("@ConditionalOnEnabledLogging management.otlp.logging.export.enabled is false");
.isEqualTo("@ConditionalOnEnabledLoggingExport management.otlp.logging.export.enabled is false");
}
@Test
void shouldMatchIfExporterPropertyIsTrue() {
OnEnabledLoggingCondition condition = new OnEnabledLoggingCondition();
OnEnabledLoggingExportCondition condition = new OnEnabledLoggingExportCondition();
ConditionOutcome outcome = condition.getMatchOutcome(
mockConditionContext(Map.of("management.otlp.logging.export.enabled", "true")), mockMetadata("otlp"));
assertThat(outcome.isMatch()).isTrue();
assertThat(outcome.getMessage())
.isEqualTo("@ConditionalOnEnabledLogging management.otlp.logging.export.enabled is true");
.isEqualTo("@ConditionalOnEnabledLoggingExport management.otlp.logging.export.enabled is true");
}
@Test
void exporterPropertyShouldOverrideGlobalPropertyIfTrue() {
OnEnabledLoggingCondition condition = new OnEnabledLoggingCondition();
OnEnabledLoggingExportCondition condition = new OnEnabledLoggingExportCondition();
ConditionOutcome outcome = condition.getMatchOutcome(mockConditionContext(
Map.of("management.logging.enabled", "false", "management.otlp.logging.export.enabled", "true")),
mockMetadata("otlp"));
assertThat(outcome.isMatch()).isTrue();
assertThat(outcome.getMessage())
.isEqualTo("@ConditionalOnEnabledLogging management.otlp.logging.export.enabled is true");
.isEqualTo("@ConditionalOnEnabledLoggingExport management.otlp.logging.export.enabled is true");
}
@Test
void exporterPropertyShouldOverrideGlobalPropertyIfFalse() {
OnEnabledLoggingCondition condition = new OnEnabledLoggingCondition();
OnEnabledLoggingExportCondition condition = new OnEnabledLoggingExportCondition();
ConditionOutcome outcome = condition.getMatchOutcome(mockConditionContext(
Map.of("management.logging.enabled", "true", "management.otlp.logging.export.enabled", "false")),
mockMetadata("otlp"));
assertThat(outcome.isMatch()).isFalse();
assertThat(outcome.getMessage())
.isEqualTo("@ConditionalOnEnabledLogging management.otlp.logging.export.enabled is false");
.isEqualTo("@ConditionalOnEnabledLoggingExport management.otlp.logging.export.enabled is false");
}
private ConditionContext mockConditionContext() {
@ -122,7 +122,7 @@ class OnEnabledLoggingConditionTests {
private AnnotatedTypeMetadata mockMetadata(String exporter) {
AnnotatedTypeMetadata metadata = mock(AnnotatedTypeMetadata.class);
given(metadata.getAnnotationAttributes(ConditionalOnEnabledLogging.class.getName()))
given(metadata.getAnnotationAttributes(ConditionalOnEnabledLoggingExport.class.getName()))
.willReturn(Map.of("value", exporter));
return metadata;
}

View File

@ -73,12 +73,26 @@ class OtlpLoggingAutoConfigurationTests {
});
}
@Test
void shouldBackOffWhenLoggingExportPropertyIsNotEnabled() {
this.contextRunner
.withPropertyValues("management.logging.export.enabled=false",
"management.otlp.logging.endpoint=http://localhost:4318/v1/logs")
.run((context) -> {
assertThat(context).hasSingleBean(OtlpLoggingConnectionDetails.class);
assertThat(context).doesNotHaveBean(LogRecordExporter.class);
});
}
@Test
void shouldBackOffWhenOtlpLoggingExportPropertyIsNotEnabled() {
this.contextRunner.withPropertyValues("management.otlp.logging.export.enabled=false").run((context) -> {
assertThat(context).doesNotHaveBean(OtlpLoggingConnectionDetails.class);
assertThat(context).doesNotHaveBean(LogRecordExporter.class);
});
this.contextRunner
.withPropertyValues("management.otlp.logging.export.enabled=false",
"management.otlp.logging.endpoint=http://localhost:4318/v1/logs")
.run((context) -> {
assertThat(context).hasSingleBean(OtlpLoggingConnectionDetails.class);
assertThat(context).doesNotHaveBean(LogRecordExporter.class);
});
}
@Test