diff --git a/sdk/@launchdarkly/observability-dotnet/src/LaunchDarkly.Observability/Otel/CommonOtelOptions.cs b/sdk/@launchdarkly/observability-dotnet/src/LaunchDarkly.Observability/Otel/CommonOtelOptions.cs index 3f765ada2..37cc01987 100644 --- a/sdk/@launchdarkly/observability-dotnet/src/LaunchDarkly.Observability/Otel/CommonOtelOptions.cs +++ b/sdk/@launchdarkly/observability-dotnet/src/LaunchDarkly.Observability/Otel/CommonOtelOptions.cs @@ -4,10 +4,8 @@ using System.Threading.Tasks; using LaunchDarkly.Observability.Logging; using LaunchDarkly.Observability.Sampling; -using LaunchDarkly.Sdk.Internal.Concurrent; using OpenTelemetry; using OpenTelemetry.Exporter; -using OpenTelemetry.Logs; using OpenTelemetry.Metrics; using OpenTelemetry.Resources; using OpenTelemetry.Trace; diff --git a/sdk/@launchdarkly/observability-dotnet/test/LaunchDarkly.Observability.Tests/CustomSamplerTests.cs b/sdk/@launchdarkly/observability-dotnet/test/LaunchDarkly.Observability.Tests/CustomSamplerTests.cs index f41ef0adb..fbfbeef2e 100644 --- a/sdk/@launchdarkly/observability-dotnet/test/LaunchDarkly.Observability.Tests/CustomSamplerTests.cs +++ b/sdk/@launchdarkly/observability-dotnet/test/LaunchDarkly.Observability.Tests/CustomSamplerTests.cs @@ -241,8 +241,10 @@ private LogLevel SeverityTextToLogLevel(string severityText) case null: return LogLevel.Information; default: - // Unsupported in this test suite. - throw new ArgumentOutOfRangeException(nameof(severityText), severityText, null); + // Log records cannot be made without a level, but in some languages they can, so we + // use "Information" for a missing level in the test suite. + // We cannot use "None" because the open telemetry logger is hard-coded to discard "None". + return LogLevel.Information; } } diff --git a/sdk/@launchdarkly/observability-dotnet/test/LaunchDarkly.Observability.Tests/log-test-scenarios.json b/sdk/@launchdarkly/observability-dotnet/test/LaunchDarkly.Observability.Tests/log-test-scenarios.json index 97ec818f6..38efec42e 100644 --- a/sdk/@launchdarkly/observability-dotnet/test/LaunchDarkly.Observability.Tests/log-test-scenarios.json +++ b/sdk/@launchdarkly/observability-dotnet/test/LaunchDarkly.Observability.Tests/log-test-scenarios.json @@ -388,5 +388,102 @@ } } ] + }, + { + "description": "Should not match an empty log when message and severity are defined", + "samplingConfig": { + "logs": [ + { + "message": { + "regexValue": "Database connection .*" + }, + "severityText": { + "matchValue": "error" + }, + "samplingRatio": 90 + } + ] + }, + "inputLog": {}, + "samplerFunctionCases": [ + { + "type": "always", + "expected_result": { + "sample": true + } + }, + { + "type": "never", + "expected_result": { + "sample": true + } + } + ] + }, + { + "description": "Should not match a log with a message when message and severity are defined", + "samplingConfig": { + "logs": [ + { + "message": { + "regexValue": "Database connection .*" + }, + "severityText": { + "matchValue": "error" + }, + "samplingRatio": 90 + } + ] + }, + "inputLog": { + "message": "Database connection failed: timeout" + }, + "samplerFunctionCases": [ + { + "type": "always", + "expected_result": { + "sample": true + } + }, + { + "type": "never", + "expected_result": { + "sample": true + } + } + ] + }, + { + "description": "Should not match a log with only severity when message and severity are defined", + "samplingConfig": { + "logs": [ + { + "message": { + "regexValue": "Database connection .*" + }, + "severityText": { + "matchValue": "error" + }, + "samplingRatio": 90 + } + ] + }, + "inputLog": { + "severityText": "error" + }, + "samplerFunctionCases": [ + { + "type": "always", + "expected_result": { + "sample": true + } + }, + { + "type": "never", + "expected_result": { + "sample": true + } + } + ] } ] diff --git a/sdk/@launchdarkly/observability-python/ldobserve/_otel/_sampling/log-test-scenarios.json b/sdk/@launchdarkly/observability-python/ldobserve/_otel/_sampling/log-test-scenarios.json index 28ea1dee0..dd0ea7611 100644 --- a/sdk/@launchdarkly/observability-python/ldobserve/_otel/_sampling/log-test-scenarios.json +++ b/sdk/@launchdarkly/observability-python/ldobserve/_otel/_sampling/log-test-scenarios.json @@ -388,5 +388,102 @@ } } ] + }, + { + "description": "Should not match an empty log when message and severity are defined", + "samplingConfig": { + "logs": [ + { + "message": { + "regexValue": "Database connection .*" + }, + "severityText": { + "matchValue": "error" + }, + "samplingRatio": 90 + } + ] + }, + "inputLog": {}, + "samplerFunctionCases": [ + { + "type": "always", + "expected_result": { + "sample": true + } + }, + { + "type": "never", + "expected_result": { + "sample": true + } + } + ] + }, + { + "description": "Should not match a log with a message when message and severity are defined", + "samplingConfig": { + "logs": [ + { + "message": { + "regexValue": "Database connection .*" + }, + "severityText": { + "matchValue": "error" + }, + "samplingRatio": 90 + } + ] + }, + "inputLog": { + "message": "Database connection failed: timeout" + }, + "samplerFunctionCases": [ + { + "type": "always", + "expected_result": { + "sample": true + } + }, + { + "type": "never", + "expected_result": { + "sample": true + } + } + ] + }, + { + "description": "Should not match a log with only severity when message and severity are defined", + "samplingConfig": { + "logs": [ + { + "message": { + "regexValue": "Database connection .*" + }, + "severityText": { + "matchValue": "error" + }, + "samplingRatio": 90 + } + ] + }, + "inputLog": { + "severityText": "error" + }, + "samplerFunctionCases": [ + { + "type": "always", + "expected_result": { + "sample": true + } + }, + { + "type": "never", + "expected_result": { + "sample": true + } + } + ] } ] diff --git a/sdk/@launchdarkly/observability-python/ldobserve/_otel/_sampling/test_custom_sampler.py b/sdk/@launchdarkly/observability-python/ldobserve/_otel/_sampling/test_custom_sampler.py index 6070c199a..9b6297aa8 100644 --- a/sdk/@launchdarkly/observability-python/ldobserve/_otel/_sampling/test_custom_sampler.py +++ b/sdk/@launchdarkly/observability-python/ldobserve/_otel/_sampling/test_custom_sampler.py @@ -177,7 +177,7 @@ def run_span_scenarios(): assert sampler.is_sampling_enabled() is True result = sampler.sample_span(span) assert result.sample == expected["sample"], desc - if expected["attributes"] is not None: + if "attributes" in expected and expected["attributes"] is not None: assert result.attributes == expected["attributes"], desc else: assert result.attributes is None or result.attributes == {}, desc @@ -202,7 +202,7 @@ def run_log_scenarios(): assert sampler.is_sampling_enabled() is True result = sampler.sample_log(log) assert result.sample == expected["sample"], desc - if expected["attributes"] is not None: + if "attributes" in expected and expected["attributes"] is not None: assert result.attributes == expected["attributes"], desc else: assert result.attributes is None or result.attributes == {}, desc