From ab2d1374a83fd9c8f926989eab31928524d4fe5c Mon Sep 17 00:00:00 2001 From: Brian Marks Date: Thu, 23 Jul 2026 18:39:31 -0400 Subject: [PATCH 1/2] feat(tracer): add OTLP export flags to startup diagnostic log Add three boolean fields to the "DATADOG TRACER CONFIGURATION" startup log indicating whether each telemetry signal is exported over OTLP: - otlp_traces_export_enabled (tracer's cached otlpExportMode, which reflects that CI-Visibility and log-to-stdout writers are selected ahead of the OTLP writer) - otlp_metrics_export_enabled (OTel metrics signal enabled AND the OTLP metrics exporter selected: RuntimeMetricsOtelEnabled() && OTLPExportMetricsMode(); defaults to false, matching the other tracers) - otlp_logs_export_enabled (config LogsOTelEnabled) Update the startup-log golden assertions and clear the OTLP-driving env vars in the test so the expected output is deterministic regardless of shell/CI env pollution. Add a positive case asserting the metrics field is true when the OTel metrics signal and OTLP exporter are both active. Co-Authored-By: Claude Opus 4.8 (1M context) --- ddtrace/tracer/log.go | 16 +++++++++++----- ddtrace/tracer/log_test.go | 35 +++++++++++++++++++++++++++++++---- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/ddtrace/tracer/log.go b/ddtrace/tracer/log.go index 774caa365a..b208cb7793 100644 --- a/ddtrace/tracer/log.go +++ b/ddtrace/tracer/log.go @@ -78,11 +78,14 @@ type startupInfo struct { PartialFlushMinSpans int `json:"partial_flush_min_spans"` // The min number of spans to trigger a partial flush Orchestrion orchestrionConfig `json:"orchestrion"` // Orchestrion (auto-instrumentation) configuration. FeatureFlags []string `json:"feature_flags"` - PropagationStyleInject string `json:"propagation_style_inject"` // Propagation style for inject - PropagationStyleExtract string `json:"propagation_style_extract"` // Propagation style for extract - TracingAsTransport bool `json:"tracing_as_transport"` // Whether the tracer is disabled and other products are using it as a transport - DogstatsdAddr string `json:"dogstatsd_address"` // Destination of statsd payloads - DataStreamsEnabled bool `json:"data_streams_enabled"` // Whether Data Streams is enabled + PropagationStyleInject string `json:"propagation_style_inject"` // Propagation style for inject + PropagationStyleExtract string `json:"propagation_style_extract"` // Propagation style for extract + TracingAsTransport bool `json:"tracing_as_transport"` // Whether the tracer is disabled and other products are using it as a transport + DogstatsdAddr string `json:"dogstatsd_address"` // Destination of statsd payloads + DataStreamsEnabled bool `json:"data_streams_enabled"` // Whether Data Streams is enabled + OTLPTracesExportEnabled bool `json:"otlp_traces_export_enabled"` // Whether traces are exported over OTLP + OTLPMetricsExportEnabled bool `json:"otlp_metrics_export_enabled"` // Whether metrics are exported over OTLP + OTLPLogsExportEnabled bool `json:"otlp_logs_export_enabled"` // Whether logs are exported over OTLP } // checkEndpoint tries to connect to the URL specified by endpoint. @@ -187,6 +190,9 @@ func logStartup(t *tracer) { TracingAsTransport: t.config.tracingAsTransport, DogstatsdAddr: t.config.internalConfig.DogstatsdAddr(), DataStreamsEnabled: t.config.internalConfig.DataStreamsMonitoringEnabled(), + OTLPTracesExportEnabled: t.otlpExportMode, + OTLPMetricsExportEnabled: t.config.internalConfig.RuntimeMetricsOtelEnabled() && t.config.internalConfig.OTLPExportMetricsMode(), + OTLPLogsExportEnabled: t.config.internalConfig.LogsOTelEnabled(), } if limit, ok := t.rulesSampling.TraceRateLimit(); ok { info.SampleRateLimit = fmt.Sprintf("%v", limit) diff --git a/ddtrace/tracer/log_test.go b/ddtrace/tracer/log_test.go index fb3c817124..f81614a666 100644 --- a/ddtrace/tracer/log_test.go +++ b/ddtrace/tracer/log_test.go @@ -25,6 +25,15 @@ const logPrefixRegexp = `Datadog Tracer v[0-9]+\.[0-9]+\.[0-9]+(-((rc|beta)\.[0- var commonLogIgnore = []string{"appsec: ", "telemetry", "Runtime metrics v2 enabled"} func TestStartupLog(t *testing.T) { + // Make the OTLP export fields deterministic regardless of any OTEL_*/DD_* + // env pollution in the dev/CI shell. Empty values are treated as unset by + // the config provider, so each field falls back to its default of false: + // traces export to the agent, the OTel metrics signal is off, and logs are + // off. This matches the golden output in the sub-tests below. + t.Setenv("OTEL_TRACES_EXPORTER", "") + t.Setenv("DD_METRICS_OTEL_ENABLED", "") + t.Setenv("DD_LOGS_OTEL_ENABLED", "") + t.Run("basic", func(t *testing.T) { assert := assert.New(t) tp := new(log.RecordLogger) @@ -36,7 +45,7 @@ func TestStartupLog(t *testing.T) { tp.Ignore(commonLogIgnore...) logStartup(tracer) require.Len(t, tp.Logs(), 2) - assert.Regexp(logPrefixRegexp+` INFO: DATADOG TRACER CONFIGURATION {"date":"[^"]*","os_name":"[^"]*","os_version":"[^"]*","version":"[^"]*","lang":"Go","lang_version":"[^"]*","env":"","service":"tracer\.test(\.exe)?","agent_url":"http://localhost:9/v1.0/traces","agent_error":"Post .*","debug":false,"analytics_enabled":false,"sample_rate":"NaN","sample_rate_limit":"disabled","trace_sampling_rules":null,"span_sampling_rules":null,"sampling_rules_error":"","service_mappings":null,"tags":{"runtime-id":"[^"]*"},"runtime_metrics_enabled":false,"runtime_metrics_v2_enabled":true,"profiler_code_hotspots_enabled":((false)|(true)),"profiler_endpoints_enabled":((false)|(true)),"dd_version":"","architecture":"[^"]*","global_service":"","lambda_mode":"false","appsec":((true)|(false)),"agent_features":{"DropP0s":true,"Stats":true,"StatsdPort":(0|8125)},"integrations":{.*},"partial_flush_enabled":false,"partial_flush_min_spans":1000,"orchestrion":{"enabled":false},"feature_flags":\[\],"propagation_style_inject":"datadog,tracecontext,baggage","propagation_style_extract":"datadog,tracecontext,baggage","tracing_as_transport":false,"dogstatsd_address":"localhost:8125","data_streams_enabled":false}`, tp.Logs()[1]) + assert.Regexp(logPrefixRegexp+` INFO: DATADOG TRACER CONFIGURATION {"date":"[^"]*","os_name":"[^"]*","os_version":"[^"]*","version":"[^"]*","lang":"Go","lang_version":"[^"]*","env":"","service":"tracer\.test(\.exe)?","agent_url":"http://localhost:9/v1.0/traces","agent_error":"Post .*","debug":false,"analytics_enabled":false,"sample_rate":"NaN","sample_rate_limit":"disabled","trace_sampling_rules":null,"span_sampling_rules":null,"sampling_rules_error":"","service_mappings":null,"tags":{"runtime-id":"[^"]*"},"runtime_metrics_enabled":false,"runtime_metrics_v2_enabled":true,"profiler_code_hotspots_enabled":((false)|(true)),"profiler_endpoints_enabled":((false)|(true)),"dd_version":"","architecture":"[^"]*","global_service":"","lambda_mode":"false","appsec":((true)|(false)),"agent_features":{"DropP0s":true,"Stats":true,"StatsdPort":(0|8125)},"integrations":{.*},"partial_flush_enabled":false,"partial_flush_min_spans":1000,"orchestrion":{"enabled":false},"feature_flags":\[\],"propagation_style_inject":"datadog,tracecontext,baggage","propagation_style_extract":"datadog,tracecontext,baggage","tracing_as_transport":false,"dogstatsd_address":"localhost:8125","data_streams_enabled":false,"otlp_traces_export_enabled":false,"otlp_metrics_export_enabled":false,"otlp_logs_export_enabled":false}`, tp.Logs()[1]) }) t.Run("configured", func(t *testing.T) { @@ -68,7 +77,7 @@ func TestStartupLog(t *testing.T) { tp.Ignore(commonLogIgnore...) logStartup(tracer) require.Len(t, tp.Logs(), 2) - assert.Regexp(logPrefixRegexp+` INFO: DATADOG TRACER CONFIGURATION {"date":"[^"]*","os_name":"[^"]*","os_version":"[^"]*","version":"[^"]*","lang":"Go","lang_version":"[^"]*","env":"configuredEnv","service":"configured.service","agent_url":"http://localhost:9/v1.0/traces","agent_error":"Post .*","debug":true,"analytics_enabled":true,"sample_rate":"0\.123000","sample_rate_limit":"100","trace_sampling_rules":\[{"service":"mysql","sample_rate":0\.75}\],"span_sampling_rules":null,"sampling_rules_error":"","service_mappings":{"initial_service":"new_service"},"tags":{"runtime-id":"[^"]*","tag":"value","tag2":"NaN"},"runtime_metrics_enabled":true,"runtime_metrics_v2_enabled":true,"profiler_code_hotspots_enabled":((false)|(true)),"profiler_endpoints_enabled":((false)|(true)),"dd_version":"2.3.4","architecture":"[^"]*","global_service":"configured.service","lambda_mode":"false","appsec":((true)|(false)),"agent_features":{"DropP0s":true,"Stats":true,"StatsdPort":(0|8125)},"integrations":{.*},"partial_flush_enabled":false,"partial_flush_min_spans":1000,"orchestrion":{"enabled":(false|true,"metadata":{"version":"v\d+.\d+.\d+(-[^"]+)?"})},"feature_flags":\["discovery"\],"propagation_style_inject":"datadog,tracecontext,baggage","propagation_style_extract":"datadog,tracecontext,baggage","tracing_as_transport":false,"dogstatsd_address":"localhost:8125","data_streams_enabled":false}`, tp.Logs()[1]) + assert.Regexp(logPrefixRegexp+` INFO: DATADOG TRACER CONFIGURATION {"date":"[^"]*","os_name":"[^"]*","os_version":"[^"]*","version":"[^"]*","lang":"Go","lang_version":"[^"]*","env":"configuredEnv","service":"configured.service","agent_url":"http://localhost:9/v1.0/traces","agent_error":"Post .*","debug":true,"analytics_enabled":true,"sample_rate":"0\.123000","sample_rate_limit":"100","trace_sampling_rules":\[{"service":"mysql","sample_rate":0\.75}\],"span_sampling_rules":null,"sampling_rules_error":"","service_mappings":{"initial_service":"new_service"},"tags":{"runtime-id":"[^"]*","tag":"value","tag2":"NaN"},"runtime_metrics_enabled":true,"runtime_metrics_v2_enabled":true,"profiler_code_hotspots_enabled":((false)|(true)),"profiler_endpoints_enabled":((false)|(true)),"dd_version":"2.3.4","architecture":"[^"]*","global_service":"configured.service","lambda_mode":"false","appsec":((true)|(false)),"agent_features":{"DropP0s":true,"Stats":true,"StatsdPort":(0|8125)},"integrations":{.*},"partial_flush_enabled":false,"partial_flush_min_spans":1000,"orchestrion":{"enabled":(false|true,"metadata":{"version":"v\d+.\d+.\d+(-[^"]+)?"})},"feature_flags":\["discovery"\],"propagation_style_inject":"datadog,tracecontext,baggage","propagation_style_extract":"datadog,tracecontext,baggage","tracing_as_transport":false,"dogstatsd_address":"localhost:8125","data_streams_enabled":false,"otlp_traces_export_enabled":false,"otlp_metrics_export_enabled":false,"otlp_logs_export_enabled":false}`, tp.Logs()[1]) }) t.Run("limit", func(t *testing.T) { @@ -99,7 +108,7 @@ func TestStartupLog(t *testing.T) { tp.Ignore(commonLogIgnore...) logStartup(tracer) require.Len(t, tp.Logs(), 2) - assert.Regexp(logPrefixRegexp+` INFO: DATADOG TRACER CONFIGURATION {"date":"[^"]*","os_name":"[^"]*","os_version":"[^"]*","version":"[^"]*","lang":"Go","lang_version":"[^"]*","env":"configuredEnv","service":"configured.service","agent_url":"http://localhost:9/v1.0/traces","agent_error":"Post .*","debug":true,"analytics_enabled":true,"sample_rate":"0\.123000","sample_rate_limit":"1000.001","trace_sampling_rules":\[{"service":"mysql","sample_rate":0\.75}\],"span_sampling_rules":null,"sampling_rules_error":"","service_mappings":{"initial_service":"new_service"},"tags":{"runtime-id":"[^"]*","tag":"value","tag2":"NaN"},"runtime_metrics_enabled":true,"runtime_metrics_v2_enabled":true,"profiler_code_hotspots_enabled":((false)|(true)),"profiler_endpoints_enabled":((false)|(true)),"dd_version":"2.3.4","architecture":"[^"]*","global_service":"configured.service","lambda_mode":"false","appsec":((true)|(false)),"agent_features":{"DropP0s":true,"Stats":true,"StatsdPort":(0|8125)},"integrations":{.*},"partial_flush_enabled":false,"partial_flush_min_spans":1000,"orchestrion":{"enabled":false},"feature_flags":\[\],"propagation_style_inject":"datadog,tracecontext,baggage","propagation_style_extract":"datadog,tracecontext,baggage","tracing_as_transport":false,"dogstatsd_address":"localhost:8125","data_streams_enabled":false}`, tp.Logs()[1]) + assert.Regexp(logPrefixRegexp+` INFO: DATADOG TRACER CONFIGURATION {"date":"[^"]*","os_name":"[^"]*","os_version":"[^"]*","version":"[^"]*","lang":"Go","lang_version":"[^"]*","env":"configuredEnv","service":"configured.service","agent_url":"http://localhost:9/v1.0/traces","agent_error":"Post .*","debug":true,"analytics_enabled":true,"sample_rate":"0\.123000","sample_rate_limit":"1000.001","trace_sampling_rules":\[{"service":"mysql","sample_rate":0\.75}\],"span_sampling_rules":null,"sampling_rules_error":"","service_mappings":{"initial_service":"new_service"},"tags":{"runtime-id":"[^"]*","tag":"value","tag2":"NaN"},"runtime_metrics_enabled":true,"runtime_metrics_v2_enabled":true,"profiler_code_hotspots_enabled":((false)|(true)),"profiler_endpoints_enabled":((false)|(true)),"dd_version":"2.3.4","architecture":"[^"]*","global_service":"configured.service","lambda_mode":"false","appsec":((true)|(false)),"agent_features":{"DropP0s":true,"Stats":true,"StatsdPort":(0|8125)},"integrations":{.*},"partial_flush_enabled":false,"partial_flush_min_spans":1000,"orchestrion":{"enabled":false},"feature_flags":\[\],"propagation_style_inject":"datadog,tracecontext,baggage","propagation_style_extract":"datadog,tracecontext,baggage","tracing_as_transport":false,"dogstatsd_address":"localhost:8125","data_streams_enabled":false,"otlp_traces_export_enabled":false,"otlp_metrics_export_enabled":false,"otlp_logs_export_enabled":false}`, tp.Logs()[1]) }) t.Run("errors", func(t *testing.T) { @@ -121,7 +130,7 @@ func TestStartupLog(t *testing.T) { tp.Ignore(commonLogIgnore...) logStartup(tracer) assert.Len(tp.Logs(), 1) - assert.Regexp(logPrefixRegexp+` INFO: DATADOG TRACER CONFIGURATION {"date":"[^"]*","os_name":"[^"]*","os_version":"[^"]*","version":"[^"]*","lang":"Go","lang_version":"[^"]*","env":"","service":"tracer\.test(\.exe)?","agent_url":"http://localhost:9/v1.0/traces","agent_error":"","debug":false,"analytics_enabled":false,"sample_rate":"NaN","sample_rate_limit":"disabled","trace_sampling_rules":null,"span_sampling_rules":null,"sampling_rules_error":"","service_mappings":null,"tags":{"runtime-id":"[^"]*"},"runtime_metrics_enabled":false,"runtime_metrics_v2_enabled":true,"profiler_code_hotspots_enabled":((false)|(true)),"profiler_endpoints_enabled":((false)|(true)),"dd_version":"","architecture":"[^"]*","global_service":"","lambda_mode":"true","appsec":((true)|(false)),"agent_features":{"DropP0s":true,"Stats":true,"StatsdPort":(0|8125)},"integrations":{.*},"partial_flush_enabled":false,"partial_flush_min_spans":1000,"orchestrion":{"enabled":false},"feature_flags":\[\],"propagation_style_inject":"datadog,tracecontext,baggage","propagation_style_extract":"datadog,tracecontext,baggage","tracing_as_transport":false,"dogstatsd_address":"localhost:8125","data_streams_enabled":false}`, tp.Logs()[0]) + assert.Regexp(logPrefixRegexp+` INFO: DATADOG TRACER CONFIGURATION {"date":"[^"]*","os_name":"[^"]*","os_version":"[^"]*","version":"[^"]*","lang":"Go","lang_version":"[^"]*","env":"","service":"tracer\.test(\.exe)?","agent_url":"http://localhost:9/v1.0/traces","agent_error":"","debug":false,"analytics_enabled":false,"sample_rate":"NaN","sample_rate_limit":"disabled","trace_sampling_rules":null,"span_sampling_rules":null,"sampling_rules_error":"","service_mappings":null,"tags":{"runtime-id":"[^"]*"},"runtime_metrics_enabled":false,"runtime_metrics_v2_enabled":true,"profiler_code_hotspots_enabled":((false)|(true)),"profiler_endpoints_enabled":((false)|(true)),"dd_version":"","architecture":"[^"]*","global_service":"","lambda_mode":"true","appsec":((true)|(false)),"agent_features":{"DropP0s":true,"Stats":true,"StatsdPort":(0|8125)},"integrations":{.*},"partial_flush_enabled":false,"partial_flush_min_spans":1000,"orchestrion":{"enabled":false},"feature_flags":\[\],"propagation_style_inject":"datadog,tracecontext,baggage","propagation_style_extract":"datadog,tracecontext,baggage","tracing_as_transport":false,"dogstatsd_address":"localhost:8125","data_streams_enabled":false,"otlp_traces_export_enabled":false,"otlp_metrics_export_enabled":false,"otlp_logs_export_enabled":false}`, tp.Logs()[0]) }) t.Run("integrations", func(t *testing.T) { @@ -140,6 +149,24 @@ func TestStartupLog(t *testing.T) { assert.Contains(tp.Logs()[1], expect, "expected integration %s", expect) } }) + + t.Run("otlp_metrics_export", func(t *testing.T) { + assert := assert.New(t) + tp := new(log.RecordLogger) + // The OTel metrics signal is enabled and the exporter is otlp, so + // metrics are actually exported over OTLP. Pin OTEL_METRICS_EXPORTER + // explicitly so the assertion holds even under a polluted shell. + t.Setenv("DD_METRICS_OTEL_ENABLED", "true") + t.Setenv("OTEL_METRICS_EXPORTER", "otlp") + tracer, _, _, stop, err := startTestTracer(t, WithLogger(tp)) + require.NoError(t, err) + defer stop() + tp.Reset() + tp.Ignore(commonLogIgnore...) + logStartup(tracer) + require.Len(t, tp.Logs(), 2) + assert.Contains(tp.Logs()[1], `"otlp_metrics_export_enabled":true`) + }) } func TestLogSamplingRules(t *testing.T) { From f3a578b58ae31ec887668ba7ddffc001897a3998 Mon Sep 17 00:00:00 2001 From: Brian Marks Date: Fri, 24 Jul 2026 18:47:39 -0400 Subject: [PATCH 2/2] fix(tracer): report OTLP metrics export from actual startup gate Derive otlp_metrics_export_enabled in the startup log from otelRuntimeMetricsShouldBeEnabled, the same gate the tracer uses to start OTel runtime metrics, instead of RuntimeMetricsOtelEnabled && OTLPExportMetricsMode. The old predicate over-reported: it logged true even when the opentelemetry/metric package was not imported (StartHook nil) or runtime metrics were off, so no OTLP pipeline was actually running. Logs keep reporting LogsOTelEnabled (config intent) because the user starts the OTel logs integration after the startup log is emitted, so no started-state is knowable at that point. Add a startup-log test for the config-intent-without-pipeline case and update the positive test to install a stub StartHook so the pipeline is genuinely active. Co-Authored-By: Claude Opus 4.8 (1M context) --- ddtrace/tracer/log.go | 9 +++++++-- ddtrace/tracer/log_test.go | 30 +++++++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/ddtrace/tracer/log.go b/ddtrace/tracer/log.go index b208cb7793..a2f308aeed 100644 --- a/ddtrace/tracer/log.go +++ b/ddtrace/tracer/log.go @@ -191,8 +191,13 @@ func logStartup(t *tracer) { DogstatsdAddr: t.config.internalConfig.DogstatsdAddr(), DataStreamsEnabled: t.config.internalConfig.DataStreamsMonitoringEnabled(), OTLPTracesExportEnabled: t.otlpExportMode, - OTLPMetricsExportEnabled: t.config.internalConfig.RuntimeMetricsOtelEnabled() && t.config.internalConfig.OTLPExportMetricsMode(), - OTLPLogsExportEnabled: t.config.internalConfig.LogsOTelEnabled(), + // Reports the tracer's resolved decision to start OTel runtime metrics over + // OTLP: the same gate the tracer uses (config enabled and opentelemetry/metric + // imported, so StartHook != nil), not a config-only guess. + OTLPMetricsExportEnabled: t.config.otelRuntimeMetricsShouldBeEnabled, + // The user starts the OTel logs integration (opentelemetry/log.Start) after + // this log is emitted, so no started-state is knowable here; report config intent. + OTLPLogsExportEnabled: t.config.internalConfig.LogsOTelEnabled(), } if limit, ok := t.rulesSampling.TraceRateLimit(); ok { info.SampleRateLimit = fmt.Sprintf("%v", limit) diff --git a/ddtrace/tracer/log_test.go b/ddtrace/tracer/log_test.go index f81614a666..9c5da1ebd6 100644 --- a/ddtrace/tracer/log_test.go +++ b/ddtrace/tracer/log_test.go @@ -13,6 +13,7 @@ import ( "github.com/DataDog/dd-trace-go/v2/internal/globalconfig" "github.com/DataDog/dd-trace-go/v2/internal/log" + "github.com/DataDog/dd-trace-go/v2/internal/otelmetricsinstall" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -153,20 +154,43 @@ func TestStartupLog(t *testing.T) { t.Run("otlp_metrics_export", func(t *testing.T) { assert := assert.New(t) tp := new(log.RecordLogger) - // The OTel metrics signal is enabled and the exporter is otlp, so - // metrics are actually exported over OTLP. Pin OTEL_METRICS_EXPORTER - // explicitly so the assertion holds even under a polluted shell. + // otlp_metrics_export_enabled tracks otelRuntimeMetricsShouldBeEnabled, whose + // gate includes StartHook != nil (normally set when opentelemetry/metric is + // imported). withTestHooks stands in for that import so the pipeline is active. + withTestHooks(t) t.Setenv("DD_METRICS_OTEL_ENABLED", "true") t.Setenv("OTEL_METRICS_EXPORTER", "otlp") tracer, _, _, stop, err := startTestTracer(t, WithLogger(tp)) require.NoError(t, err) defer stop() + require.True(t, tracer.config.otelRuntimeMetricsShouldBeEnabled, + "OTLP metrics pipeline should be active for this assertion to be meaningful") tp.Reset() tp.Ignore(commonLogIgnore...) logStartup(tracer) require.Len(t, tp.Logs(), 2) assert.Contains(tp.Logs()[1], `"otlp_metrics_export_enabled":true`) }) + + t.Run("otlp_metrics_export_config_without_pipeline", func(t *testing.T) { + assert := assert.New(t) + tp := new(log.RecordLogger) + // Config intent is present but opentelemetry/metric is not imported, so + // StartHook is nil and the pipeline never starts: the field must report false + // rather than over-reporting from config alone. + require.Nil(t, otelmetricsinstall.StartHook, "test binary must not have the metric package imported") + t.Setenv("DD_METRICS_OTEL_ENABLED", "true") + t.Setenv("OTEL_METRICS_EXPORTER", "otlp") + tracer, _, _, stop, err := startTestTracer(t, WithLogger(tp)) + require.NoError(t, err) + defer stop() + require.False(t, tracer.config.otelRuntimeMetricsShouldBeEnabled) + tp.Reset() + tp.Ignore(commonLogIgnore...) + logStartup(tracer) + require.Len(t, tp.Logs(), 2) + assert.Contains(tp.Logs()[1], `"otlp_metrics_export_enabled":false`) + }) } func TestLogSamplingRules(t *testing.T) {