From 98c2c9d96c84816d1a6a65440b5a8c45bc748bfe Mon Sep 17 00:00:00 2001 From: Will Li Date: Fri, 18 Feb 2022 00:21:13 +0800 Subject: [PATCH] Add env support for span limits configuration (#2606) * add env support for otel_span configuration Signed-off-by: Cuichen Li * update changelog * update changelog and some logic based on comment * Update CHANGELOG.md Co-authored-by: Anthony Mirabella * add document about retrieve value from environment variable Signed-off-by: Cuichen Li * remove trailing whitespace Signed-off-by: Cuichen Li * parse environment variable before apply the options * Update CHANGELOG.md Co-authored-by: Tyler Yahn * Update sdk/trace/provider_test.go Co-authored-by: Tyler Yahn * Update CHANGELOG.md Co-authored-by: Anthony Mirabella Co-authored-by: Tyler Yahn --- CHANGELOG.md | 10 +++++++ sdk/internal/env/env.go | 15 ++++++++++ sdk/trace/config.go | 16 ++++++++++ sdk/trace/provider.go | 1 + sdk/trace/provider_test.go | 61 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 103 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b2bcfe09bf..59d0b7bad66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,16 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [Unreleased] +### Added + +- Added support to configure the span limits with environment variables. + The following environment variables are used. (#2606) + - `OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT` + - `OTEL_SPAN_EVENT_COUNT_LIMIT` + - `OTEL_SPAN_LINK_COUNT_LIMIT` + + If the provided environment variables are invalid (negative), the default values would be used. + ### Changed - Add event and link drop counts to the exported data from the `oltptrace` exporter. (#2601) diff --git a/sdk/internal/env/env.go b/sdk/internal/env/env.go index 397fd9593cc..df7a05626b3 100644 --- a/sdk/internal/env/env.go +++ b/sdk/internal/env/env.go @@ -40,6 +40,21 @@ const ( // Note: Must be less than or equal to EnvBatchSpanProcessorMaxQueueSize // i.e. 512 BatchSpanProcessorMaxExportBatchSizeKey = "OTEL_BSP_MAX_EXPORT_BATCH_SIZE" + + // SpanAttributesCountKey + // Maximum allowed span attribute count + // Default: 128 + SpanAttributesCountKey = "OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT" + + // SpanEventCountKey + // Maximum allowed span event count + // Default: 128 + SpanEventCountKey = "OTEL_SPAN_EVENT_COUNT_LIMIT" + + // SpanLinkCountKey + // Maximum allowed span link count + // Default: 128 + SpanLinkCountKey = "OTEL_SPAN_LINK_COUNT_LIMIT" ) // IntEnvOr returns the int value of the environment variable with name key if diff --git a/sdk/trace/config.go b/sdk/trace/config.go index 61a30439251..efea7b302f9 100644 --- a/sdk/trace/config.go +++ b/sdk/trace/config.go @@ -13,6 +13,7 @@ // limitations under the License. package trace // import "go.opentelemetry.io/otel/sdk/trace" +import "go.opentelemetry.io/otel/sdk/internal/env" // SpanLimits represents the limits of a span. type SpanLimits struct { @@ -50,14 +51,29 @@ func (sl *SpanLimits) ensureDefault() { } } +func (sl *SpanLimits) parsePotentialEnvConfigs() { + sl.AttributeCountLimit = env.IntEnvOr(env.SpanAttributesCountKey, sl.AttributeCountLimit) + sl.LinkCountLimit = env.IntEnvOr(env.SpanLinkCountKey, sl.LinkCountLimit) + sl.EventCountLimit = env.IntEnvOr(env.SpanEventCountKey, sl.EventCountLimit) +} + const ( // DefaultAttributeCountLimit is the default maximum allowed span attribute count. + // If not specified via WithSpanLimits, will try to retrieve the value from + // environment variable `OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT`. + // If Invalid value (negative or zero) is provided, the default value 128 will be used. DefaultAttributeCountLimit = 128 // DefaultEventCountLimit is the default maximum allowed span event count. + // If not specified via WithSpanLimits, will try to retrieve the value from + // environment variable `OTEL_SPAN_EVENT_COUNT_LIMIT`. + // If Invalid value (negative or zero) is provided, the default value 128 will be used. DefaultEventCountLimit = 128 // DefaultLinkCountLimit is the default maximum allowed span link count. + // If the value is not specified via WithSpanLimits, will try to retrieve the value from + // environment variable `OTEL_SPAN_LINK_COUNT_LIMIT`. + // If Invalid value (negative or zero) is provided, the default value 128 will be used. DefaultLinkCountLimit = 128 // DefaultAttributePerEventCountLimit is the default maximum allowed attribute per span event count. diff --git a/sdk/trace/provider.go b/sdk/trace/provider.go index c6b311f9cdc..2de79f03397 100644 --- a/sdk/trace/provider.go +++ b/sdk/trace/provider.go @@ -98,6 +98,7 @@ var _ trace.TracerProvider = &TracerProvider{} func NewTracerProvider(opts ...TracerProviderOption) *TracerProvider { o := tracerProviderConfig{} + o.spanLimits.parsePotentialEnvConfigs() for _, opt := range opts { o = opt.apply(o) } diff --git a/sdk/trace/provider_test.go b/sdk/trace/provider_test.go index e2fce31d7f7..0633889bdc2 100644 --- a/sdk/trace/provider_test.go +++ b/sdk/trace/provider_test.go @@ -17,8 +17,14 @@ package trace import ( "context" "errors" + "os" "testing" + "github.com/stretchr/testify/require" + + ottest "go.opentelemetry.io/otel/internal/internaltest" + "go.opentelemetry.io/otel/sdk/internal/env" + "github.com/stretchr/testify/assert" "go.opentelemetry.io/otel/trace" @@ -94,3 +100,58 @@ func TestSchemaURL(t *testing.T) { tracerStruct := tracerIface.(*tracer) assert.EqualValues(t, schemaURL, tracerStruct.instrumentationLibrary.SchemaURL) } + +func TestNewTraceProviderWithoutSpanLimitConfiguration(t *testing.T) { + envStore := ottest.NewEnvStore() + defer func() { + require.NoError(t, envStore.Restore()) + }() + envStore.Record(env.SpanAttributesCountKey) + envStore.Record(env.SpanEventCountKey) + envStore.Record(env.SpanLinkCountKey) + require.NoError(t, os.Setenv(env.SpanEventCountKey, "111")) + require.NoError(t, os.Setenv(env.SpanAttributesCountKey, "222")) + require.NoError(t, os.Setenv(env.SpanLinkCountKey, "333")) + tp := NewTracerProvider() + assert.Equal(t, 111, tp.spanLimits.EventCountLimit) + assert.Equal(t, 222, tp.spanLimits.AttributeCountLimit) + assert.Equal(t, 333, tp.spanLimits.LinkCountLimit) +} + +func TestNewTraceProviderWithSpanLimitConfigurationFromOptsAndEnvironmentVariable(t *testing.T) { + envStore := ottest.NewEnvStore() + defer func() { + require.NoError(t, envStore.Restore()) + }() + envStore.Record(env.SpanAttributesCountKey) + envStore.Record(env.SpanEventCountKey) + envStore.Record(env.SpanLinkCountKey) + require.NoError(t, os.Setenv(env.SpanEventCountKey, "111")) + require.NoError(t, os.Setenv(env.SpanAttributesCountKey, "222")) + require.NoError(t, os.Setenv(env.SpanLinkCountKey, "333")) + tp := NewTracerProvider(WithSpanLimits(SpanLimits{ + EventCountLimit: 1, + AttributeCountLimit: 2, + LinkCountLimit: 3, + })) + assert.Equal(t, 1, tp.spanLimits.EventCountLimit) + assert.Equal(t, 2, tp.spanLimits.AttributeCountLimit) + assert.Equal(t, 3, tp.spanLimits.LinkCountLimit) +} + +func TestNewTraceProviderWithInvalidSpanLimitConfigurationFromEnvironmentVariable(t *testing.T) { + envStore := ottest.NewEnvStore() + defer func() { + require.NoError(t, envStore.Restore()) + }() + envStore.Record(env.SpanAttributesCountKey) + envStore.Record(env.SpanEventCountKey) + envStore.Record(env.SpanLinkCountKey) + require.NoError(t, os.Setenv(env.SpanEventCountKey, "-111")) + require.NoError(t, os.Setenv(env.SpanAttributesCountKey, "-222")) + require.NoError(t, os.Setenv(env.SpanLinkCountKey, "-333")) + tp := NewTracerProvider() + assert.Equal(t, 128, tp.spanLimits.EventCountLimit) + assert.Equal(t, 128, tp.spanLimits.AttributeCountLimit) + assert.Equal(t, 128, tp.spanLimits.LinkCountLimit) +}