diff --git a/sdk-extensions/zpages/src/main/java/io/opentelemetry/sdk/extension/zpages/TraceConfigzZPageHandler.java b/sdk-extensions/zpages/src/main/java/io/opentelemetry/sdk/extension/zpages/TraceConfigzZPageHandler.java index 7cd087f54b..2768bdd032 100644 --- a/sdk-extensions/zpages/src/main/java/io/opentelemetry/sdk/extension/zpages/TraceConfigzZPageHandler.java +++ b/sdk-extensions/zpages/src/main/java/io/opentelemetry/sdk/extension/zpages/TraceConfigzZPageHandler.java @@ -7,6 +7,7 @@ package io.opentelemetry.sdk.extension.zpages; import io.opentelemetry.sdk.trace.TracerSdkManagement; import io.opentelemetry.sdk.trace.config.TraceConfig; +import io.opentelemetry.sdk.trace.config.TraceConfigBuilder; import io.opentelemetry.sdk.trace.samplers.Sampler; import java.io.OutputStream; import java.io.PrintStream; @@ -368,7 +369,7 @@ final class TraceConfigzZPageHandler extends ZPageHandler { return; } if (action.equals(QUERY_STRING_ACTION_CHANGE)) { - TraceConfig.Builder newConfigBuilder = + TraceConfigBuilder newConfigBuilder = this.tracerSdkManagement.getActiveTraceConfig().toBuilder(); String samplingProbabilityStr = queryMap.get(QUERY_STRING_SAMPLING_PROBABILITY); if (samplingProbabilityStr != null) { diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/TracerSdkManagement.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/TracerSdkManagement.java index 3c409ee777..c6ee2b6198 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/TracerSdkManagement.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/TracerSdkManagement.java @@ -8,6 +8,7 @@ package io.opentelemetry.sdk.trace; import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.trace.config.TraceConfig; +import io.opentelemetry.sdk.trace.config.TraceConfigBuilder; import io.opentelemetry.sdk.trace.export.SpanExporter; /** @@ -28,7 +29,7 @@ public interface TracerSdkManagement { * *

Note: To update the {@link TraceConfig} associated with this instance you should use the * {@link TraceConfig#toBuilder()} method on the {@link TraceConfig} returned from {@link - * #getActiveTraceConfig()}, make the changes desired to the {@link TraceConfig.Builder} instance, + * #getActiveTraceConfig()}, make the changes desired to the {@link TraceConfigBuilder} instance, * then use this method with the resulting {@link TraceConfig} instance. * * @param traceConfig the new active {@code TraceConfig}. diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/config/TraceConfig.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/config/TraceConfig.java index 01398e9a1d..dbaa034d41 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/config/TraceConfig.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/config/TraceConfig.java @@ -6,12 +6,8 @@ package io.opentelemetry.sdk.trace.config; import com.google.auto.value.AutoValue; -import io.opentelemetry.api.internal.Utils; import io.opentelemetry.api.trace.Span; -import io.opentelemetry.sdk.common.export.ConfigBuilder; import io.opentelemetry.sdk.trace.samplers.Sampler; -import java.util.Map; -import java.util.Properties; import javax.annotation.concurrent.Immutable; /** @@ -20,7 +16,7 @@ import javax.annotation.concurrent.Immutable; *

Note: To update the TraceConfig associated with a {@link * io.opentelemetry.sdk.trace.TracerSdkManagement}, you should use the {@link #toBuilder()} method * on the TraceConfig currently assigned to the provider, make the changes desired to the {@link - * Builder} instance, then use the {@link + * TraceConfigBuilder} instance, then use the {@link * io.opentelemetry.sdk.trace.TracerSdkManagement#updateActiveTraceConfig(TraceConfig)} with the * resulting TraceConfig instance. * @@ -69,17 +65,18 @@ import javax.annotation.concurrent.Immutable; @AutoValue @Immutable public abstract class TraceConfig { + + /** + * Value for attribute length which indicates attributes should not be truncated. + * + * @see TraceConfigBuilder#setMaxLengthOfAttributeValues(int) + */ + public static final int UNLIMITED_ATTRIBUTE_LENGTH = -1; + // These values are the default values for all the global parameters. // TODO: decide which default sampler to use - private static final Sampler DEFAULT_SAMPLER = Sampler.parentBased(Sampler.alwaysOn()); - private static final int DEFAULT_SPAN_MAX_NUM_ATTRIBUTES = 1000; - private static final int DEFAULT_SPAN_MAX_NUM_EVENTS = 1000; - private static final int DEFAULT_SPAN_MAX_NUM_LINKS = 1000; - private static final int DEFAULT_SPAN_MAX_NUM_ATTRIBUTES_PER_EVENT = 32; - private static final int DEFAULT_SPAN_MAX_NUM_ATTRIBUTES_PER_LINK = 32; - public static final int UNLIMITED_ATTRIBUTE_LENGTH = -1; - private static final int DEFAULT_MAX_ATTRIBUTE_LENGTH = UNLIMITED_ATTRIBUTE_LENGTH; + private static final TraceConfig DEFAULT = new TraceConfigBuilder().build(); /** * Returns the default {@code TraceConfig}. @@ -90,7 +87,23 @@ public abstract class TraceConfig { return DEFAULT; } - private static final TraceConfig DEFAULT = TraceConfig.builder().build(); + static TraceConfig create( + Sampler sampler, + int maxNumAttributes, + int maxNumEvents, + int maxNumLinks, + int maxNumAttributesPerEvent, + int maxNumAttributesPerLink, + int maxAttributeLength) { + return new AutoValue_TraceConfig( + sampler, + maxNumAttributes, + maxNumEvents, + maxNumLinks, + maxNumAttributesPerEvent, + maxNumAttributesPerLink, + maxAttributeLength); + } /** * Returns the global default {@code Sampler} which is used when constructing a new {@code Span}. @@ -147,231 +160,20 @@ public abstract class TraceConfig { } /** - * Returns a new {@link Builder}. + * Returns a {@link TraceConfigBuilder} initialized to the same property values as the current + * instance. * - * @return a new {@link Builder}. + * @return a {@link TraceConfigBuilder} initialized to the same property values as the current + * instance. */ - private static Builder builder() { - return new AutoValue_TraceConfig.Builder() - .setSampler(DEFAULT_SAMPLER) - .setMaxNumberOfAttributes(DEFAULT_SPAN_MAX_NUM_ATTRIBUTES) - .setMaxNumberOfEvents(DEFAULT_SPAN_MAX_NUM_EVENTS) - .setMaxNumberOfLinks(DEFAULT_SPAN_MAX_NUM_LINKS) - .setMaxNumberOfAttributesPerEvent(DEFAULT_SPAN_MAX_NUM_ATTRIBUTES_PER_EVENT) - .setMaxNumberOfAttributesPerLink(DEFAULT_SPAN_MAX_NUM_ATTRIBUTES_PER_LINK) - .setMaxLengthOfAttributeValues(DEFAULT_MAX_ATTRIBUTE_LENGTH); - } - - /** - * Returns a {@link Builder} initialized to the same property values as the current instance. - * - * @return a {@link Builder} initialized to the same property values as the current instance. - */ - public abstract Builder toBuilder(); - - /** Builder for {@link TraceConfig}. */ - @AutoValue.Builder - public abstract static class Builder extends ConfigBuilder { - private static final String KEY_SAMPLER_PROBABILITY = "otel.config.sampler.probability"; - private static final String KEY_SPAN_ATTRIBUTE_COUNT_LIMIT = "otel.span.attribute.count.limit"; - private static final String KEY_SPAN_EVENT_COUNT_LIMIT = "otel.span.event.count.limit"; - private static final String KEY_SPAN_LINK_COUNT_LIMIT = "otel.span.link.count.limit"; - private static final String KEY_SPAN_MAX_NUM_ATTRIBUTES_PER_EVENT = - "otel.config.max.event.attrs"; - private static final String KEY_SPAN_MAX_NUM_ATTRIBUTES_PER_LINK = "otel.config.max.link.attrs"; - private static final String KEY_SPAN_ATTRIBUTE_MAX_VALUE_LENGTH = "otel.config.max.attr.length"; - - Builder() {} - - /** - * Sets the configuration values from the given configuration map for only the available keys. - * - * @param configMap {@link Map} holding the configuration values. - * @return this - */ - // Visible for testing - @Override - protected Builder fromConfigMap( - Map configMap, Builder.NamingConvention namingConvention) { - configMap = namingConvention.normalize(configMap); - Double doubleValue = getDoubleProperty(KEY_SAMPLER_PROBABILITY, configMap); - if (doubleValue != null) { - this.setTraceIdRatioBased(doubleValue); - } - Integer intValue = getIntProperty(KEY_SPAN_ATTRIBUTE_COUNT_LIMIT, configMap); - if (intValue != null) { - this.setMaxNumberOfAttributes(intValue); - } - intValue = getIntProperty(KEY_SPAN_EVENT_COUNT_LIMIT, configMap); - if (intValue != null) { - this.setMaxNumberOfEvents(intValue); - } - intValue = getIntProperty(KEY_SPAN_LINK_COUNT_LIMIT, configMap); - if (intValue != null) { - this.setMaxNumberOfLinks(intValue); - } - intValue = getIntProperty(KEY_SPAN_MAX_NUM_ATTRIBUTES_PER_EVENT, configMap); - if (intValue != null) { - this.setMaxNumberOfAttributesPerEvent(intValue); - } - intValue = getIntProperty(KEY_SPAN_MAX_NUM_ATTRIBUTES_PER_LINK, configMap); - if (intValue != null) { - this.setMaxNumberOfAttributesPerLink(intValue); - } - intValue = getIntProperty(KEY_SPAN_ATTRIBUTE_MAX_VALUE_LENGTH, configMap); - if (intValue != null) { - this.setMaxLengthOfAttributeValues(intValue); - } - return this; - } - - /** - * * Sets the configuration values from the given properties object for only the available keys. - * - * @param properties {@link Properties} holding the configuration values. - * @return this - */ - @Override - public Builder readProperties(Properties properties) { - return super.readProperties(properties); - } - - /** - * * Sets the configuration values from environment variables for only the available keys. - * - * @return this. - */ - @Override - public Builder readEnvironmentVariables() { - return super.readEnvironmentVariables(); - } - - /** - * * Sets the configuration values from system properties for only the available keys. - * - * @return this. - */ - @Override - public Builder readSystemProperties() { - return super.readSystemProperties(); - } - - /** - * Sets the global default {@code Sampler}. It must be not {@code null} otherwise {@link - * #build()} will throw an exception. - * - * @param sampler the global default {@code Sampler}. - * @return this. - */ - public abstract Builder setSampler(Sampler sampler); - - /** - * Sets the global default {@code Sampler}. It must be not {@code null} otherwise {@link - * #build()} will throw an exception. - * - * @param samplerRatio the global default ratio used to make decisions on {@link Span} sampling. - * @return this. - */ - public Builder setTraceIdRatioBased(double samplerRatio) { - Utils.checkArgument(samplerRatio >= 0, "samplerRatio must be greater than or equal to 0."); - Utils.checkArgument(samplerRatio <= 1, "samplerRatio must be lesser than or equal to 1."); - if (samplerRatio == 1) { - setSampler(Sampler.parentBased(Sampler.alwaysOn())); - } else if (samplerRatio == 0) { - setSampler(Sampler.alwaysOff()); - } else { - setSampler(Sampler.parentBased(Sampler.traceIdRatioBased(samplerRatio))); - } - return this; - } - - /** - * Sets the global default max number of attributes per {@link Span}. - * - * @param maxNumberOfAttributes the global default max number of attributes per {@link Span}. It - * must be positive otherwise {@link #build()} will throw an exception. - * @return this. - */ - public abstract Builder setMaxNumberOfAttributes(int maxNumberOfAttributes); - - /** - * Sets the global default max number of events per {@link Span}. - * - * @param maxNumberOfEvents the global default max number of events per {@link Span}. It must be - * positive otherwise {@link #build()} will throw an exception. - * @return this. - */ - public abstract Builder setMaxNumberOfEvents(int maxNumberOfEvents); - - /** - * Sets the global default max number of links per {@link Span}. - * - * @param maxNumberOfLinks the global default max number of links per {@link Span}. It must be - * positive otherwise {@link #build()} will throw an exception. - * @return this. - */ - public abstract Builder setMaxNumberOfLinks(int maxNumberOfLinks); - - /** - * Sets the global default max number of attributes per event. - * - * @param maxNumberOfAttributesPerEvent the global default max number of attributes per event. - * It must be positive otherwise {@link #build()} will throw an exception. - * @return this. - */ - public abstract Builder setMaxNumberOfAttributesPerEvent(int maxNumberOfAttributesPerEvent); - - /** - * Sets the global default max number of attributes per link. - * - * @param maxNumberOfAttributesPerLink the global default max number of attributes per link. It - * must be positive otherwise {@link #build()} will throw an exception. - * @return this. - */ - public abstract Builder setMaxNumberOfAttributesPerLink(int maxNumberOfAttributesPerLink); - - /** - * Sets the global default max length of string attribute value in characters. - * - * @param maxLengthOfAttributeValues the global default max length of string attribute value in - * characters. It must be non-negative (or {@link #UNLIMITED_ATTRIBUTE_LENGTH}) otherwise - * {@link #build()} will throw an exception. - * @return this. - */ - public abstract Builder setMaxLengthOfAttributeValues(int maxLengthOfAttributeValues); - - abstract TraceConfig autoBuild(); - - /** - * Builds and returns a {@code TraceConfig} with the desired values. - * - * @return a {@code TraceConfig} with the desired values. - * @throws IllegalArgumentException if any of the max numbers are not positive. - */ - public TraceConfig build() { - TraceConfig traceConfig = autoBuild(); - if (traceConfig.getMaxNumberOfAttributes() <= 0) { - throw new IllegalArgumentException("maxNumberOfAttributes must be greater than 0"); - } - if (traceConfig.getMaxNumberOfEvents() <= 0) { - throw new IllegalArgumentException("maxNumberOfEvents must be greater than 0"); - } - if (traceConfig.getMaxNumberOfLinks() <= 0) { - throw new IllegalArgumentException("maxNumberOfLinks must be greater than 0"); - } - if (traceConfig.getMaxNumberOfAttributesPerEvent() <= 0) { - throw new IllegalArgumentException("maxNumberOfAttributesPerEvent must be greater than 0"); - } - if (traceConfig.getMaxNumberOfAttributesPerLink() <= 0) { - throw new IllegalArgumentException("maxNumberOfAttributesPerLink must be greater than 0"); - } - if (traceConfig.getMaxLengthOfAttributeValues() <= 0 - && traceConfig.getMaxLengthOfAttributeValues() != UNLIMITED_ATTRIBUTE_LENGTH) { - throw new IllegalArgumentException( - "maxLengthOfAttributeValues must be -1 to " - + "disable length restriction, or positive to enable length restriction"); - } - return traceConfig; - } + public TraceConfigBuilder toBuilder() { + return new TraceConfigBuilder() + .setSampler(getSampler()) + .setMaxNumberOfAttributes(getMaxNumberOfAttributes()) + .setMaxNumberOfEvents(getMaxNumberOfEvents()) + .setMaxNumberOfLinks(getMaxNumberOfLinks()) + .setMaxNumberOfAttributesPerEvent(getMaxNumberOfAttributesPerEvent()) + .setMaxNumberOfAttributesPerLink(getMaxNumberOfAttributesPerLink()) + .setMaxLengthOfAttributeValues(getMaxLengthOfAttributeValues()); } } diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/config/TraceConfigBuilder.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/config/TraceConfigBuilder.java new file mode 100644 index 0000000000..9d78a94bfd --- /dev/null +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/config/TraceConfigBuilder.java @@ -0,0 +1,251 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.trace.config; + +import static java.util.Objects.requireNonNull; + +import io.opentelemetry.api.internal.Utils; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.sdk.common.export.ConfigBuilder; +import io.opentelemetry.sdk.trace.samplers.Sampler; +import java.util.Map; +import java.util.Properties; + +/** Builder for {@link TraceConfig}. */ +public class TraceConfigBuilder extends ConfigBuilder { + private static final String KEY_SAMPLER_PROBABILITY = "otel.config.sampler.probability"; + private static final String KEY_SPAN_ATTRIBUTE_COUNT_LIMIT = "otel.span.attribute.count.limit"; + private static final String KEY_SPAN_EVENT_COUNT_LIMIT = "otel.span.event.count.limit"; + private static final String KEY_SPAN_LINK_COUNT_LIMIT = "otel.span.link.count.limit"; + private static final String KEY_SPAN_MAX_NUM_ATTRIBUTES_PER_EVENT = "otel.config.max.event.attrs"; + private static final String KEY_SPAN_MAX_NUM_ATTRIBUTES_PER_LINK = "otel.config.max.link.attrs"; + private static final String KEY_SPAN_ATTRIBUTE_MAX_VALUE_LENGTH = "otel.config.max.attr.length"; + + private static final Sampler DEFAULT_SAMPLER = Sampler.parentBased(Sampler.alwaysOn()); + private static final int DEFAULT_SPAN_MAX_NUM_ATTRIBUTES = 1000; + private static final int DEFAULT_SPAN_MAX_NUM_EVENTS = 1000; + private static final int DEFAULT_SPAN_MAX_NUM_LINKS = 1000; + private static final int DEFAULT_SPAN_MAX_NUM_ATTRIBUTES_PER_EVENT = 32; + private static final int DEFAULT_SPAN_MAX_NUM_ATTRIBUTES_PER_LINK = 32; + private static final int DEFAULT_MAX_ATTRIBUTE_LENGTH = TraceConfig.UNLIMITED_ATTRIBUTE_LENGTH; + + private Sampler sampler = DEFAULT_SAMPLER; + private int maxNumAttributes = DEFAULT_SPAN_MAX_NUM_ATTRIBUTES; + private int maxNumEvents = DEFAULT_SPAN_MAX_NUM_EVENTS; + private int maxNumLinks = DEFAULT_SPAN_MAX_NUM_LINKS; + private int maxNumAttributesPerEvent = DEFAULT_SPAN_MAX_NUM_ATTRIBUTES_PER_EVENT; + private int maxNumAttributesPerLink = DEFAULT_SPAN_MAX_NUM_ATTRIBUTES_PER_LINK; + private int maxAttributeLength = DEFAULT_MAX_ATTRIBUTE_LENGTH; + + TraceConfigBuilder() {} + + /** + * Sets the configuration values from the given configuration map for only the available keys. + * + * @param configMap {@link Map} holding the configuration values. + * @return this + */ + // Visible for testing + @Override + protected TraceConfigBuilder fromConfigMap( + Map configMap, NamingConvention namingConvention) { + configMap = namingConvention.normalize(configMap); + Double doubleValue = getDoubleProperty(KEY_SAMPLER_PROBABILITY, configMap); + if (doubleValue != null) { + this.setTraceIdRatioBased(doubleValue); + } + Integer intValue = getIntProperty(KEY_SPAN_ATTRIBUTE_COUNT_LIMIT, configMap); + if (intValue != null) { + this.setMaxNumberOfAttributes(intValue); + } + intValue = getIntProperty(KEY_SPAN_EVENT_COUNT_LIMIT, configMap); + if (intValue != null) { + this.setMaxNumberOfEvents(intValue); + } + intValue = getIntProperty(KEY_SPAN_LINK_COUNT_LIMIT, configMap); + if (intValue != null) { + this.setMaxNumberOfLinks(intValue); + } + intValue = getIntProperty(KEY_SPAN_MAX_NUM_ATTRIBUTES_PER_EVENT, configMap); + if (intValue != null) { + this.setMaxNumberOfAttributesPerEvent(intValue); + } + intValue = getIntProperty(KEY_SPAN_MAX_NUM_ATTRIBUTES_PER_LINK, configMap); + if (intValue != null) { + this.setMaxNumberOfAttributesPerLink(intValue); + } + intValue = getIntProperty(KEY_SPAN_ATTRIBUTE_MAX_VALUE_LENGTH, configMap); + if (intValue != null) { + this.setMaxLengthOfAttributeValues(intValue); + } + return this; + } + + /** + * * Sets the configuration values from the given properties object for only the available keys. + * + * @param properties {@link Properties} holding the configuration values. + * @return this + */ + @Override + public TraceConfigBuilder readProperties(Properties properties) { + return super.readProperties(properties); + } + + /** + * * Sets the configuration values from environment variables for only the available keys. + * + * @return this. + */ + @Override + public TraceConfigBuilder readEnvironmentVariables() { + return super.readEnvironmentVariables(); + } + + /** + * * Sets the configuration values from system properties for only the available keys. + * + * @return this. + */ + @Override + public TraceConfigBuilder readSystemProperties() { + return super.readSystemProperties(); + } + + /** + * Sets the global default {@code Sampler}. It must be not {@code null} otherwise {@link #build()} + * will throw an exception. + * + * @param sampler the global default {@code Sampler}. + * @return this. + */ + public TraceConfigBuilder setSampler(Sampler sampler) { + requireNonNull(sampler, "sampler"); + this.sampler = sampler; + return this; + } + + /** + * Sets the global default {@code Sampler}. It must be not {@code null} otherwise {@link #build()} + * will throw an exception. + * + * @param samplerRatio the global default ratio used to make decisions on {@link Span} sampling. + * @return this. + */ + public TraceConfigBuilder setTraceIdRatioBased(double samplerRatio) { + Utils.checkArgument(samplerRatio >= 0, "samplerRatio must be greater than or equal to 0."); + Utils.checkArgument(samplerRatio <= 1, "samplerRatio must be lesser than or equal to 1."); + if (samplerRatio == 1) { + setSampler(Sampler.parentBased(Sampler.alwaysOn())); + } else if (samplerRatio == 0) { + setSampler(Sampler.alwaysOff()); + } else { + setSampler(Sampler.parentBased(Sampler.traceIdRatioBased(samplerRatio))); + } + return this; + } + + /** + * Sets the global default max number of attributes per {@link Span}. + * + * @param maxNumberOfAttributes the global default max number of attributes per {@link Span}. It + * must be positive otherwise {@link #build()} will throw an exception. + * @return this. + */ + public TraceConfigBuilder setMaxNumberOfAttributes(int maxNumberOfAttributes) { + Utils.checkArgument(maxNumberOfAttributes > 0, "maxNumberOfAttributes must be greater than 0"); + this.maxNumAttributes = maxNumberOfAttributes; + return this; + } + + /** + * Sets the global default max number of events per {@link Span}. + * + * @param maxNumberOfEvents the global default max number of events per {@link Span}. It must be + * positive otherwise {@link #build()} will throw an exception. + * @return this. + */ + public TraceConfigBuilder setMaxNumberOfEvents(int maxNumberOfEvents) { + Utils.checkArgument(maxNumberOfEvents > 0, "maxNumberOfEvents must be greater than 0"); + this.maxNumEvents = maxNumberOfEvents; + return this; + } + + /** + * Sets the global default max number of links per {@link Span}. + * + * @param maxNumberOfLinks the global default max number of links per {@link Span}. It must be + * positive otherwise {@link #build()} will throw an exception. + * @return this. + */ + public TraceConfigBuilder setMaxNumberOfLinks(int maxNumberOfLinks) { + Utils.checkArgument(maxNumberOfLinks > 0, "maxNumberOfLinks must be greater than 0"); + this.maxNumLinks = maxNumberOfLinks; + return this; + } + + /** + * Sets the global default max number of attributes per event. + * + * @param maxNumberOfAttributesPerEvent the global default max number of attributes per event. It + * must be positive otherwise {@link #build()} will throw an exception. + * @return this. + */ + public TraceConfigBuilder setMaxNumberOfAttributesPerEvent(int maxNumberOfAttributesPerEvent) { + Utils.checkArgument( + maxNumberOfAttributesPerEvent > 0, "maxNumberOfAttributesPerEvent must be greater than 0"); + this.maxNumAttributesPerEvent = maxNumberOfAttributesPerEvent; + return this; + } + + /** + * Sets the global default max number of attributes per link. + * + * @param maxNumberOfAttributesPerLink the global default max number of attributes per link. It + * must be positive otherwise {@link #build()} will throw an exception. + * @return this. + */ + public TraceConfigBuilder setMaxNumberOfAttributesPerLink(int maxNumberOfAttributesPerLink) { + Utils.checkArgument( + maxNumberOfAttributesPerLink > 0, "maxNumberOfAttributesPerLink must be greater than 0"); + this.maxNumAttributesPerLink = maxNumberOfAttributesPerLink; + return this; + } + + /** + * Sets the global default max length of string attribute value in characters. + * + * @param maxLengthOfAttributeValues the global default max length of string attribute value in + * characters. It must be non-negative (or {@link TraceConfig#UNLIMITED_ATTRIBUTE_LENGTH}) + * otherwise {@link #build()} will throw an exception. + * @return this. + */ + public TraceConfigBuilder setMaxLengthOfAttributeValues(int maxLengthOfAttributeValues) { + Utils.checkArgument( + maxLengthOfAttributeValues == -1 || maxLengthOfAttributeValues > 0, + "maxLengthOfAttributeValues must be -1 to " + + "disable length restriction, or positive to enable length restriction"); + this.maxAttributeLength = maxLengthOfAttributeValues; + return this; + } + + /** + * Builds and returns a {@code TraceConfig} with the desired values. + * + * @return a {@code TraceConfig} with the desired values. + * @throws IllegalArgumentException if any of the max numbers are not positive. + */ + public TraceConfig build() { + return TraceConfig.create( + sampler, + maxNumAttributes, + maxNumEvents, + maxNumLinks, + maxNumAttributesPerEvent, + maxNumAttributesPerLink, + maxAttributeLength); + } +} diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/config/TraceConfigTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/config/TraceConfigTest.java index 4fd0106982..e560b776b5 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/config/TraceConfigTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/config/TraceConfigTest.java @@ -27,57 +27,56 @@ class TraceConfigTest { @Test void updateTraceConfig_NullSampler() { assertThrows( - NullPointerException.class, - () -> TraceConfig.getDefault().toBuilder().setSampler(null).build()); + NullPointerException.class, () -> TraceConfig.getDefault().toBuilder().setSampler(null)); } @Test void updateTraceConfig_NonPositiveMaxNumberOfAttributes() { assertThrows( IllegalArgumentException.class, - () -> TraceConfig.getDefault().toBuilder().setMaxNumberOfAttributes(0).build()); + () -> TraceConfig.getDefault().toBuilder().setMaxNumberOfAttributes(0)); } @Test void updateTraceConfig_NonPositiveMaxNumberOfEvents() { assertThrows( IllegalArgumentException.class, - () -> TraceConfig.getDefault().toBuilder().setMaxNumberOfEvents(0).build()); + () -> TraceConfig.getDefault().toBuilder().setMaxNumberOfEvents(0)); } @Test void updateTraceConfig_NonPositiveMaxNumberOfLinks() { assertThrows( IllegalArgumentException.class, - () -> TraceConfig.getDefault().toBuilder().setMaxNumberOfLinks(0).build()); + () -> TraceConfig.getDefault().toBuilder().setMaxNumberOfLinks(0)); } @Test void updateTraceConfig_NonPositiveMaxNumberOfAttributesPerEvent() { assertThrows( IllegalArgumentException.class, - () -> TraceConfig.getDefault().toBuilder().setMaxNumberOfAttributesPerEvent(0).build()); + () -> TraceConfig.getDefault().toBuilder().setMaxNumberOfAttributesPerEvent(0)); } @Test void updateTraceConfig_NonPositiveMaxNumberOfAttributesPerLink() { assertThrows( IllegalArgumentException.class, - () -> TraceConfig.getDefault().toBuilder().setMaxNumberOfAttributesPerLink(0).build()); + () -> TraceConfig.getDefault().toBuilder().setMaxNumberOfAttributesPerLink(0)); } @Test void updateTraceConfig_InvalidTraceIdRatioBased() { assertThrows( IllegalArgumentException.class, - () -> TraceConfig.getDefault().toBuilder().setTraceIdRatioBased(2).build()); + () -> TraceConfig.getDefault().toBuilder().setTraceIdRatioBased(2)); } @Test void updateTraceConfig_NegativeTraceIdRatioBased() { assertThrows( IllegalArgumentException.class, - () -> TraceConfig.getDefault().toBuilder().setTraceIdRatioBased(-1).build()); + () -> TraceConfig.getDefault().toBuilder().setTraceIdRatioBased(-1)); } @Test @@ -111,5 +110,10 @@ class TraceConfigTest { assertThat(traceConfig.getMaxNumberOfLinks()).isEqualTo(11); assertThat(traceConfig.getMaxNumberOfAttributesPerEvent()).isEqualTo(1); assertThat(traceConfig.getMaxNumberOfAttributesPerLink()).isEqualTo(2); + + // Preserves values + TraceConfig traceConfigDupe = traceConfig.toBuilder().build(); + // Use reflective comparison to catch when new fields are added. + assertThat(traceConfigDupe).usingRecursiveComparison().isEqualTo(traceConfig); } }