diff --git a/sdk-extensions/autoconfigure/README.md b/sdk-extensions/autoconfigure/README.md index 24fad759e3..21b9fcee0d 100644 --- a/sdk-extensions/autoconfigure/README.md +++ b/sdk-extensions/autoconfigure/README.md @@ -235,16 +235,25 @@ Supported values for `otel.traces.sampler` are - "parentbased_always_off": ParentBased(root=AlwaysOffSampler) - "parentbased_traceidratio": ParentBased(root=TraceIdRatioBased). `otel.traces.sampler.arg` sets the ratio. +## Attribute limits + +These properties can be used to control the maximum number and length of attributes. + +| System property | Environment variable | Description | +|-----------------------------------|-----------------------------------|----------------------------------------------------------------------------------------------------------| +| otel.attribute.value.length.limit | OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT | The maximum length of attribute values. Applies to spans and logs. By default there is no limit. | +| otel.attribute.count.limit | OTEL_ATTRIBUTE_COUNT_LIMIT | The maximum number of attributes. Applies to spans, span events, span links, and logs. Default is `128`. | + ## Span limits -These properties can be used to control the maximum size of recordings per span. +These properties can be used to control the maximum size of spans by placing limits on attributes, events, and links. -| System property | Environment variable | Description | -|----------------------------------------|----------------------------------------|------------------------------------------------------------------------| -| otel.span.attribute.value.length.limit | OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT | The maximum length of attribute values. By default there is no limit. | -| otel.span.attribute.count.limit | OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT | The maximum number of attributes per span. Default is `128`. | -| otel.span.event.count.limit | OTEL_SPAN_EVENT_COUNT_LIMIT | The maximum number of events per span. Default is `128`. | -| otel.span.link.count.limit | OTEL_SPAN_LINK_COUNT_LIMIT | The maximum number of links per span. Default is `128` | +| System property | Environment variable | Description | +|----------------------------------------|----------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------| +| otel.span.attribute.value.length.limit | OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT | The maximum length of span attribute values. Takes precedence over `otel.attribute.value.length.limit`. By default there is no limit. | +| otel.span.attribute.count.limit | OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT | The maximum number of attributes per span. Takes precedence over `otel.attribute.count.limit`. Default is `128`. | +| otel.span.event.count.limit | OTEL_SPAN_EVENT_COUNT_LIMIT | The maximum number of events per span. Default is `128`. | +| otel.span.link.count.limit | OTEL_SPAN_LINK_COUNT_LIMIT | The maximum number of links per span. Default is `128` | ## Exemplars diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LogEmitterProviderConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LogEmitterProviderConfiguration.java index 7b183605e0..c74ae0a2a3 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LogEmitterProviderConfiguration.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LogEmitterProviderConfiguration.java @@ -9,6 +9,8 @@ import static io.opentelemetry.sdk.autoconfigure.LogExporterConfiguration.config import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.logs.LogLimits; +import io.opentelemetry.sdk.logs.LogLimitsBuilder; import io.opentelemetry.sdk.logs.LogProcessor; import io.opentelemetry.sdk.logs.SdkLogEmitterProviderBuilder; import io.opentelemetry.sdk.logs.export.BatchLogProcessor; @@ -28,6 +30,9 @@ final class LogEmitterProviderConfiguration { MeterProvider meterProvider, BiFunction logExporterCustomizer) { + + logEmitterProviderBuilder.setLogLimits(() -> configureLogLimits(config)); + Map exportersByName = configureLogExporters(config, meterProvider, logExporterCustomizer); @@ -55,5 +60,22 @@ final class LogEmitterProviderConfiguration { return logProcessors; } + // Visible for testing + static LogLimits configureLogLimits(ConfigProperties config) { + LogLimitsBuilder builder = LogLimits.builder(); + + Integer maxAttrLength = config.getInt("otel.attribute.value.length.limit"); + if (maxAttrLength != null) { + builder.setMaxAttributeValueLength(maxAttrLength); + } + + Integer maxAttrs = config.getInt("otel.attribute.count.limit"); + if (maxAttrs != null) { + builder.setMaxNumberOfAttributes(maxAttrs); + } + + return builder.build(); + } + private LogEmitterProviderConfiguration() {} } diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfiguration.java index dd5b84e1c4..78a239597c 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfiguration.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfiguration.java @@ -106,14 +106,24 @@ final class TracerProviderConfiguration { static SpanLimits configureSpanLimits(ConfigProperties config) { SpanLimitsBuilder builder = SpanLimits.builder(); - Integer maxLength = config.getInt("otel.span.attribute.value.length.limit"); - if (maxLength != null) { - builder.setMaxAttributeValueLength(maxLength); + Integer maxAttrLength = config.getInt("otel.attribute.value.length.limit"); + if (maxAttrLength != null) { + builder.setMaxAttributeValueLength(maxAttrLength); + } + Integer maxSpanAttrLength = config.getInt("otel.span.attribute.value.length.limit"); + if (maxSpanAttrLength != null) { + builder.setMaxAttributeValueLength(maxSpanAttrLength); } - Integer maxAttrs = config.getInt("otel.span.attribute.count.limit"); + Integer maxAttrs = config.getInt("otel.attribute.count.limit"); if (maxAttrs != null) { builder.setMaxNumberOfAttributes(maxAttrs); + builder.setMaxNumberOfAttributesPerEvent(maxAttrs); + builder.setMaxNumberOfAttributesPerLink(maxAttrs); + } + Integer maxSpanAttrs = config.getInt("otel.span.attribute.count.limit"); + if (maxSpanAttrs != null) { + builder.setMaxNumberOfAttributes(maxSpanAttrs); } Integer maxEvents = config.getInt("otel.span.event.count.limit"); diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/LogEmitterProviderConfigurationTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/LogEmitterProviderConfigurationTest.java index eadc396380..784ae7bf48 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/LogEmitterProviderConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/LogEmitterProviderConfigurationTest.java @@ -5,21 +5,34 @@ package io.opentelemetry.sdk.autoconfigure; +import static org.assertj.core.api.Assertions.as; import static org.assertj.core.api.Assertions.assertThat; +import com.google.common.collect.ImmutableMap; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.logs.LogLimits; import io.opentelemetry.sdk.logs.LogProcessor; import io.opentelemetry.sdk.logs.SdkLogEmitterProvider; import io.opentelemetry.sdk.logs.SdkLogEmitterProviderBuilder; +import io.opentelemetry.sdk.trace.SpanLimits; import java.util.Collections; import java.util.Map; +import java.util.function.Supplier; +import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.jupiter.api.Test; class LogEmitterProviderConfigurationTest { + private static final ConfigProperties EMPTY = + DefaultConfigProperties.createForTest(Collections.emptyMap()); + @Test void configureLogEmitterProvider() { - Map properties = Collections.singletonMap("otel.logs.exporter", "none"); + Map properties = + ImmutableMap.of( + "otel.logs.exporter", "none", + "otel.attribute.count.limit", "5"); // We don't have any exporters on classpath for this test so check no-op case. Exporter cases // are verified in other test sets like testFullConfig. @@ -35,12 +48,33 @@ class LogEmitterProviderConfigurationTest { assertThat(logEmitterProvider) .extracting("sharedState") .satisfies( - sharedState -> - assertThat(sharedState) - .extracting("logProcessor") - .isEqualTo(LogProcessor.composite())); + sharedState -> { + assertThat(sharedState) + .extracting("logProcessor") + .isEqualTo(LogProcessor.composite()); + assertThat(sharedState) + .extracting( + "logLimitsSupplier", as(InstanceOfAssertFactories.type(Supplier.class))) + .extracting(supplier -> (LogLimits) supplier.get()) + .isEqualTo(LogLimits.builder().setMaxNumberOfAttributes(5).build()); + }); } finally { logEmitterProvider.shutdown(); } } + + @Test + void configureSpanLimits() { + assertThat(LogEmitterProviderConfiguration.configureLogLimits(EMPTY)) + .isEqualTo(LogLimits.getDefault()); + + SpanLimits config = + TracerProviderConfiguration.configureSpanLimits( + DefaultConfigProperties.createForTest( + ImmutableMap.of( + "otel.attribute.value.length.limit", "100", + "otel.attribute.count.limit", "5"))); + assertThat(config.getMaxAttributeValueLength()).isEqualTo(100); + assertThat(config.getMaxNumberOfAttributes()).isEqualTo(5); + } } diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfigurationTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfigurationTest.java index 500e9941fc..43f464f8a4 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfigurationTest.java @@ -9,6 +9,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.when; +import com.google.common.collect.ImmutableMap; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; @@ -156,26 +157,39 @@ class TracerProviderConfigurationTest { } @Test - void configureTraceConfig_empty() { + void configureSpanLimits() { assertThat(TracerProviderConfiguration.configureSpanLimits(EMPTY)) .isEqualTo(SpanLimits.getDefault()); - } - - @Test - void configureTraceConfig_full() { - - Map properties = new HashMap<>(); - properties.put("otel.traces.sampler", "always_off"); - properties.put("otel.span.attribute.value.length.limit", "100"); - properties.put("otel.span.attribute.count.limit", "5"); - properties.put("otel.span.event.count.limit", "4"); - properties.put("otel.span.link.count.limit", "3"); SpanLimits config = TracerProviderConfiguration.configureSpanLimits( - DefaultConfigProperties.createForTest(properties)); + DefaultConfigProperties.createForTest( + ImmutableMap.of( + "otel.attribute.value.length.limit", "100", + "otel.attribute.count.limit", "5"))); assertThat(config.getMaxAttributeValueLength()).isEqualTo(100); assertThat(config.getMaxNumberOfAttributes()).isEqualTo(5); + assertThat(config.getMaxNumberOfAttributesPerEvent()).isEqualTo(5); + assertThat(config.getMaxNumberOfAttributesPerLink()).isEqualTo(5); + assertThat(config.getMaxNumberOfEvents()) + .isEqualTo(SpanLimits.getDefault().getMaxNumberOfEvents()); + assertThat(config.getMaxNumberOfLinks()) + .isEqualTo(SpanLimits.getDefault().getMaxNumberOfLinks()); + + config = + TracerProviderConfiguration.configureSpanLimits( + DefaultConfigProperties.createForTest( + ImmutableMap.of( + "otel.attribute.value.length.limit", "100", + "otel.span.attribute.value.length.limit", "200", + "otel.attribute.count.limit", "5", + "otel.span.attribute.count.limit", "10", + "otel.span.event.count.limit", "4", + "otel.span.link.count.limit", "3"))); + assertThat(config.getMaxAttributeValueLength()).isEqualTo(200); + assertThat(config.getMaxNumberOfAttributes()).isEqualTo(10); + assertThat(config.getMaxNumberOfAttributesPerEvent()).isEqualTo(5); + assertThat(config.getMaxNumberOfAttributesPerLink()).isEqualTo(5); assertThat(config.getMaxNumberOfEvents()).isEqualTo(4); assertThat(config.getMaxNumberOfLinks()).isEqualTo(3); }