From 543c9b182fab81c82c4229bfad6809714235e9c0 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 13 Aug 2026 14:08:55 +0300 Subject: [PATCH 01/86] feat(feature-flags): add agentless configuration keys to supported-configurations --- .../supported-configurations.yaml | 72 +++++++++++++++++++ .../ConfigurationKeys.FeatureFlags.g.cs | 48 +++++++++++++ .../ConfigurationKeys.FeatureFlags.g.cs | 48 +++++++++++++ .../ConfigurationKeys.FeatureFlags.g.cs | 48 +++++++++++++ .../ConfigurationKeys.FeatureFlags.g.cs | 48 +++++++++++++ 5 files changed, 264 insertions(+) diff --git a/tracer/src/Datadog.Trace/Configuration/supported-configurations.yaml b/tracer/src/Datadog.Trace/Configuration/supported-configurations.yaml index cba391e5643a..eef60327d1c8 100644 --- a/tracer/src/Datadog.Trace/Configuration/supported-configurations.yaml +++ b/tracer/src/Datadog.Trace/Configuration/supported-configurations.yaml @@ -3157,6 +3157,78 @@ supportedConfigurations: documentation: |- Enables Feature Flags Provider (Experimental). Default value is false (disabled). + DD_EXPERIMENTAL_FLAGGING_PROVIDER_INITIALIZATION_TIMEOUT_MS: + - implementation: B + scope: managed + type: int + default: '10000' + product: FeatureFlags + const_name: FlaggingProviderInitializationTimeoutMs + documentation: |- + Configuration key for how long, in milliseconds, provider initialization waits for the first + flag configuration to arrive before returning. + Default value is 10000 (10 seconds). + Initialization does not fail when the timeout expires: the provider stays not-ready, evaluations + return the caller's default value, and the provider becomes ready when configuration arrives. + DD_FEATURE_FLAGS_ENABLED: + - implementation: A + scope: managed + type: boolean + default: 'true' + product: FeatureFlags + const_name: FeatureFlagsEnabled + documentation: |- + Configuration key to enable or disable Feature Flags. + Default value is true (enabled). + Feature Flags only contact Datadog once application code initializes the provider, so enabling + this alone does not start requesting flag configuration. + This supersedes . + DD_FEATURE_FLAGS_CONFIGURATION_SOURCE: + - implementation: A + scope: managed + type: string + default: agentless + product: FeatureFlags + const_name: FeatureFlagsConfigurationSource + documentation: |- + Configuration key for selecting where flag configuration is loaded from. + Supported values are agentless (direct HTTP delivery, the default) and + remote_config (delivery through the Datadog Agent's Remote Configuration). + Any other value disables Feature Flags, which fails closed and contacts nothing. + DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_BASE_URL: + - implementation: A + scope: managed + type: string + default: null + product: FeatureFlags + const_name: FeatureFlagsConfigurationSourceAgentlessBaseUrl + documentation: |- + Configuration key for overriding the endpoint used by the agentless configuration source. + When the URL has no path, or a path of /, the standard rules-based server path is appended; + any other path is used verbatim as the exact endpoint. + If unset, the endpoint is derived from . + DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_POLL_INTERVAL_SECONDS: + - implementation: A + scope: managed + type: int + default: '30' + product: FeatureFlags + const_name: FeatureFlagsConfigurationSourceAgentlessPollIntervalSeconds + documentation: |- + Configuration key for how often, in seconds, the agentless configuration source polls for + flag configuration. + Default value is 30. Values outside (0, 3600] are rejected and the default is used. + DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_REQUEST_TIMEOUT_SECONDS: + - implementation: A + scope: managed + type: int + default: '5' + product: FeatureFlags + const_name: FeatureFlagsConfigurationSourceAgentlessRequestTimeoutSeconds + documentation: |- + Configuration key for the request timeout, in seconds, used by the agentless configuration + source. + Default value is 5. Non-positive values are rejected and the default is used. DD_EXPERIMENTAL_FLAGGING_PROVIDER_SPAN_ENRICHMENT_ENABLED: - implementation: A scope: managed diff --git a/tracer/src/Datadog.Trace/Generated/net461/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs b/tracer/src/Datadog.Trace/Generated/net461/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs index e3c49c08f659..c0bc6ef9a199 100644 --- a/tracer/src/Datadog.Trace/Generated/net461/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs +++ b/tracer/src/Datadog.Trace/Generated/net461/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs @@ -23,12 +23,60 @@ internal static class FeatureFlags /// public const string FlaggingProviderEnabled = "DD_EXPERIMENTAL_FLAGGING_PROVIDER_ENABLED"; + /// + /// Configuration key for how long, in milliseconds, provider initialization waits for the first + /// flag configuration to arrive before returning. + /// Default value is 10000 (10 seconds). + /// Initialization does not fail when the timeout expires: the provider stays not-ready, evaluations + /// return the caller's default value, and the provider becomes ready when configuration arrives. + /// + public const string FlaggingProviderInitializationTimeoutMs = "DD_EXPERIMENTAL_FLAGGING_PROVIDER_INITIALIZATION_TIMEOUT_MS"; + /// /// Enables APM span enrichment with feature-flag evaluation metadata (Experimental). /// Default value is false (disabled). /// public const string SpanEnrichmentEnabled = "DD_EXPERIMENTAL_FLAGGING_PROVIDER_SPAN_ENRICHMENT_ENABLED"; + /// + /// Configuration key for selecting where flag configuration is loaded from. + /// Supported values are agentless (direct HTTP delivery, the default) and + /// remote_config (delivery through the Datadog Agent's Remote Configuration). + /// Any other value disables Feature Flags, which fails closed and contacts nothing. + /// + public const string FeatureFlagsConfigurationSource = "DD_FEATURE_FLAGS_CONFIGURATION_SOURCE"; + + /// + /// Configuration key for overriding the endpoint used by the agentless configuration source. + /// When the URL has no path, or a path of /, the standard rules-based server path is appended; + /// any other path is used verbatim as the exact endpoint. + /// If unset, the endpoint is derived from . + /// + public const string FeatureFlagsConfigurationSourceAgentlessBaseUrl = "DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_BASE_URL"; + + /// + /// Configuration key for how often, in seconds, the agentless configuration source polls for + /// flag configuration. + /// Default value is 30. Values outside (0, 3600] are rejected and the default is used. + /// + public const string FeatureFlagsConfigurationSourceAgentlessPollIntervalSeconds = "DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_POLL_INTERVAL_SECONDS"; + + /// + /// Configuration key for the request timeout, in seconds, used by the agentless configuration + /// source. + /// Default value is 5. Non-positive values are rejected and the default is used. + /// + public const string FeatureFlagsConfigurationSourceAgentlessRequestTimeoutSeconds = "DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_REQUEST_TIMEOUT_SECONDS"; + + /// + /// Configuration key to enable or disable Feature Flags. + /// Default value is true (enabled). + /// Feature Flags only contact Datadog once application code initializes the provider, so enabling + /// this alone does not start requesting flag configuration. + /// This supersedes . + /// + public const string FeatureFlagsEnabled = "DD_FEATURE_FLAGS_ENABLED"; + /// /// Enables support for collecting and exporting logs generated by the the OpenTelemetry Logs API. /// This feature is available starting with .NET 3.1 when using Microsoft.Extensions.Logging diff --git a/tracer/src/Datadog.Trace/Generated/net6.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs b/tracer/src/Datadog.Trace/Generated/net6.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs index e3c49c08f659..c0bc6ef9a199 100644 --- a/tracer/src/Datadog.Trace/Generated/net6.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs +++ b/tracer/src/Datadog.Trace/Generated/net6.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs @@ -23,12 +23,60 @@ internal static class FeatureFlags /// public const string FlaggingProviderEnabled = "DD_EXPERIMENTAL_FLAGGING_PROVIDER_ENABLED"; + /// + /// Configuration key for how long, in milliseconds, provider initialization waits for the first + /// flag configuration to arrive before returning. + /// Default value is 10000 (10 seconds). + /// Initialization does not fail when the timeout expires: the provider stays not-ready, evaluations + /// return the caller's default value, and the provider becomes ready when configuration arrives. + /// + public const string FlaggingProviderInitializationTimeoutMs = "DD_EXPERIMENTAL_FLAGGING_PROVIDER_INITIALIZATION_TIMEOUT_MS"; + /// /// Enables APM span enrichment with feature-flag evaluation metadata (Experimental). /// Default value is false (disabled). /// public const string SpanEnrichmentEnabled = "DD_EXPERIMENTAL_FLAGGING_PROVIDER_SPAN_ENRICHMENT_ENABLED"; + /// + /// Configuration key for selecting where flag configuration is loaded from. + /// Supported values are agentless (direct HTTP delivery, the default) and + /// remote_config (delivery through the Datadog Agent's Remote Configuration). + /// Any other value disables Feature Flags, which fails closed and contacts nothing. + /// + public const string FeatureFlagsConfigurationSource = "DD_FEATURE_FLAGS_CONFIGURATION_SOURCE"; + + /// + /// Configuration key for overriding the endpoint used by the agentless configuration source. + /// When the URL has no path, or a path of /, the standard rules-based server path is appended; + /// any other path is used verbatim as the exact endpoint. + /// If unset, the endpoint is derived from . + /// + public const string FeatureFlagsConfigurationSourceAgentlessBaseUrl = "DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_BASE_URL"; + + /// + /// Configuration key for how often, in seconds, the agentless configuration source polls for + /// flag configuration. + /// Default value is 30. Values outside (0, 3600] are rejected and the default is used. + /// + public const string FeatureFlagsConfigurationSourceAgentlessPollIntervalSeconds = "DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_POLL_INTERVAL_SECONDS"; + + /// + /// Configuration key for the request timeout, in seconds, used by the agentless configuration + /// source. + /// Default value is 5. Non-positive values are rejected and the default is used. + /// + public const string FeatureFlagsConfigurationSourceAgentlessRequestTimeoutSeconds = "DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_REQUEST_TIMEOUT_SECONDS"; + + /// + /// Configuration key to enable or disable Feature Flags. + /// Default value is true (enabled). + /// Feature Flags only contact Datadog once application code initializes the provider, so enabling + /// this alone does not start requesting flag configuration. + /// This supersedes . + /// + public const string FeatureFlagsEnabled = "DD_FEATURE_FLAGS_ENABLED"; + /// /// Enables support for collecting and exporting logs generated by the the OpenTelemetry Logs API. /// This feature is available starting with .NET 3.1 when using Microsoft.Extensions.Logging diff --git a/tracer/src/Datadog.Trace/Generated/netcoreapp3.1/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs b/tracer/src/Datadog.Trace/Generated/netcoreapp3.1/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs index e3c49c08f659..c0bc6ef9a199 100644 --- a/tracer/src/Datadog.Trace/Generated/netcoreapp3.1/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs +++ b/tracer/src/Datadog.Trace/Generated/netcoreapp3.1/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs @@ -23,12 +23,60 @@ internal static class FeatureFlags /// public const string FlaggingProviderEnabled = "DD_EXPERIMENTAL_FLAGGING_PROVIDER_ENABLED"; + /// + /// Configuration key for how long, in milliseconds, provider initialization waits for the first + /// flag configuration to arrive before returning. + /// Default value is 10000 (10 seconds). + /// Initialization does not fail when the timeout expires: the provider stays not-ready, evaluations + /// return the caller's default value, and the provider becomes ready when configuration arrives. + /// + public const string FlaggingProviderInitializationTimeoutMs = "DD_EXPERIMENTAL_FLAGGING_PROVIDER_INITIALIZATION_TIMEOUT_MS"; + /// /// Enables APM span enrichment with feature-flag evaluation metadata (Experimental). /// Default value is false (disabled). /// public const string SpanEnrichmentEnabled = "DD_EXPERIMENTAL_FLAGGING_PROVIDER_SPAN_ENRICHMENT_ENABLED"; + /// + /// Configuration key for selecting where flag configuration is loaded from. + /// Supported values are agentless (direct HTTP delivery, the default) and + /// remote_config (delivery through the Datadog Agent's Remote Configuration). + /// Any other value disables Feature Flags, which fails closed and contacts nothing. + /// + public const string FeatureFlagsConfigurationSource = "DD_FEATURE_FLAGS_CONFIGURATION_SOURCE"; + + /// + /// Configuration key for overriding the endpoint used by the agentless configuration source. + /// When the URL has no path, or a path of /, the standard rules-based server path is appended; + /// any other path is used verbatim as the exact endpoint. + /// If unset, the endpoint is derived from . + /// + public const string FeatureFlagsConfigurationSourceAgentlessBaseUrl = "DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_BASE_URL"; + + /// + /// Configuration key for how often, in seconds, the agentless configuration source polls for + /// flag configuration. + /// Default value is 30. Values outside (0, 3600] are rejected and the default is used. + /// + public const string FeatureFlagsConfigurationSourceAgentlessPollIntervalSeconds = "DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_POLL_INTERVAL_SECONDS"; + + /// + /// Configuration key for the request timeout, in seconds, used by the agentless configuration + /// source. + /// Default value is 5. Non-positive values are rejected and the default is used. + /// + public const string FeatureFlagsConfigurationSourceAgentlessRequestTimeoutSeconds = "DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_REQUEST_TIMEOUT_SECONDS"; + + /// + /// Configuration key to enable or disable Feature Flags. + /// Default value is true (enabled). + /// Feature Flags only contact Datadog once application code initializes the provider, so enabling + /// this alone does not start requesting flag configuration. + /// This supersedes . + /// + public const string FeatureFlagsEnabled = "DD_FEATURE_FLAGS_ENABLED"; + /// /// Enables support for collecting and exporting logs generated by the the OpenTelemetry Logs API. /// This feature is available starting with .NET 3.1 when using Microsoft.Extensions.Logging diff --git a/tracer/src/Datadog.Trace/Generated/netstandard2.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs b/tracer/src/Datadog.Trace/Generated/netstandard2.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs index e3c49c08f659..c0bc6ef9a199 100644 --- a/tracer/src/Datadog.Trace/Generated/netstandard2.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs +++ b/tracer/src/Datadog.Trace/Generated/netstandard2.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs @@ -23,12 +23,60 @@ internal static class FeatureFlags /// public const string FlaggingProviderEnabled = "DD_EXPERIMENTAL_FLAGGING_PROVIDER_ENABLED"; + /// + /// Configuration key for how long, in milliseconds, provider initialization waits for the first + /// flag configuration to arrive before returning. + /// Default value is 10000 (10 seconds). + /// Initialization does not fail when the timeout expires: the provider stays not-ready, evaluations + /// return the caller's default value, and the provider becomes ready when configuration arrives. + /// + public const string FlaggingProviderInitializationTimeoutMs = "DD_EXPERIMENTAL_FLAGGING_PROVIDER_INITIALIZATION_TIMEOUT_MS"; + /// /// Enables APM span enrichment with feature-flag evaluation metadata (Experimental). /// Default value is false (disabled). /// public const string SpanEnrichmentEnabled = "DD_EXPERIMENTAL_FLAGGING_PROVIDER_SPAN_ENRICHMENT_ENABLED"; + /// + /// Configuration key for selecting where flag configuration is loaded from. + /// Supported values are agentless (direct HTTP delivery, the default) and + /// remote_config (delivery through the Datadog Agent's Remote Configuration). + /// Any other value disables Feature Flags, which fails closed and contacts nothing. + /// + public const string FeatureFlagsConfigurationSource = "DD_FEATURE_FLAGS_CONFIGURATION_SOURCE"; + + /// + /// Configuration key for overriding the endpoint used by the agentless configuration source. + /// When the URL has no path, or a path of /, the standard rules-based server path is appended; + /// any other path is used verbatim as the exact endpoint. + /// If unset, the endpoint is derived from . + /// + public const string FeatureFlagsConfigurationSourceAgentlessBaseUrl = "DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_BASE_URL"; + + /// + /// Configuration key for how often, in seconds, the agentless configuration source polls for + /// flag configuration. + /// Default value is 30. Values outside (0, 3600] are rejected and the default is used. + /// + public const string FeatureFlagsConfigurationSourceAgentlessPollIntervalSeconds = "DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_POLL_INTERVAL_SECONDS"; + + /// + /// Configuration key for the request timeout, in seconds, used by the agentless configuration + /// source. + /// Default value is 5. Non-positive values are rejected and the default is used. + /// + public const string FeatureFlagsConfigurationSourceAgentlessRequestTimeoutSeconds = "DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_REQUEST_TIMEOUT_SECONDS"; + + /// + /// Configuration key to enable or disable Feature Flags. + /// Default value is true (enabled). + /// Feature Flags only contact Datadog once application code initializes the provider, so enabling + /// this alone does not start requesting flag configuration. + /// This supersedes . + /// + public const string FeatureFlagsEnabled = "DD_FEATURE_FLAGS_ENABLED"; + /// /// Enables support for collecting and exporting logs generated by the the OpenTelemetry Logs API. /// This feature is available starting with .NET 3.1 when using Microsoft.Extensions.Logging From 47530796486e0d93ecf6d2a74a82a5b422bc17e5 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 13 Aug 2026 14:13:45 +0300 Subject: [PATCH 02/86] feat(feature-flags): add FeatureFlagsSettings with source resolution and validation --- .../FeatureFlags/FeatureFlagsSettings.cs | 228 ++++++++++++++++++ 1 file changed, 228 insertions(+) create mode 100644 tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs new file mode 100644 index 000000000000..71677f39b508 --- /dev/null +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs @@ -0,0 +1,228 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +#nullable enable + +using System; +using Datadog.Trace.Configuration; +using Datadog.Trace.Configuration.Telemetry; +using Datadog.Trace.Logging; +using Datadog.Trace.Telemetry; +using Datadog.Trace.Util; + +namespace Datadog.Trace.FeatureFlags; + +/// +/// Feature Flags configuration: which delivery source is selected, and how the agentless +/// source is operated. +/// +internal sealed class FeatureFlagsSettings +{ + internal const string AgentlessSourceName = "agentless"; + internal const string RemoteConfigSourceName = "remote_config"; + internal const string OfflineSourceName = "offline"; + + internal const string DefaultSite = "datadoghq.com"; + + internal const int DefaultPollIntervalSeconds = 30; + internal const int DefaultRequestTimeoutSeconds = 5; + internal const int DefaultInitializationTimeoutMs = 10_000; + + // An interval above this is indistinguishable from "never poll" and is more likely a + // misconfiguration (for example milliseconds passed as seconds) than an intent. + private const int MaxPollIntervalSeconds = 3600; + + private static readonly IDatadogLogger Log = DatadogLogging.GetLoggerFor(typeof(FeatureFlagsSettings)); + + public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetry telemetry) + { + source ??= NullConfigurationSource.Instance; + var config = new ConfigurationBuilder(source, telemetry); + + // Read as nullable: the precedence rules distinguish "explicitly provided" from "left unset", + // so a default value here would erase the difference the legacy key depends on. + var enabled = config.WithKeys(ConfigurationKeys.FeatureFlags.FeatureFlagsEnabled).AsBool(); +#pragma warning disable 618 // superseded, but still honoured so existing adopters keep their source + var legacyEnabled = config.WithKeys(ConfigurationKeys.FeatureFlags.FlaggingProviderEnabled).AsBool(); +#pragma warning restore 618 + var configuredSource = config.WithKeys(ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSource).AsString(); + + if (legacyEnabled is not null) + { +#pragma warning disable 618 + Log.Warning( + "{LegacyKey} is deprecated. Use {EnabledKey} and {SourceKey} instead.", + ConfigurationKeys.FeatureFlags.FlaggingProviderEnabled, + ConfigurationKeys.FeatureFlags.FeatureFlagsEnabled, + ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSource); +#pragma warning restore 618 + } + + Source = ResolveSource(enabled, configuredSource, legacyEnabled); + + AgentlessBaseUrl = config + .WithKeys(ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSourceAgentlessBaseUrl) + .AsString(url => !StringUtil.IsNullOrEmpty(url?.Trim())); + + PollInterval = TimeSpan.FromSeconds( + InRangeOrDefault( + config.WithKeys(ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSourceAgentlessPollIntervalSeconds).AsInt32(), + ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSourceAgentlessPollIntervalSeconds, + DefaultPollIntervalSeconds, + MaxPollIntervalSeconds)); + + RequestTimeout = TimeSpan.FromSeconds( + InRangeOrDefault( + config.WithKeys(ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSourceAgentlessRequestTimeoutSeconds).AsInt32(), + ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSourceAgentlessRequestTimeoutSeconds, + DefaultRequestTimeoutSeconds, + maximumSeconds: null)); + + Site = config + .WithKeys(ConfigurationKeys.Site) + .AsString(DefaultSite, site => !StringUtil.IsNullOrEmpty(site?.Trim())); + + Env = config.WithKeys(ConfigurationKeys.Environment).AsString(); + + ApiKey = config.WithKeys(ConfigurationKeys.ApiKey).AsRedactedString(); + + var initializationTimeoutMs = config + .WithKeys(ConfigurationKeys.FeatureFlags.FlaggingProviderInitializationTimeoutMs) + .AsInt32(DefaultInitializationTimeoutMs, timeout => timeout > 0) + .Value; + InitializationTimeout = TimeSpan.FromMilliseconds(initializationTimeoutMs); + } + + /// + /// Gets the resolved delivery source. means nothing is contacted. + /// + public FeatureFlagsSource Source { get; } + + /// + /// Gets a value indicating whether Feature Flags are enabled at all. + /// + public bool Enabled => Source != FeatureFlagsSource.Disabled; + + /// + /// Gets the configured override for the agentless endpoint, or null to derive it from the site. + /// + public string? AgentlessBaseUrl { get; } + + /// + /// Gets the Datadog site the managed agentless endpoint is derived from. + /// + public string Site { get; } + + /// + /// Gets the configured environment, sent to the agentless endpoint as dd_env. + /// + public string? Env { get; } + + /// + /// Gets the API key, required by the managed agentless endpoint. + /// + public string? ApiKey { get; } + + /// + /// Gets how often the agentless source polls for configuration. + /// + public TimeSpan PollInterval { get; } + + /// + /// Gets the per-request timeout used by the agentless source. + /// + public TimeSpan RequestTimeout { get; } + + /// + /// Gets how long provider initialization waits for the first configuration. + /// + public TimeSpan InitializationTimeout { get; } + + public static FeatureFlagsSettings FromDefaultSource() + => new(GlobalConfigurationSource.Instance, TelemetryFactory.Config); + + /// + /// Resolves the delivery source. Shared across tracers, so the ordering is deliberate: + /// the stable kill switch wins over everything, an explicit source wins over the legacy key + /// (and fails closed when unrecognised), the legacy key grandfathers existing adopters onto + /// Remote Configuration, and everything else defaults to agentless. + /// + internal static FeatureFlagsSource ResolveSource(bool? enabled, string? configuredSource, bool? legacyEnabled) + { + var normalizedSource = NormalizeSource(configuredSource); + + if (enabled == false) + { + return FeatureFlagsSource.Disabled; + } + + if (normalizedSource is not null) + { + switch (normalizedSource) + { + case AgentlessSourceName: + return FeatureFlagsSource.Agentless; + case RemoteConfigSourceName: + return FeatureFlagsSource.RemoteConfig; + case OfflineSourceName: + // Reserved fail-closed sentinel: the provider is intentionally off, so no warning. + return FeatureFlagsSource.Disabled; + default: + Log.Warning( + "Unsupported {SourceKey} value '{Source}'. Feature Flags are disabled.", + ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSource, + normalizedSource); + return FeatureFlagsSource.Disabled; + } + } + + // The legacy key only grandfathers adopters who have not migrated: an explicit new-key + // value (true or false) takes precedence, so the legacy key is consulted only when the + // new key was left unset. + if (enabled is null && legacyEnabled is not null) + { + return legacyEnabled.Value ? FeatureFlagsSource.RemoteConfig : FeatureFlagsSource.Disabled; + } + + return FeatureFlagsSource.Agentless; + } + + /// + /// An empty or whitespace-only source is semantically unset, not an unrecognised value. + /// + private static string? NormalizeSource(string? configuredSource) + { + if (configuredSource is null) + { + return null; + } + + var normalized = configuredSource.Trim().ToLowerInvariant(); + return normalized.Length == 0 ? null : normalized; + } + + internal static int InRangeOrDefault(int? configured, string key, int defaultSeconds, int? maximumSeconds) + { + if (configured is null) + { + return defaultSeconds; + } + + var value = configured.Value; + if (value <= 0 || (maximumSeconds is { } maximum && value > maximum)) + { + // A non-positive interval would turn polling into a tight loop against the endpoint, + // so an out-of-range value is rejected rather than honoured. + Log.Warning( + "Invalid value {Key}={Value}. Using {Default} seconds instead.", + key, + value, + defaultSeconds); + return defaultSeconds; + } + + return value; + } +} From 25e168f7fac589e3cff2de605165565579e4dca4 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 13 Aug 2026 14:34:49 +0300 Subject: [PATCH 03/86] feat(feature-flags): add AgentlessEndpoint for CDN URL derivation --- .../Agentless/AgentlessEndpoint.cs | 116 ++++++++++++++++++ .../FeatureFlags/FeatureFlagsSource.cs | 29 +++++ 2 files changed, 145 insertions(+) create mode 100644 tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs create mode 100644 tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSource.cs diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs new file mode 100644 index 000000000000..757691bfa4cf --- /dev/null +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs @@ -0,0 +1,116 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +#nullable enable + +using System; +using Datadog.Trace.Util; + +namespace Datadog.Trace.FeatureFlags.Agentless; + +/// +/// The agentless endpoint, derived from the Datadog site or a custom base URL. +/// +internal readonly struct AgentlessEndpoint +{ + /// + /// Canonical rules-based server path, appended to the managed CDN host and to custom base + /// URLs that only supply an origin. + /// + internal const string DefaultPath = "/api/v2/feature-flagging/config/rules-based/server"; + + /// + /// The prefix prepended to the site to form the managed CDN host. + /// + internal const string ManagedHostPrefix = "ufc-server.ff-cdn."; + + private AgentlessEndpoint(Uri uri, bool isManaged) + { + Uri = uri; + IsManaged = isManaged; + } + + /// + /// Gets the endpoint URI. + /// + public Uri Uri { get; } + + /// + /// Gets a value indicating whether this is the endpoint derived from the site. The API key is + /// only sent there: a custom endpoint reports its own authentication failure rather than + /// having the credential guessed onto it. + /// + public bool IsManaged { get; } + + /// + /// Builds the endpoint. Without a custom the managed Datadog CDN + /// endpoint is derived from the (lowercased) site, so staging and government sites resolve + /// with no allowlist, and dd_env is added only when an environment is configured. + /// A custom base URL that is an origin receives the canonical path; one that carries a path + /// is used verbatim. + /// + /// The Datadog site, for example datadoghq.com. + /// The configured environment, or null. + /// The configured endpoint override, or null. + /// The resulting endpoint. + /// Why the configured base URL was rejected. Never contains the URL, which may carry credentials. + /// true when an endpoint could be built. + public static bool TryCreate(string? site, string? env, string? baseUrl, out AgentlessEndpoint endpoint, out string? error) + { + endpoint = default; + error = null; + + var configured = baseUrl?.Trim(); + if (StringUtil.IsNullOrEmpty(configured)) + { + var trimmedSite = site?.Trim(); + if (StringUtil.IsNullOrEmpty(trimmedSite)) + { + error = "No Datadog site is configured"; + return false; + } + + var managed = new UriBuilder("https", ManagedHostPrefix + trimmedSite!.ToLowerInvariant()) { Path = DefaultPath }; + if (!StringUtil.IsNullOrEmpty(env)) + { + managed.Query = "dd_env=" + Uri.EscapeDataString(env!); + } + + endpoint = new AgentlessEndpoint(managed.Uri, isManaged: true); + return true; + } + + // A URL with internal whitespace is malformed, and Uri parsing is lenient enough to accept it. + foreach (var character in configured!) + { + if (char.IsWhiteSpace(character)) + { + error = "The configured Feature Flags agentless URL is not a valid URL"; + return false; + } + } + + if (!Uri.TryCreate(configured, UriKind.Absolute, out var custom) || StringUtil.IsNullOrEmpty(custom.Host)) + { + error = "The configured Feature Flags agentless URL is not a valid absolute URL"; + return false; + } + + // http is accepted for a custom endpoint only: pointing at one is an operator decision. + if (custom.Scheme != Uri.UriSchemeHttps && custom.Scheme != Uri.UriSchemeHttp) + { + error = "The configured Feature Flags agentless URL must use HTTP or HTTPS"; + return false; + } + + if (custom.AbsolutePath is "" or "/") + { + custom = new UriBuilder(custom) { Path = DefaultPath }.Uri; + } + + endpoint = new AgentlessEndpoint(custom, isManaged: false); + return true; + } +} diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSource.cs new file mode 100644 index 000000000000..dd50047ede42 --- /dev/null +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSource.cs @@ -0,0 +1,29 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +#nullable enable + +namespace Datadog.Trace.FeatureFlags; + +/// +/// Where flag configuration is loaded from. +/// +internal enum FeatureFlagsSource +{ + /// + /// Feature Flags are disabled: no configuration is loaded, and neither delivery path is contacted. + /// + Disabled, + + /// + /// Configuration is fetched over HTTP, without the Datadog Agent. + /// + Agentless, + + /// + /// Configuration is delivered through the Datadog Agent's Remote Configuration. + /// + RemoteConfig, +} From 9c3a236bfb63e211793ab97eefaa170a26a3c270 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 13 Aug 2026 14:37:12 +0300 Subject: [PATCH 04/86] test(feature-flags): add unit tests for FeatureFlagsSettings and AgentlessEndpoint --- .../FeatureFlags/AgentlessEndpointTests.cs | 116 +++++++++++ .../FeatureFlags/FeatureFlagsSettingsTests.cs | 184 ++++++++++++++++++ 2 files changed, 300 insertions(+) create mode 100644 tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs create mode 100644 tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs new file mode 100644 index 000000000000..1ab87b4c3dec --- /dev/null +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs @@ -0,0 +1,116 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +#nullable enable + +using System; +using Datadog.Trace.FeatureFlags.Agentless; +using FluentAssertions; +using Xunit; + +namespace Datadog.Trace.Tests.FeatureFlags; + +public class AgentlessEndpointTests +{ + private const string DefaultPath = "/api/v2/feature-flagging/config/rules-based/server"; + + [Theory] + [InlineData("datadoghq.com", "https://ufc-server.ff-cdn.datadoghq.com" + DefaultPath)] + [InlineData("DATADOGHQ.COM", "https://ufc-server.ff-cdn.datadoghq.com" + DefaultPath)] // site is lowercased + [InlineData("datad0g.com", "https://ufc-server.ff-cdn.datad0g.com" + DefaultPath)] // staging + [InlineData("ddog-gov.com", "https://ufc-server.ff-cdn.ddog-gov.com" + DefaultPath)] // govcloud + public void DerivesManagedEndpointFromSite(string site, string expected) + { + AgentlessEndpoint.TryCreate(site, env: null, baseUrl: null, out var endpoint, out var error) + .Should().BeTrue(); + error.Should().BeNull(); + endpoint.IsManaged.Should().BeTrue(); + endpoint.Uri.ToString().Should().Be(expected); + } + + [Fact] + public void AddsDdEnvWhenEnvIsConfigured() + { + AgentlessEndpoint.TryCreate("datadoghq.com", env: "production", baseUrl: null, out var endpoint, out _) + .Should().BeTrue(); + endpoint.Uri.Query.Should().Be("?dd_env=production"); + } + + [Fact] + public void DoesNotAddDdEnvWhenEnvIsNull() + { + AgentlessEndpoint.TryCreate("datadoghq.com", env: null, baseUrl: null, out var endpoint, out _) + .Should().BeTrue(); + endpoint.Uri.Query.Should().BeEmpty(); + } + + [Fact] + public void EscapesDdEnvValue() + { + AgentlessEndpoint.TryCreate("datadoghq.com", env: "my env&test", baseUrl: null, out var endpoint, out _) + .Should().BeTrue(); + endpoint.Uri.Query.Should().Be("?dd_env=my%20env%26test"); + } + + [Theory] + [InlineData("https://flags.example.com", "https://flags.example.com" + DefaultPath)] + [InlineData("https://flags.example.com/", "https://flags.example.com" + DefaultPath)] + [InlineData("https://flags.example.com/ufc", "https://flags.example.com/ufc")] + [InlineData("https://flags.example.com/ufc?custom=query", "https://flags.example.com/ufc?custom=query")] + public void CustomEndpointReceivesCanonicalPathForOriginOnly(string baseUrl, string expected) + { + AgentlessEndpoint.TryCreate("datadoghq.com", env: null, baseUrl: baseUrl, out var endpoint, out var error) + .Should().BeTrue(); + error.Should().BeNull(); + endpoint.IsManaged.Should().BeFalse(); + endpoint.Uri.ToString().Should().Be(expected); + } + + [Theory] + [InlineData("http://localhost:8080/ufc")] // http accepted for custom endpoints + public void CustomEndpointAcceptsHttp(string baseUrl) + { + AgentlessEndpoint.TryCreate("datadoghq.com", env: null, baseUrl: baseUrl, out var endpoint, out var error) + .Should().BeTrue(); + endpoint.IsManaged.Should().BeFalse(); + } + + [Theory] + [InlineData("ftp://flags.example.com", "The configured Feature Flags agentless URL must use HTTP or HTTPS")] + [InlineData("not a url", "The configured Feature Flags agentless URL is not a valid absolute URL")] + [InlineData(" https://flags.example.com ", "The configured Feature Flags agentless URL is not a valid URL")] // internal whitespace + public void RejectsInvalidBaseUrl(string baseUrl, string expectedError) + { + AgentlessEndpoint.TryCreate("datadoghq.com", env: null, baseUrl: baseUrl, out var endpoint, out var error) + .Should().BeFalse(); + error.Should().Be(expectedError); + } + + [Fact] + public void RejectsEmptySiteWithoutBaseUrl() + { + AgentlessEndpoint.TryCreate(site: null, env: null, baseUrl: null, out var endpoint, out var error) + .Should().BeFalse(); + error.Should().Be("No Datadog site is configured"); + } + + [Fact] + public void RejectsWhitespaceOnlySiteWithoutBaseUrl() + { + AgentlessEndpoint.TryCreate(" ", env: null, baseUrl: null, out var endpoint, out var error) + .Should().BeFalse(); + error.Should().Be("No Datadog site is configured"); + } + + [Fact] + public void ErrorNeverContainsUrl() + { + // A URL may carry credentials, so the error must never echo it. + AgentlessEndpoint.TryCreate("datadoghq.com", env: null, baseUrl: "https://user:pass@flags.example.com bad", out _, out var error) + .Should().BeFalse(); + error.Should().NotContain("user"); + error.Should().NotContain("pass"); + } +} diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs new file mode 100644 index 000000000000..ec8be148a134 --- /dev/null +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs @@ -0,0 +1,184 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +#nullable enable + +using System; +using System.Collections.Specialized; +using Datadog.Trace.Configuration; +using Datadog.Trace.Configuration.Telemetry; +using Datadog.Trace.FeatureFlags; +using FluentAssertions; +using Xunit; + +namespace Datadog.Trace.Tests.FeatureFlags; + +public class FeatureFlagsSettingsTests +{ + // The source-selection contract is shared across tracers, so these cases mirror the + // system-tests parametric suite (tests/parametric/test_ffe/test_configuration_sources.py). + [Theory] + // Nothing configured: agentless is the default. + [InlineData(null, null, null, FeatureFlagsSource.Agentless)] + // The stable kill switch wins over everything, including a legacy opt-in and an explicit source. + [InlineData("false", null, null, FeatureFlagsSource.Disabled)] + [InlineData("false", null, "true", FeatureFlagsSource.Disabled)] + [InlineData("false", "agentless", null, FeatureFlagsSource.Disabled)] + [InlineData("false", "remote_config", null, FeatureFlagsSource.Disabled)] + // Enabling explicitly does not imply the historical Remote Configuration source. + [InlineData("true", null, null, FeatureFlagsSource.Agentless)] + // An explicit source wins over the legacy key, in both directions. + [InlineData(null, "agentless", "true", FeatureFlagsSource.Agentless)] + [InlineData(null, "remote_config", "false", FeatureFlagsSource.RemoteConfig)] + // The legacy key grandfathers existing adopters, who opted in when RC was the only source. + [InlineData(null, null, "true", FeatureFlagsSource.RemoteConfig)] + [InlineData(null, null, "false", FeatureFlagsSource.Disabled)] + // An explicit new-key value takes precedence over the legacy key, so a stale legacy disable + // does not silently keep Feature Flags off during migration. + [InlineData("true", null, "false", FeatureFlagsSource.Agentless)] + [InlineData("true", null, "true", FeatureFlagsSource.Agentless)] + // An unrecognised source fails closed rather than guessing a billed delivery path. + [InlineData(null, "invalid", null, FeatureFlagsSource.Disabled)] + [InlineData(null, "invalid", "true", FeatureFlagsSource.Disabled)] + // "offline" is a reserved, recognised fail-closed sentinel (not an unrecognised value). + [InlineData(null, "offline", null, FeatureFlagsSource.Disabled)] + [InlineData(null, "offline", "true", FeatureFlagsSource.Disabled)] + public void ResolvesSource(string? enabled, string? source, string? legacyEnabled, object expected) + { + var expectedSource = (FeatureFlagsSource)expected; + var settings = CreateSettings(enabled, source, legacyEnabled); + + settings.Source.Should().Be(expectedSource); + settings.Enabled.Should().Be(expectedSource != FeatureFlagsSource.Disabled); + } + + [Theory] + [InlineData("")] + [InlineData(" ")] + public void TreatsBlankSourceAsUnset(string source) + { + CreateSettings(enabled: null, source: source, legacyEnabled: null) + .Source.Should().Be(FeatureFlagsSource.Agentless); + + // Being semantically unset, a blank source still lets the legacy key grandfather RC. + CreateSettings(enabled: null, source: source, legacyEnabled: "true") + .Source.Should().Be(FeatureFlagsSource.RemoteConfig); + } + + [Theory] + [InlineData("AGENTLESS", FeatureFlagsSource.Agentless)] + [InlineData(" Remote_Config ", FeatureFlagsSource.RemoteConfig)] + public void NormalizesSourceCasingAndWhitespace(string source, object expected) + => CreateSettings(enabled: null, source: source, legacyEnabled: null).Source.Should().Be((FeatureFlagsSource)expected); + + [Fact] + public void UsesDocumentedDefaults() + { + var settings = CreateSettings(null, null, null); + + settings.PollInterval.Should().Be(TimeSpan.FromSeconds(30)); + settings.RequestTimeout.Should().Be(TimeSpan.FromSeconds(5)); + settings.InitializationTimeout.Should().Be(TimeSpan.FromMilliseconds(10_000)); + settings.AgentlessBaseUrl.Should().BeNull(); + } + + [Theory] + [InlineData("60", 60)] + [InlineData("3600", 3600)] + // Out of range values are rejected in favour of the default: a non-positive interval would + // turn polling into a tight loop, and an implausibly large one is a misconfiguration. + [InlineData("0", 30)] + [InlineData("-1", 30)] + [InlineData("3601", 30)] + [InlineData("not-a-number", 30)] + public void ReadsPollInterval(string configured, int expectedSeconds) + { + var settings = CreateSettings( + null, + null, + null, + (ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSourceAgentlessPollIntervalSeconds, configured)); + + settings.PollInterval.Should().Be(TimeSpan.FromSeconds(expectedSeconds)); + } + + [Theory] + [InlineData("1", 1)] + [InlineData("0", 5)] + [InlineData("-2", 5)] + public void ReadsRequestTimeout(string configured, int expectedSeconds) + { + var settings = CreateSettings( + null, + null, + null, + (ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSourceAgentlessRequestTimeoutSeconds, configured)); + + settings.RequestTimeout.Should().Be(TimeSpan.FromSeconds(expectedSeconds)); + } + + [Theory] + [InlineData("1000", 1000)] + [InlineData("0", 10_000)] + [InlineData("-1", 10_000)] + public void ReadsInitializationTimeout(string configured, int expectedMs) + { + var settings = CreateSettings( + null, + null, + null, + (ConfigurationKeys.FeatureFlags.FlaggingProviderInitializationTimeoutMs, configured)); + + settings.InitializationTimeout.Should().Be(TimeSpan.FromMilliseconds(expectedMs)); + } + + [Theory] + [InlineData("https://flags.example.com/ufc", "https://flags.example.com/ufc")] + [InlineData("", null)] + [InlineData(" ", null)] + public void ReadsAgentlessBaseUrl(string configured, string? expected) + { + var settings = CreateSettings( + null, + null, + null, + (ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSourceAgentlessBaseUrl, configured)); + + settings.AgentlessBaseUrl.Should().Be(expected); + } + + private static FeatureFlagsSettings CreateSettings( + string? enabled, + string? source, + string? legacyEnabled, + params (string Key, string Value)[] extra) + { + var collection = new NameValueCollection(); + + if (enabled is not null) + { + collection[ConfigurationKeys.FeatureFlags.FeatureFlagsEnabled] = enabled; + } + + if (source is not null) + { + collection[ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSource] = source; + } + + if (legacyEnabled is not null) + { +#pragma warning disable 618 // superseded, but still honoured for existing adopters + collection[ConfigurationKeys.FeatureFlags.FlaggingProviderEnabled] = legacyEnabled; +#pragma warning restore 618 + } + + foreach (var (key, value) in extra) + { + collection[key] = value; + } + + return new FeatureFlagsSettings(new NameValueConfigurationSource(collection), NullConfigurationTelemetry.Instance); + } +} From 95bf50bd8a1db8c4f465cfb4c259d57903bcd2e7 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 13 Aug 2026 15:52:35 +0300 Subject: [PATCH 05/86] fix(tests): correct AgentlessEndpointTests invalid URL expectations --- .../FeatureFlags/AgentlessEndpointTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs index 1ab87b4c3dec..049a6254025d 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs @@ -79,8 +79,8 @@ public void CustomEndpointAcceptsHttp(string baseUrl) [Theory] [InlineData("ftp://flags.example.com", "The configured Feature Flags agentless URL must use HTTP or HTTPS")] - [InlineData("not a url", "The configured Feature Flags agentless URL is not a valid absolute URL")] - [InlineData(" https://flags.example.com ", "The configured Feature Flags agentless URL is not a valid URL")] // internal whitespace + [InlineData("notaurl", "The configured Feature Flags agentless URL is not a valid absolute URL")] + [InlineData("https://flags.example.com bad", "The configured Feature Flags agentless URL is not a valid URL")] // internal whitespace public void RejectsInvalidBaseUrl(string baseUrl, string expectedError) { AgentlessEndpoint.TryCreate("datadoghq.com", env: null, baseUrl: baseUrl, out var endpoint, out var error) From 4e6232bafed9809aad269594857fc87fb0dbe389 Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 14 Aug 2026 14:45:21 +0300 Subject: [PATCH 06/86] fix(feature-flags): redact agentless base URL telemetry and reject malformed sites safely --- .../Agentless/AgentlessEndpoint.cs | 31 +++++++++++++++++-- .../FeatureFlags/FeatureFlagsSettings.cs | 7 +++-- .../FeatureFlags/AgentlessEndpointTests.cs | 11 +++++++ 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs index 757691bfa4cf..e0f60f1c4e9d 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs @@ -72,13 +72,25 @@ public static bool TryCreate(string? site, string? env, string? baseUrl, out Age return false; } - var managed = new UriBuilder("https", ManagedHostPrefix + trimmedSite!.ToLowerInvariant()) { Path = DefaultPath }; + var managedHost = ManagedHostPrefix + trimmedSite!.ToLowerInvariant(); + if (managedHost.Contains("://") || HasWhitespace(managedHost)) + { + error = "The configured Datadog site is not valid"; + return false; + } + + if (!Uri.TryCreate($"https://{managedHost}{DefaultPath}", UriKind.Absolute, out var managedUri)) + { + error = "The configured Datadog site is not valid"; + return false; + } + if (!StringUtil.IsNullOrEmpty(env)) { - managed.Query = "dd_env=" + Uri.EscapeDataString(env!); + managedUri = new UriBuilder(managedUri) { Query = "dd_env=" + Uri.EscapeDataString(env!) }.Uri; } - endpoint = new AgentlessEndpoint(managed.Uri, isManaged: true); + endpoint = new AgentlessEndpoint(managedUri, isManaged: true); return true; } @@ -113,4 +125,17 @@ public static bool TryCreate(string? site, string? env, string? baseUrl, out Age endpoint = new AgentlessEndpoint(custom, isManaged: false); return true; } + + private static bool HasWhitespace(string value) + { + foreach (var c in value) + { + if (char.IsWhiteSpace(c)) + { + return true; + } + } + + return false; + } } diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs index 71677f39b508..e25c97fd0dfa 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs @@ -62,9 +62,10 @@ public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetr Source = ResolveSource(enabled, configuredSource, legacyEnabled); - AgentlessBaseUrl = config - .WithKeys(ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSourceAgentlessBaseUrl) - .AsString(url => !StringUtil.IsNullOrEmpty(url?.Trim())); + var agentlessBaseUrl = config + .WithKeys(ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSourceAgentlessBaseUrl) + .AsRedactedString(); + AgentlessBaseUrl = !StringUtil.IsNullOrEmpty(agentlessBaseUrl?.Trim()) ? agentlessBaseUrl : null; PollInterval = TimeSpan.FromSeconds( InRangeOrDefault( diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs index 049a6254025d..3a737c8937ff 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs @@ -104,6 +104,17 @@ public void RejectsWhitespaceOnlySiteWithoutBaseUrl() error.Should().Be("No Datadog site is configured"); } + [Theory] + [InlineData("https://datadoghq.com")] // user accidentally includes the scheme + [InlineData("data dog hq.com")] // internal spaces + [InlineData("datadoghq.com:99999")] // invalid port + public void RejectsMalformedSiteWithoutThrowing(string site) + { + AgentlessEndpoint.TryCreate(site, env: null, baseUrl: null, out var endpoint, out var error) + .Should().BeFalse(); + error.Should().Be("The configured Datadog site is not valid"); + } + [Fact] public void ErrorNeverContainsUrl() { From 7ee3cf37bbe143311666245edd39ff05b1886c75 Mon Sep 17 00:00:00 2001 From: Pavel Date: Mon, 17 Aug 2026 14:48:30 +0300 Subject: [PATCH 07/86] fix: remove unnecessary null-forgiving operators in AgentlessEndpoint --- .../Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs index e0f60f1c4e9d..657dbfd2d673 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs @@ -72,7 +72,7 @@ public static bool TryCreate(string? site, string? env, string? baseUrl, out Age return false; } - var managedHost = ManagedHostPrefix + trimmedSite!.ToLowerInvariant(); + var managedHost = ManagedHostPrefix + trimmedSite.ToLowerInvariant(); if (managedHost.Contains("://") || HasWhitespace(managedHost)) { error = "The configured Datadog site is not valid"; @@ -95,7 +95,7 @@ public static bool TryCreate(string? site, string? env, string? baseUrl, out Age } // A URL with internal whitespace is malformed, and Uri parsing is lenient enough to accept it. - foreach (var character in configured!) + foreach (var character in configured) { if (char.IsWhiteSpace(character)) { From 02a6ac6764e466f7524183447cf7aeb8b0adb95a Mon Sep 17 00:00:00 2001 From: Pavel Date: Mon, 17 Aug 2026 14:59:00 +0300 Subject: [PATCH 08/86] fix: drop redundant HasWhitespace check, defer to Uri.TryCreate per review --- .../Agentless/AgentlessEndpoint.cs | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs index 657dbfd2d673..dfa5d032871b 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs @@ -73,7 +73,11 @@ public static bool TryCreate(string? site, string? env, string? baseUrl, out Age } var managedHost = ManagedHostPrefix + trimmedSite.ToLowerInvariant(); - if (managedHost.Contains("://") || HasWhitespace(managedHost)) + // A site accidentally set to e.g. "https://datadoghq.com" would produce a host like + // "ufc-server.ff-cdn.https://datadoghq.com" which Uri.TryCreate accepts as valid + // (treating the "//" as a path separator). Catch it explicitly; whitespace and + // invalid ports are already rejected by TryCreate. + if (managedHost.Contains("://")) { error = "The configured Datadog site is not valid"; return false; @@ -125,17 +129,4 @@ public static bool TryCreate(string? site, string? env, string? baseUrl, out Age endpoint = new AgentlessEndpoint(custom, isManaged: false); return true; } - - private static bool HasWhitespace(string value) - { - foreach (var c in value) - { - if (char.IsWhiteSpace(c)) - { - return true; - } - } - - return false; - } } From 7f72e7fe2791740a0143bfb58fe7cb7219af4b61 Mon Sep 17 00:00:00 2001 From: Pavel Date: Mon, 17 Aug 2026 15:13:13 +0300 Subject: [PATCH 09/86] fix: reword credential comment and remove unnecessary null-forgiving operator on env --- .../Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs index dfa5d032871b..ffd17c5d15bf 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs @@ -40,7 +40,7 @@ private AgentlessEndpoint(Uri uri, bool isManaged) /// /// Gets a value indicating whether this is the endpoint derived from the site. The API key is /// only sent there: a custom endpoint reports its own authentication failure rather than - /// having the credential guessed onto it. + /// having the credential leaked to it. /// public bool IsManaged { get; } @@ -91,7 +91,7 @@ public static bool TryCreate(string? site, string? env, string? baseUrl, out Age if (!StringUtil.IsNullOrEmpty(env)) { - managedUri = new UriBuilder(managedUri) { Query = "dd_env=" + Uri.EscapeDataString(env!) }.Uri; + managedUri = new UriBuilder(managedUri) { Query = "dd_env=" + Uri.EscapeDataString(env) }.Uri; } endpoint = new AgentlessEndpoint(managedUri, isManaged: true); From fb32e7d19017356abbaa58115984e1558f77d728 Mon Sep 17 00:00:00 2001 From: Pavel Date: Mon, 17 Aug 2026 15:48:36 +0300 Subject: [PATCH 10/86] refactor(feature-flags): use config framework for source resolution and validation telemetry --- .../FeatureFlags/FeatureFlagsSettings.cs | 122 ++++++++---------- .../FeatureFlags/SourceSelection.cs | 20 +++ 2 files changed, 72 insertions(+), 70 deletions(-) create mode 100644 tracer/src/Datadog.Trace/FeatureFlags/SourceSelection.cs diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs index e25c97fd0dfa..cffad6588ee0 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs @@ -7,6 +7,7 @@ using System; using Datadog.Trace.Configuration; +using Datadog.Trace.Configuration.ConfigurationSources.Telemetry; using Datadog.Trace.Configuration.Telemetry; using Datadog.Trace.Logging; using Datadog.Trace.Telemetry; @@ -47,7 +48,17 @@ public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetr #pragma warning disable 618 // superseded, but still honoured so existing adopters keep their source var legacyEnabled = config.WithKeys(ConfigurationKeys.FeatureFlags.FlaggingProviderEnabled).AsBool(); #pragma warning restore 618 - var configuredSource = config.WithKeys(ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSource).AsString(); + + // Use GetAsClass so the config framework records both the raw string and the resolved + // value in configuration telemetry. The converter maps recognised values to a + // SourceSelection record, returns Failure for unrecognised values (so the framework + // records the fallback), and returns Failure for null/empty (so "not set" also falls + // back to the default, which is null — meaning "not explicitly set"). + var configuredSource = config + .WithKeys(ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSource) + .GetAsClass( + validator: null, + converter: ConvertSource); if (legacyEnabled is not null) { @@ -65,25 +76,21 @@ public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetr var agentlessBaseUrl = config .WithKeys(ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSourceAgentlessBaseUrl) .AsRedactedString(); - AgentlessBaseUrl = !StringUtil.IsNullOrEmpty(agentlessBaseUrl?.Trim()) ? agentlessBaseUrl : null; + AgentlessBaseUrl = !StringUtil.IsNullOrWhiteSpace(agentlessBaseUrl) ? agentlessBaseUrl : null; PollInterval = TimeSpan.FromSeconds( - InRangeOrDefault( - config.WithKeys(ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSourceAgentlessPollIntervalSeconds).AsInt32(), - ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSourceAgentlessPollIntervalSeconds, - DefaultPollIntervalSeconds, - MaxPollIntervalSeconds)); + config.WithKeys(ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSourceAgentlessPollIntervalSeconds) + .AsInt32(DefaultPollIntervalSeconds, v => v > 0 && v <= MaxPollIntervalSeconds) + .Value); RequestTimeout = TimeSpan.FromSeconds( - InRangeOrDefault( - config.WithKeys(ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSourceAgentlessRequestTimeoutSeconds).AsInt32(), - ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSourceAgentlessRequestTimeoutSeconds, - DefaultRequestTimeoutSeconds, - maximumSeconds: null)); + config.WithKeys(ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSourceAgentlessRequestTimeoutSeconds) + .AsInt32(DefaultRequestTimeoutSeconds, v => v > 0) + .Value); Site = config .WithKeys(ConfigurationKeys.Site) - .AsString(DefaultSite, site => !StringUtil.IsNullOrEmpty(site?.Trim())); + .AsString(DefaultSite, site => !StringUtil.IsNullOrWhiteSpace(site)); Env = config.WithKeys(ConfigurationKeys.Environment).AsString(); @@ -145,85 +152,60 @@ public static FeatureFlagsSettings FromDefaultSource() => new(GlobalConfigurationSource.Instance, TelemetryFactory.Config); /// - /// Resolves the delivery source. Shared across tracers, so the ordering is deliberate: - /// the stable kill switch wins over everything, an explicit source wins over the legacy key - /// (and fails closed when unrecognised), the legacy key grandfathers existing adopters onto - /// Remote Configuration, and everything else defaults to agentless. + /// Converts a configuration source string to a . + /// Used as the converter for GetAsClass so the + /// config framework records both the raw string and the resolved value in telemetry. /// - internal static FeatureFlagsSource ResolveSource(bool? enabled, string? configuredSource, bool? legacyEnabled) + private static ParsingResult ConvertSource(string? value) { - var normalizedSource = NormalizeSource(configuredSource); - - if (enabled == false) + if (value is null) { - return FeatureFlagsSource.Disabled; + return ParsingResult.Failure(); } - if (normalizedSource is not null) + var normalized = value.Trim().ToLowerInvariant(); + if (normalized.Length == 0) { - switch (normalizedSource) - { - case AgentlessSourceName: - return FeatureFlagsSource.Agentless; - case RemoteConfigSourceName: - return FeatureFlagsSource.RemoteConfig; - case OfflineSourceName: - // Reserved fail-closed sentinel: the provider is intentionally off, so no warning. - return FeatureFlagsSource.Disabled; - default: - Log.Warning( - "Unsupported {SourceKey} value '{Source}'. Feature Flags are disabled.", - ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSource, - normalizedSource); - return FeatureFlagsSource.Disabled; - } + return ParsingResult.Failure(); } - // The legacy key only grandfathers adopters who have not migrated: an explicit new-key - // value (true or false) takes precedence, so the legacy key is consulted only when the - // new key was left unset. - if (enabled is null && legacyEnabled is not null) + return normalized switch { - return legacyEnabled.Value ? FeatureFlagsSource.RemoteConfig : FeatureFlagsSource.Disabled; - } - - return FeatureFlagsSource.Agentless; + AgentlessSourceName => ParsingResult.Success(new SourceSelection(FeatureFlagsSource.Agentless, isValid: true)), + RemoteConfigSourceName => ParsingResult.Success(new SourceSelection(FeatureFlagsSource.RemoteConfig, isValid: true)), + OfflineSourceName => ParsingResult.Success(new SourceSelection(FeatureFlagsSource.Disabled, isValid: true)), + _ => ParsingResult.Success(new SourceSelection(FeatureFlagsSource.Disabled, isValid: false)), + }; } /// - /// An empty or whitespace-only source is semantically unset, not an unrecognised value. + /// Resolves the delivery source. Shared across tracers, so the ordering is deliberate: + /// the stable kill switch wins over everything, an explicit source wins over the legacy key + /// (and fails closed when unrecognised), the legacy key grandfathers existing adopters onto + /// Remote Configuration, and everything else defaults to agentless. /// - private static string? NormalizeSource(string? configuredSource) + private static FeatureFlagsSource ResolveSource(bool? enabled, SourceSelection? configuredSource, bool? legacyEnabled) { - if (configuredSource is null) + if (enabled == false) { - return null; + return FeatureFlagsSource.Disabled; } - var normalized = configuredSource.Trim().ToLowerInvariant(); - return normalized.Length == 0 ? null : normalized; - } - - internal static int InRangeOrDefault(int? configured, string key, int defaultSeconds, int? maximumSeconds) - { - if (configured is null) + if (configuredSource is not null) { - return defaultSeconds; + // "offline" is a reserved fail-closed sentinel: the provider is intentionally off. + // An invalid value also fails closed. Both are mapped to Disabled by the converter. + return configuredSource.Source; } - var value = configured.Value; - if (value <= 0 || (maximumSeconds is { } maximum && value > maximum)) + // The legacy key only grandfathers adopters who have not migrated: an explicit new-key + // value (true or false) takes precedence, so the legacy key is consulted only when the + // new key was left unset. + if (enabled is null && legacyEnabled is not null) { - // A non-positive interval would turn polling into a tight loop against the endpoint, - // so an out-of-range value is rejected rather than honoured. - Log.Warning( - "Invalid value {Key}={Value}. Using {Default} seconds instead.", - key, - value, - defaultSeconds); - return defaultSeconds; + return legacyEnabled.Value ? FeatureFlagsSource.RemoteConfig : FeatureFlagsSource.Disabled; } - return value; + return FeatureFlagsSource.Agentless; } } diff --git a/tracer/src/Datadog.Trace/FeatureFlags/SourceSelection.cs b/tracer/src/Datadog.Trace/FeatureFlags/SourceSelection.cs new file mode 100644 index 000000000000..960006d8c009 --- /dev/null +++ b/tracer/src/Datadog.Trace/FeatureFlags/SourceSelection.cs @@ -0,0 +1,20 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +#nullable enable + +namespace Datadog.Trace.FeatureFlags; + +/// +/// A wrapper used as the converter result type so the config framework records telemetry, +/// while allowing to distinguish "not set" (null) from +/// "set to an invalid value" (non-null with ). +/// +internal sealed class SourceSelection(FeatureFlagsSource source, bool isValid) +{ + public FeatureFlagsSource Source { get; } = source; + + public bool IsValid { get; } = isValid; +} From 2911d785e826636a40748d04ca379af32b9201cd Mon Sep 17 00:00:00 2001 From: Pavel Date: Mon, 17 Aug 2026 16:00:34 +0300 Subject: [PATCH 11/86] fix: mark DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_BASE_URL as sensitive in yaml --- .../Datadog.Trace/Configuration/supported-configurations.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/tracer/src/Datadog.Trace/Configuration/supported-configurations.yaml b/tracer/src/Datadog.Trace/Configuration/supported-configurations.yaml index eef60327d1c8..33a8c0f6a63b 100644 --- a/tracer/src/Datadog.Trace/Configuration/supported-configurations.yaml +++ b/tracer/src/Datadog.Trace/Configuration/supported-configurations.yaml @@ -3199,6 +3199,7 @@ supportedConfigurations: - implementation: A scope: managed type: string + sensitive: true default: null product: FeatureFlags const_name: FeatureFlagsConfigurationSourceAgentlessBaseUrl From 7af7bc53e90b7c53fa0be3832eff1ed390a9dd09 Mon Sep 17 00:00:00 2001 From: Pavel Date: Mon, 17 Aug 2026 16:44:14 +0300 Subject: [PATCH 12/86] refactor: pass site/env/apiKey via constructor instead of re-reading from config --- .../FeatureFlags/FeatureFlagsSettings.cs | 21 +++++++++++-------- .../FeatureFlags/FeatureFlagsSettingsTests.cs | 2 +- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs index cffad6588ee0..488bf1e79f97 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs @@ -37,7 +37,7 @@ internal sealed class FeatureFlagsSettings private static readonly IDatadogLogger Log = DatadogLogging.GetLoggerFor(typeof(FeatureFlagsSettings)); - public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetry telemetry) + public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetry telemetry, string? site, string? env, string? apiKey) { source ??= NullConfigurationSource.Instance; var config = new ConfigurationBuilder(source, telemetry); @@ -88,13 +88,9 @@ public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetr .AsInt32(DefaultRequestTimeoutSeconds, v => v > 0) .Value); - Site = config - .WithKeys(ConfigurationKeys.Site) - .AsString(DefaultSite, site => !StringUtil.IsNullOrWhiteSpace(site)); - - Env = config.WithKeys(ConfigurationKeys.Environment).AsString(); - - ApiKey = config.WithKeys(ConfigurationKeys.ApiKey).AsRedactedString(); + Site = StringUtil.IsNullOrWhiteSpace(site) ? DefaultSite : site; + Env = env; + ApiKey = apiKey; var initializationTimeoutMs = config .WithKeys(ConfigurationKeys.FeatureFlags.FlaggingProviderInitializationTimeoutMs) @@ -149,7 +145,14 @@ public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetr public TimeSpan InitializationTimeout { get; } public static FeatureFlagsSettings FromDefaultSource() - => new(GlobalConfigurationSource.Instance, TelemetryFactory.Config); + { + var source = GlobalConfigurationSource.Instance; + var config = new ConfigurationBuilder(source, TelemetryFactory.Config); + var site = config.WithKeys(ConfigurationKeys.Site).AsString(DefaultSite, s => !StringUtil.IsNullOrWhiteSpace(s)); + var env = config.WithKeys(ConfigurationKeys.Environment).AsString(); + var apiKey = config.WithKeys(ConfigurationKeys.ApiKey).AsRedactedString(); + return new FeatureFlagsSettings(source, TelemetryFactory.Config, site, env, apiKey); + } /// /// Converts a configuration source string to a . diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs index ec8be148a134..ebdeaa734cf9 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs @@ -179,6 +179,6 @@ private static FeatureFlagsSettings CreateSettings( collection[key] = value; } - return new FeatureFlagsSettings(new NameValueConfigurationSource(collection), NullConfigurationTelemetry.Instance); + return new FeatureFlagsSettings(new NameValueConfigurationSource(collection), NullConfigurationTelemetry.Instance, site: null, env: null, apiKey: null); } } From 8f406d94371dd7657d6d57569a9cfe5f729fda88 Mon Sep 17 00:00:00 2001 From: Pavel Date: Tue, 18 Aug 2026 15:24:46 +0300 Subject: [PATCH 13/86] [FeatureFlags] Resolve the configuration source in a single telemetry-reported read --- .../Configuration/TracerSettings.cs | 11 ++ .../FeatureFlags/FeatureFlagsSettings.cs | 115 ++++++++---------- .../FeatureFlags/SourceSelection.cs | 20 --- .../FeatureFlags/FeatureFlagsSettingsTests.cs | 24 +++- 4 files changed, 88 insertions(+), 82 deletions(-) delete mode 100644 tracer/src/Datadog.Trace/FeatureFlags/SourceSelection.cs diff --git a/tracer/src/Datadog.Trace/Configuration/TracerSettings.cs b/tracer/src/Datadog.Trace/Configuration/TracerSettings.cs index 6e04e7a41e71..1ce04feb0861 100644 --- a/tracer/src/Datadog.Trace/Configuration/TracerSettings.cs +++ b/tracer/src/Datadog.Trace/Configuration/TracerSettings.cs @@ -15,6 +15,7 @@ using Datadog.Trace.Configuration.ConfigurationSources.Telemetry; using Datadog.Trace.Configuration.Telemetry; using Datadog.Trace.DataStreamsMonitoring.TransactionTracking; +using Datadog.Trace.FeatureFlags; using Datadog.Trace.Logging; using Datadog.Trace.Logging.DirectSubmission; using Datadog.Trace.PlatformHelpers; @@ -888,6 +889,11 @@ not null when string.Equals(value, "otlp", StringComparison.OrdinalIgnoreCase) = Manager = new(source, this, telemetry, errorLog); + // Created after the manager so the environment can be taken from the initial mutable + // settings, which also honour the "env" entry of DD_TAGS. It is captured once, so a + // later dynamic-configuration change to "env" does not move the agentless endpoint. + FeatureFlags = new FeatureFlagsSettings(source, telemetry, Manager.InitialMutableSettings.Environment); + // OTLP span metrics require OTLP trace export (see TracerManagerFactory.GetAgentWriter). // Force to false otherwise, even if explicitly requested. if (OtelTracesSpanMetricsEnabled && !Manager.InitialExporterSettings.IsOtlpTraceExport) @@ -1500,6 +1506,11 @@ not null when string.Equals(value, "otlp", StringComparison.OrdinalIgnoreCase) = /// internal bool IsSpanEnrichmentEnabled { get; } + /// + /// Gets the Feature Flags settings, which select where flag configuration is delivered from. + /// + internal FeatureFlagsSettings FeatureFlags { get; } + /// /// Gets a value indicating whether partial flush is enabled /// diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs index 488bf1e79f97..f9c804f30364 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs @@ -10,7 +10,6 @@ using Datadog.Trace.Configuration.ConfigurationSources.Telemetry; using Datadog.Trace.Configuration.Telemetry; using Datadog.Trace.Logging; -using Datadog.Trace.Telemetry; using Datadog.Trace.Util; namespace Datadog.Trace.FeatureFlags; @@ -37,7 +36,7 @@ internal sealed class FeatureFlagsSettings private static readonly IDatadogLogger Log = DatadogLogging.GetLoggerFor(typeof(FeatureFlagsSettings)); - public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetry telemetry, string? site, string? env, string? apiKey) + public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetry telemetry, string? env) { source ??= NullConfigurationSource.Instance; var config = new ConfigurationBuilder(source, telemetry); @@ -49,17 +48,6 @@ public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetr var legacyEnabled = config.WithKeys(ConfigurationKeys.FeatureFlags.FlaggingProviderEnabled).AsBool(); #pragma warning restore 618 - // Use GetAsClass so the config framework records both the raw string and the resolved - // value in configuration telemetry. The converter maps recognised values to a - // SourceSelection record, returns Failure for unrecognised values (so the framework - // records the fallback), and returns Failure for null/empty (so "not set" also falls - // back to the default, which is null — meaning "not explicitly set"). - var configuredSource = config - .WithKeys(ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSource) - .GetAsClass( - validator: null, - converter: ConvertSource); - if (legacyEnabled is not null) { #pragma warning disable 618 @@ -71,7 +59,26 @@ public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetr #pragma warning restore 618 } - Source = ResolveSource(enabled, configuredSource, legacyEnabled); + // The source is resolved in a single read so configuration telemetry reports the value we + // actually use. Shared across tracers, so the precedence is deliberate: the stable kill + // switch wins over everything (expressed as a validator that rejects any configured value), + // an explicit source wins over the legacy key, the legacy key grandfathers existing + // adopters onto Remote Configuration, and everything else defaults to agentless. + DefaultResult defaultSource = enabled switch + { + false => new(FeatureFlagsSource.Disabled, OfflineSourceName), + null when legacyEnabled is not null => legacyEnabled.Value + ? new(FeatureFlagsSource.RemoteConfig, RemoteConfigSourceName) + : new(FeatureFlagsSource.Disabled, OfflineSourceName), + _ => new(FeatureFlagsSource.Agentless, AgentlessSourceName), + }; + + Source = config + .WithKeys(ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSource) + .GetAs( + defaultSource, + validator: enabled == false ? static _ => false : static _ => true, + converter: ConvertSource); var agentlessBaseUrl = config .WithKeys(ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSourceAgentlessBaseUrl) @@ -88,9 +95,15 @@ public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetr .AsInt32(DefaultRequestTimeoutSeconds, v => v > 0) .Value); - Site = StringUtil.IsNullOrWhiteSpace(site) ? DefaultSite : site; + // DD_SITE and DD_API_KEY are not extracted on TracerSettings, so they are read here as the + // other product settings do (TelemetrySettings, DirectLogSubmissionSettings). DD_ENV is + // passed in, because TracerSettings also honours the "env" entry of DD_TAGS and re-reading + // the key alone would disagree with the rest of the tracer. + Site = config + .WithKeys(ConfigurationKeys.Site) + .AsString(DefaultSite, static site => !StringUtil.IsNullOrWhiteSpace(site)); Env = env; - ApiKey = apiKey; + ApiKey = config.WithKeys(ConfigurationKeys.ApiKey).AsRedactedString(); var initializationTimeoutMs = config .WithKeys(ConfigurationKeys.FeatureFlags.FlaggingProviderInitializationTimeoutMs) @@ -144,71 +157,51 @@ public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetr /// public TimeSpan InitializationTimeout { get; } - public static FeatureFlagsSettings FromDefaultSource() - { - var source = GlobalConfigurationSource.Instance; - var config = new ConfigurationBuilder(source, TelemetryFactory.Config); - var site = config.WithKeys(ConfigurationKeys.Site).AsString(DefaultSite, s => !StringUtil.IsNullOrWhiteSpace(s)); - var env = config.WithKeys(ConfigurationKeys.Environment).AsString(); - var apiKey = config.WithKeys(ConfigurationKeys.ApiKey).AsRedactedString(); - return new FeatureFlagsSettings(source, TelemetryFactory.Config, site, env, apiKey); - } - /// - /// Converts a configuration source string to a . - /// Used as the converter for GetAsClass so the - /// config framework records both the raw string and the resolved value in telemetry. + /// Converts a configured source name to a . A blank value is + /// treated as unset so the default applies, and an unrecognised one fails closed: it resolves + /// to rather than falling back to a billed delivery + /// path, which is why it is reported as a successful conversion. /// - private static ParsingResult ConvertSource(string? value) + private static ParsingResult ConvertSource(string? value) { - if (value is null) + if (StringUtil.IsNullOrWhiteSpace(value)) { - return ParsingResult.Failure(); + return ParsingResult.Failure(); } - var normalized = value.Trim().ToLowerInvariant(); - if (normalized.Length == 0) + // Compared without allocating. A value with surrounding whitespace is trimmed only once the + // direct comparisons have failed, so the common path stays allocation-free. + if (TryMatch(value, out var source) || TryMatch(value.Trim(), out source)) { - return ParsingResult.Failure(); + return ParsingResult.Success(source); } - return normalized switch - { - AgentlessSourceName => ParsingResult.Success(new SourceSelection(FeatureFlagsSource.Agentless, isValid: true)), - RemoteConfigSourceName => ParsingResult.Success(new SourceSelection(FeatureFlagsSource.RemoteConfig, isValid: true)), - OfflineSourceName => ParsingResult.Success(new SourceSelection(FeatureFlagsSource.Disabled, isValid: true)), - _ => ParsingResult.Success(new SourceSelection(FeatureFlagsSource.Disabled, isValid: false)), - }; + return ParsingResult.Success(FeatureFlagsSource.Disabled); } - /// - /// Resolves the delivery source. Shared across tracers, so the ordering is deliberate: - /// the stable kill switch wins over everything, an explicit source wins over the legacy key - /// (and fails closed when unrecognised), the legacy key grandfathers existing adopters onto - /// Remote Configuration, and everything else defaults to agentless. - /// - private static FeatureFlagsSource ResolveSource(bool? enabled, SourceSelection? configuredSource, bool? legacyEnabled) + private static bool TryMatch(string value, out FeatureFlagsSource source) { - if (enabled == false) + if (string.Equals(value, AgentlessSourceName, StringComparison.OrdinalIgnoreCase)) { - return FeatureFlagsSource.Disabled; + source = FeatureFlagsSource.Agentless; + return true; } - if (configuredSource is not null) + if (string.Equals(value, RemoteConfigSourceName, StringComparison.OrdinalIgnoreCase)) { - // "offline" is a reserved fail-closed sentinel: the provider is intentionally off. - // An invalid value also fails closed. Both are mapped to Disabled by the converter. - return configuredSource.Source; + source = FeatureFlagsSource.RemoteConfig; + return true; } - // The legacy key only grandfathers adopters who have not migrated: an explicit new-key - // value (true or false) takes precedence, so the legacy key is consulted only when the - // new key was left unset. - if (enabled is null && legacyEnabled is not null) + // "offline" is a reserved fail-closed sentinel: the provider is intentionally off. + if (string.Equals(value, OfflineSourceName, StringComparison.OrdinalIgnoreCase)) { - return legacyEnabled.Value ? FeatureFlagsSource.RemoteConfig : FeatureFlagsSource.Disabled; + source = FeatureFlagsSource.Disabled; + return true; } - return FeatureFlagsSource.Agentless; + source = FeatureFlagsSource.Disabled; + return false; } } diff --git a/tracer/src/Datadog.Trace/FeatureFlags/SourceSelection.cs b/tracer/src/Datadog.Trace/FeatureFlags/SourceSelection.cs deleted file mode 100644 index 960006d8c009..000000000000 --- a/tracer/src/Datadog.Trace/FeatureFlags/SourceSelection.cs +++ /dev/null @@ -1,20 +0,0 @@ -// -// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. -// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. -// - -#nullable enable - -namespace Datadog.Trace.FeatureFlags; - -/// -/// A wrapper used as the converter result type so the config framework records telemetry, -/// while allowing to distinguish "not set" (null) from -/// "set to an invalid value" (non-null with ). -/// -internal sealed class SourceSelection(FeatureFlagsSource source, bool isValid) -{ - public FeatureFlagsSource Source { get; } = source; - - public bool IsValid { get; } = isValid; -} diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs index ebdeaa734cf9..efd24e3d9419 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs @@ -149,6 +149,28 @@ public void ReadsAgentlessBaseUrl(string configured, string? expected) settings.AgentlessBaseUrl.Should().Be(expected); } + [Fact] + public void ReadsSiteAndApiKeyFromTheConfigurationSource() + { + var settings = CreateSettings( + null, + null, + null, + (ConfigurationKeys.Site, "datadoghq.eu"), + (ConfigurationKeys.ApiKey, "an-api-key")); + + settings.Site.Should().Be("datadoghq.eu"); + settings.ApiKey.Should().Be("an-api-key"); + } + + [Theory] + // A blank site is rejected in favour of the default, so the managed endpoint stays resolvable. + [InlineData("")] + [InlineData(" ")] + public void FallsBackToTheDefaultSite(string configured) + => CreateSettings(null, null, null, (ConfigurationKeys.Site, configured)) + .Site.Should().Be(FeatureFlagsSettings.DefaultSite); + private static FeatureFlagsSettings CreateSettings( string? enabled, string? source, @@ -179,6 +201,6 @@ private static FeatureFlagsSettings CreateSettings( collection[key] = value; } - return new FeatureFlagsSettings(new NameValueConfigurationSource(collection), NullConfigurationTelemetry.Instance, site: null, env: null, apiKey: null); + return new FeatureFlagsSettings(new NameValueConfigurationSource(collection), NullConfigurationTelemetry.Instance, env: null); } } From ada921dbd0ecf91fd29888427c623f5209ae11cc Mon Sep 17 00:00:00 2001 From: Pavel Date: Tue, 18 Aug 2026 17:00:18 +0300 Subject: [PATCH 14/86] [FeatureFlags] Make AgentlessEndpoint a class so a failed TryCreate yields null --- .../Agentless/AgentlessEndpoint.cs | 13 +++-- .../FeatureFlags/AgentlessEndpointTests.cs | 51 +++++++++---------- 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs index ffd17c5d15bf..2ebc7b03b3b3 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs @@ -6,14 +6,17 @@ #nullable enable using System; +using System.Diagnostics.CodeAnalysis; using Datadog.Trace.Util; namespace Datadog.Trace.FeatureFlags.Agentless; /// -/// The agentless endpoint, derived from the Datadog site or a custom base URL. +/// The agentless endpoint, derived from the Datadog site or a custom base URL. A class rather +/// than a struct so that "no endpoint" is null instead of a default instance whose +/// non-nullable is null; it is built once per process, so the allocation is free. /// -internal readonly struct AgentlessEndpoint +internal sealed class AgentlessEndpoint { /// /// Canonical rules-based server path, appended to the managed CDN host and to custom base @@ -54,12 +57,12 @@ private AgentlessEndpoint(Uri uri, bool isManaged) /// The Datadog site, for example datadoghq.com. /// The configured environment, or null. /// The configured endpoint override, or null. - /// The resulting endpoint. + /// The resulting endpoint, or null when none could be built. /// Why the configured base URL was rejected. Never contains the URL, which may carry credentials. /// true when an endpoint could be built. - public static bool TryCreate(string? site, string? env, string? baseUrl, out AgentlessEndpoint endpoint, out string? error) + public static bool TryCreate(string? site, string? env, string? baseUrl, [NotNullWhen(true)] out AgentlessEndpoint? endpoint, out string? error) { - endpoint = default; + endpoint = null; error = null; var configured = baseUrl?.Trim(); diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs index 3a737c8937ff..2fbda55d3836 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs @@ -23,36 +23,23 @@ public class AgentlessEndpointTests [InlineData("ddog-gov.com", "https://ufc-server.ff-cdn.ddog-gov.com" + DefaultPath)] // govcloud public void DerivesManagedEndpointFromSite(string site, string expected) { - AgentlessEndpoint.TryCreate(site, env: null, baseUrl: null, out var endpoint, out var error) - .Should().BeTrue(); - error.Should().BeNull(); + var endpoint = Create(site); + endpoint.IsManaged.Should().BeTrue(); endpoint.Uri.ToString().Should().Be(expected); } [Fact] public void AddsDdEnvWhenEnvIsConfigured() - { - AgentlessEndpoint.TryCreate("datadoghq.com", env: "production", baseUrl: null, out var endpoint, out _) - .Should().BeTrue(); - endpoint.Uri.Query.Should().Be("?dd_env=production"); - } + => Create("datadoghq.com", env: "production").Uri.Query.Should().Be("?dd_env=production"); [Fact] public void DoesNotAddDdEnvWhenEnvIsNull() - { - AgentlessEndpoint.TryCreate("datadoghq.com", env: null, baseUrl: null, out var endpoint, out _) - .Should().BeTrue(); - endpoint.Uri.Query.Should().BeEmpty(); - } + => Create("datadoghq.com").Uri.Query.Should().BeEmpty(); [Fact] public void EscapesDdEnvValue() - { - AgentlessEndpoint.TryCreate("datadoghq.com", env: "my env&test", baseUrl: null, out var endpoint, out _) - .Should().BeTrue(); - endpoint.Uri.Query.Should().Be("?dd_env=my%20env%26test"); - } + => Create("datadoghq.com", env: "my env&test").Uri.Query.Should().Be("?dd_env=my%20env%26test"); [Theory] [InlineData("https://flags.example.com", "https://flags.example.com" + DefaultPath)] @@ -61,9 +48,8 @@ public void EscapesDdEnvValue() [InlineData("https://flags.example.com/ufc?custom=query", "https://flags.example.com/ufc?custom=query")] public void CustomEndpointReceivesCanonicalPathForOriginOnly(string baseUrl, string expected) { - AgentlessEndpoint.TryCreate("datadoghq.com", env: null, baseUrl: baseUrl, out var endpoint, out var error) - .Should().BeTrue(); - error.Should().BeNull(); + var endpoint = Create("datadoghq.com", baseUrl: baseUrl); + endpoint.IsManaged.Should().BeFalse(); endpoint.Uri.ToString().Should().Be(expected); } @@ -71,11 +57,7 @@ public void CustomEndpointReceivesCanonicalPathForOriginOnly(string baseUrl, str [Theory] [InlineData("http://localhost:8080/ufc")] // http accepted for custom endpoints public void CustomEndpointAcceptsHttp(string baseUrl) - { - AgentlessEndpoint.TryCreate("datadoghq.com", env: null, baseUrl: baseUrl, out var endpoint, out var error) - .Should().BeTrue(); - endpoint.IsManaged.Should().BeFalse(); - } + => Create("datadoghq.com", baseUrl: baseUrl).IsManaged.Should().BeFalse(); [Theory] [InlineData("ftp://flags.example.com", "The configured Feature Flags agentless URL must use HTTP or HTTPS")] @@ -86,6 +68,7 @@ public void RejectsInvalidBaseUrl(string baseUrl, string expectedError) AgentlessEndpoint.TryCreate("datadoghq.com", env: null, baseUrl: baseUrl, out var endpoint, out var error) .Should().BeFalse(); error.Should().Be(expectedError); + endpoint.Should().BeNull(); } [Fact] @@ -94,6 +77,7 @@ public void RejectsEmptySiteWithoutBaseUrl() AgentlessEndpoint.TryCreate(site: null, env: null, baseUrl: null, out var endpoint, out var error) .Should().BeFalse(); error.Should().Be("No Datadog site is configured"); + endpoint.Should().BeNull(); } [Fact] @@ -102,6 +86,7 @@ public void RejectsWhitespaceOnlySiteWithoutBaseUrl() AgentlessEndpoint.TryCreate(" ", env: null, baseUrl: null, out var endpoint, out var error) .Should().BeFalse(); error.Should().Be("No Datadog site is configured"); + endpoint.Should().BeNull(); } [Theory] @@ -113,6 +98,7 @@ public void RejectsMalformedSiteWithoutThrowing(string site) AgentlessEndpoint.TryCreate(site, env: null, baseUrl: null, out var endpoint, out var error) .Should().BeFalse(); error.Should().Be("The configured Datadog site is not valid"); + endpoint.Should().BeNull(); } [Fact] @@ -124,4 +110,17 @@ public void ErrorNeverContainsUrl() error.Should().NotContain("user"); error.Should().NotContain("pass"); } + + // Builds an endpoint that is expected to be valid, and returns it as non-nullable so the + // assertions can read it directly. Throwing rather than asserting keeps the compiler's nullable + // analysis satisfied without a null-forgiving operator, which would let an assertion be + // silently skipped if the endpoint were ever null. + private static AgentlessEndpoint Create(string? site, string? env = null, string? baseUrl = null) + { + AgentlessEndpoint.TryCreate(site, env, baseUrl, out var endpoint, out var error) + .Should().BeTrue(); + error.Should().BeNull(); + + return endpoint ?? throw new InvalidOperationException("TryCreate reported success without producing an endpoint."); + } } From c224e2d20c552327a8223fcb7a8530189b1137ba Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 13 Aug 2026 14:53:55 +0300 Subject: [PATCH 15/86] feat(feature-flags): add UfcConfigurationParser for JSON:API envelope validation --- .../Agentless/UfcConfigurationParser.cs | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs new file mode 100644 index 000000000000..58bbfe2691e9 --- /dev/null +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs @@ -0,0 +1,90 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +#nullable enable + +using System; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using Datadog.Trace.FeatureFlags.Rcm.Model; +using Datadog.Trace.Vendors.Newtonsoft.Json; +using Datadog.Trace.Vendors.Newtonsoft.Json.Linq; + +namespace Datadog.Trace.FeatureFlags.Agentless; + +/// +/// Reads the JSON:API envelope returned by the agentless endpoint. +/// +internal static class UfcConfigurationParser +{ + private const string ResourceType = "universal-flag-configuration"; + + /// + /// Validates a JSON:API Universal Flag Configuration response and returns data.attributes, + /// which is the document the evaluator consumes. A raw UFC document is rejected, including from + /// a custom endpoint, so that every source agrees on one wire format. + /// + /// The response body. + /// The parsed configuration. + /// Why the payload was rejected. + /// true when the payload matches the contract. + public static bool TryParse(string? body, [NotNullWhen(true)] out ServerConfiguration? configuration, out string? error) + { + configuration = null; + error = null; + + JToken payload; + try + { + using var stringReader = new StringReader(body ?? string.Empty); + + // Timestamps stay strings: the model carries createdAt verbatim, and letting Newtonsoft + // turn it into a date would also make the type check below fail. + using var jsonReader = new JsonTextReader(stringReader) { DateParseHandling = DateParseHandling.None }; + payload = JToken.ReadFrom(jsonReader); + } + catch (Exception) + { + error = "Malformed UFC payload"; + return false; + } + + if (payload is not JObject + || payload["data"] is not JObject data + || data["type"]?.Value() != ResourceType) + { + error = "Expected a JSON:API Universal Flag Configuration resource"; + return false; + } + + if (data["attributes"] is not JObject attributes + || attributes["format"]?.Type != JTokenType.String + || attributes["createdAt"]?.Type != JTokenType.String + || attributes["environment"] is not JObject environment + || environment["name"]?.Type != JTokenType.String + || attributes["flags"] is not JObject) + { + error = "Expected a Universal Flag Configuration v1 object"; + return false; + } + + try + { + configuration = attributes.ToObject(); + } + catch (Exception) + { + configuration = null; + } + + if (configuration is null) + { + error = "Expected a Universal Flag Configuration v1 object"; + return false; + } + + return true; + } +} From 6a5f49a9091ac032d4919b3983e5302ad5094691 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 13 Aug 2026 15:01:50 +0300 Subject: [PATCH 16/86] test(feature-flags): add UfcConfigurationParserTests for JSON:API envelope validation --- .../Agentless/AgentlessConfigurationSource.cs | 399 ++++++++++++++++++ .../UfcConfigurationParserTests.cs | 108 +++++ 2 files changed, 507 insertions(+) create mode 100644 tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs create mode 100644 tracer/test/Datadog.Trace.Tests/FeatureFlags/UfcConfigurationParserTests.cs diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs new file mode 100644 index 000000000000..6d23a7045c31 --- /dev/null +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs @@ -0,0 +1,399 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +#nullable enable + +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Threading; +using System.Threading.Tasks; +using Datadog.Trace.Agent; +using Datadog.Trace.Agent.Transports; +using Datadog.Trace.FeatureFlags.Rcm.Model; +using Datadog.Trace.Headers; +using Datadog.Trace.Logging; +using Datadog.Trace.Telemetry; +using Datadog.Trace.Util; + +namespace Datadog.Trace.FeatureFlags.Agentless; + +/// +/// Polls the agentless endpoint for flag configuration. Polling is billable, so it is only +/// started once application code has activated the provider. +/// +internal sealed class AgentlessConfigurationSource : IDisposable +{ + private const int MaxAttempts = 3; + private const double RetryJitter = 0.2; + + private static readonly TimeSpan FirstRetryMin = TimeSpan.FromSeconds(2); + private static readonly TimeSpan FirstRetryMax = TimeSpan.FromSeconds(10); + private static readonly TimeSpan SecondRetryMin = TimeSpan.FromSeconds(5); + private static readonly TimeSpan SecondRetryMax = TimeSpan.FromSeconds(30); + + // A jittered retry delay never drops below this, so a short poll interval cannot turn + // retries into a burst against the endpoint. + private static readonly TimeSpan MinRetryDelay = TimeSpan.FromSeconds(1); + + private static readonly IDatadogLogger Log = DatadogLogging.GetLoggerFor(typeof(AgentlessConfigurationSource)); + + private readonly IApiRequestFactory _requestFactory; + private readonly Uri _endpoint; + private readonly TimeSpan _pollInterval; + private readonly Func _applyConfiguration; + private readonly Func _waitAsync; + private readonly CancellationTokenSource _shutdown = new(); + private readonly Random _random = new(); + + // Only ever touched from the poll loop. + private readonly HashSet _loggedFailureCategories = new(); + private bool _malformedPayloadLogged; + private bool _applyFailureLogged; + private string? _etag; + + private int _started; + + internal AgentlessConfigurationSource( + Uri endpoint, + IApiRequestFactory requestFactory, + TimeSpan pollInterval, + Func applyConfiguration, + Func? waitAsync = null) + { + _endpoint = endpoint; + _requestFactory = requestFactory; + _pollInterval = pollInterval; + _applyConfiguration = applyConfiguration; + _waitAsync = waitAsync ?? Task.Delay; + } + + /// + /// Creates the source, or returns null when it cannot be operated: a base URL that is + /// not a URL, or the managed endpoint without an API key. Polling anyway would only produce + /// failures every interval. + /// + public static AgentlessConfigurationSource? Create(FeatureFlagsSettings settings, Func applyConfiguration) + { + if (!AgentlessEndpoint.TryCreate(settings.Site, settings.Env, settings.AgentlessBaseUrl, out var endpoint, out var error)) + { + Log.Error("Feature Flags agentless source is unavailable: {Error}", error); + return null; + } + + if (endpoint.IsManaged && StringUtil.IsNullOrEmpty(settings.ApiKey)) + { + Log.Error("Feature Flags agentless source requires an API key. Set DD_API_KEY, or point DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_BASE_URL at an endpoint of your own."); + return null; + } + + return new AgentlessConfigurationSource( + endpoint.Uri, + CreateRequestFactory(endpoint, settings), + settings.PollInterval, + applyConfiguration); + } + + /// + /// Starts polling. Idempotent. + /// + public void Start() + { + if (Interlocked.CompareExchange(ref _started, 1, 0) != 0) + { + return; + } + + // Deliberately not wrapped in Task.Run: this is called from provider initialization, which + // is waiting for the first configuration, so the first request should go out on the calling + // thread rather than queue behind whatever else is on the thread pool. + _ = RunAsync().ContinueWith(t => Log.Error(t.Exception, "Feature Flags agentless poll loop failed"), TaskContinuationOptions.OnlyOnFaulted); + } + + /// + /// Runs a single poll, including its in-tick retries. + /// + internal async Task PollAsync() + { + var result = default(PollResult); + + for (var attempt = 1; attempt <= MaxAttempts; attempt++) + { + result = await RequestAsync().ConfigureAwait(false); + + if (_shutdown.IsCancellationRequested) + { + // A shutdown mid-poll leaves the response unusable for state transitions: keep + // last-known-good and the current ETag. + return; + } + + if (!IsRetryable(result)) + { + break; + } + + if (attempt == MaxAttempts) + { + // Every attempt failed in a retryable way. Last-known-good stays in place. + WarnFailure(result, MaxAttempts); + return; + } + + await WaitAsync(RetryDelay(attempt)).ConfigureAwait(false); + + if (_shutdown.IsCancellationRequested) + { + return; + } + } + + if (_shutdown.IsCancellationRequested) + { + // A shutdown during the final attempt leaves the response unusable for state + // transitions: keep last-known-good and the current ETag. + return; + } + + await ApplyAsync(result).ConfigureAwait(false); + } + + public void Dispose() + { + // The request in flight is bounded by the request timeout, and the loop is never joined, + // so a shutdown does not wait for it. A poll that completes after disposal is prevented + // from applying its result by the shutdown check in PollAsync. + try + { + _shutdown.Cancel(); + } + catch (Exception ex) + { + Log.Debug(ex, "Error cancelling the Feature Flags agentless poll loop"); + } + } + + // The concrete type is returned rather than the interface because CA1859 asks for it on a + // private member, which is also why the signature varies by target framework. +#if NETCOREAPP + private static HttpClientRequestFactory CreateRequestFactory(AgentlessEndpoint endpoint, FeatureFlagsSettings settings) +#else + private static ApiWebRequestFactory CreateRequestFactory(AgentlessEndpoint endpoint, FeatureFlagsSettings settings) +#endif + { + var headers = new List> + { + // The endpoint serves gzip, and neither transport decompresses for us. + new("Accept-Encoding", "gzip"), + new(TelemetryConstants.ClientLibraryLanguageHeader, TracerConstants.Language), + new(TelemetryConstants.ClientLibraryVersionHeader, TracerConstants.ThreePartVersion), + + // Without this the poll is itself instrumented, producing a span per poll and letting + // auto-instrumentation recurse through the poller's own client. + new(HttpHeaderNames.TracingEnabled, "false"), + }; + + if (endpoint.IsManaged) + { + // A custom endpoint is left to report its own authentication failure rather than + // having the Datadog credential sent to it. + headers.Add(new(TelemetryConstants.ApiKeyHeader, settings.ApiKey!)); + } + +#if NETCOREAPP + return new HttpClientRequestFactory(endpoint.Uri, headers.ToArray(), timeout: settings.RequestTimeout); +#else + return new ApiWebRequestFactory(endpoint.Uri, headers.ToArray(), timeout: settings.RequestTimeout); +#endif + } + + private static bool IsRetryable(in PollResult result) + => result.StatusCode is not { } status || status is 408 or 429 or (>= 500 and <= 599); + + private async Task RunAsync() + { + Log.Debug("AgentlessConfigurationSource::RunAsync -> Enter"); + + while (!_shutdown.IsCancellationRequested) + { + try + { + await PollAsync().ConfigureAwait(false); + } + catch (Exception ex) + { + Log.Debug(ex, "Feature Flags agentless poll failed unexpectedly"); + } + + // Fixed delay after completion, so polls never overlap. + await WaitAsync(_pollInterval).ConfigureAwait(false); + } + + Log.Debug("AgentlessConfigurationSource::RunAsync -> Exit"); + } + + private async Task WaitAsync(TimeSpan delay) + { + try + { + await _waitAsync(delay, _shutdown.Token).ConfigureAwait(false); + } + catch (OperationCanceledException) + { + // Shutting down + } + } + + private TimeSpan RetryDelay(int attempt) + { + var seconds = attempt == 1 + ? Clamp(_pollInterval.TotalSeconds / 6, FirstRetryMin, FirstRetryMax) + : Clamp(_pollInterval.TotalSeconds / 3, SecondRetryMin, SecondRetryMax); + + double jitter; + lock (_random) + { + jitter = 1 - RetryJitter + (_random.NextDouble() * RetryJitter * 2); + } + + return TimeSpan.FromSeconds(Math.Max(MinRetryDelay.TotalSeconds, seconds * jitter)); + + static double Clamp(double value, TimeSpan minimum, TimeSpan maximum) + => Math.Max(minimum.TotalSeconds, Math.Min(maximum.TotalSeconds, value)); + } + + private async Task RequestAsync() + { + try + { + var request = _requestFactory.Create(_endpoint); + if (_etag is { } etag) + { + request.AddHeader("If-None-Match", etag); + } + + using var response = await request.GetAsync().ConfigureAwait(false); + + // Only a 200 carries configuration; other bodies are never decoded as one. + var body = response.StatusCode == 200 ? await ReadBodyAsync(response).ConfigureAwait(false) : null; + return new PollResult(response.StatusCode, response.GetHeader("ETag"), body, error: null); + } + catch (Exception ex) + { + return new PollResult(statusCode: null, etag: null, body: null, error: ex); + } + } + + private async Task ReadBodyAsync(IApiResponse response) + { + var stream = await response.GetStreamAsync().ConfigureAwait(false); + GZipStream? decompressed = null; + + try + { + if (response.GetContentEncodingType() == ContentEncodingType.GZip) + { + decompressed = new GZipStream(stream, CompressionMode.Decompress); + } + + using var reader = new StreamReader(decompressed ?? stream, response.GetCharsetEncoding()); + return await reader.ReadToEndAsync().ConfigureAwait(false); + } + finally + { + decompressed?.Dispose(); + } + } + + private Task ApplyAsync(PollResult result) + { + switch (result.StatusCode) + { + case 304: + // Nothing changed, and the ETag stays as it is. + return Task.CompletedTask; + case 401 or 403: + WarnFailure(result, attempts: 1); + return Task.CompletedTask; + case not 200: + WarnFailure(result, attempts: 1); + return Task.CompletedTask; + } + + if (!UfcConfigurationParser.TryParse(result.Body, out var configuration, out var error)) + { + if (!_malformedPayloadLogged) + { + _malformedPayloadLogged = true; + Log.Error("Feature Flags agentless endpoint returned an unusable payload: {Error}", error); + } + + return Task.CompletedTask; + } + + if (!_applyConfiguration(configuration)) + { + if (!_applyFailureLogged) + { + _applyFailureLogged = true; + Log.Warning("Feature Flags agentless configuration could not be applied"); + } + + return Task.CompletedTask; + } + + // The ETag advances only once parsing and applying have both succeeded. Advancing on + // receipt would acknowledge a payload that was never applied, and every later poll would + // answer 304, pinning the process to stale configuration with no way back. + var newEtag = result.ETag?.Trim(); + _etag = StringUtil.IsNullOrEmpty(newEtag) ? null : newEtag; + + return Task.CompletedTask; + } + + /// + /// Warns once per failure category. A dead endpoint would otherwise produce a warning every + /// poll interval, indefinitely. + /// + private void WarnFailure(in PollResult result, int attempts) + { + var category = result.StatusCode switch + { + 401 or 403 => "authentication", + not null => "http", + _ => "request", + }; + + if (!_loggedFailureCategories.Add(category)) + { + return; + } + + switch (result.StatusCode) + { + case 401 or 403: + Log.Warning("Feature Flags agentless endpoint returned HTTP {StatusCode}; verify endpoint authentication", result.StatusCode!.Value); + break; + case not null: + Log.Warning("Feature Flags agentless endpoint returned HTTP {StatusCode} after {Attempts} attempts", result.StatusCode.Value, attempts); + break; + default: + Log.Warning(result.Error, "Feature Flags agentless request failed after {Attempts} attempts", attempts); + break; + } + } + + internal readonly struct PollResult(int? statusCode, string? etag, string? body, Exception? error) + { + public int? StatusCode { get; } = statusCode; + + public string? ETag { get; } = etag; + + public string? Body { get; } = body; + + public Exception? Error { get; } = error; + } +} diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/UfcConfigurationParserTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/UfcConfigurationParserTests.cs new file mode 100644 index 000000000000..14fc51ab85a7 --- /dev/null +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/UfcConfigurationParserTests.cs @@ -0,0 +1,108 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +#nullable enable + +using System.Collections.Generic; +using Datadog.Trace.FeatureFlags.Agentless; +using Datadog.Trace.FeatureFlags.Rcm.Model; +using FluentAssertions; +using Xunit; + +namespace Datadog.Trace.Tests.FeatureFlags; + +public class UfcConfigurationParserTests +{ + private const string ValidEnvelope = """ + { "data": { "type": "universal-flag-configuration", + "attributes": { "format": "SERVER", "createdAt": "2025-01-01T00:00:00Z", + "environment": { "name": "production" }, "flags": {} } } } + """; + + private const string Attributes = """ + { "format": "SERVER", "createdAt": "2025-01-01T00:00:00Z", + "environment": { "name": "production" }, "flags": {} } + """; + + [Fact] + public void ParsesValidEnvelope() + { + UfcConfigurationParser.TryParse(ValidEnvelope, out var configuration, out var error) + .Should().BeTrue(); + + error.Should().BeNull(); + configuration.Should().NotBeNull(); + configuration!.Environment!.Name.Should().Be("production"); + configuration.Flags.Should().BeEmpty(); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData("not json")] + [InlineData("{ \"data\": ")] + public void RejectsMalformedJson(string? body) + { + UfcConfigurationParser.TryParse(body, out var configuration, out var error).Should().BeFalse(); + + configuration.Should().BeNull(); + error.Should().Be("Malformed UFC payload"); + } + + [Theory] + // A raw UFC document is rejected too, so every source agrees on one wire format. + [InlineData(Attributes)] + // Wrong resource type + [InlineData("""{ "data": { "type": "wrong-type", "attributes": { "format": "SERVER", "createdAt": "x", "environment": { "name": "prod" }, "flags": {} } } }""")] + // Missing data + [InlineData("""{ "meta": {} }""")] + // data is not an object + [InlineData("""{ "data": "string" }""")] + public void RejectsInvalidEnvelope(string body) + { + UfcConfigurationParser.TryParse(body, out var configuration, out var error).Should().BeFalse(); + + configuration.Should().BeNull(); + error.Should().Be("Expected a JSON:API Universal Flag Configuration resource"); + } + + [Theory] + // Missing format + [InlineData("""{ "data": { "type": "universal-flag-configuration", "attributes": { "createdAt": "x", "environment": { "name": "prod" }, "flags": {} } } }""")] + // Missing createdAt + [InlineData("""{ "data": { "type": "universal-flag-configuration", "attributes": { "format": "SERVER", "environment": { "name": "prod" }, "flags": {} } } }""")] + // Missing environment + [InlineData("""{ "data": { "type": "universal-flag-configuration", "attributes": { "format": "SERVER", "createdAt": "x", "flags": {} } } }""")] + // environment.name is not a string + [InlineData("""{ "data": { "type": "universal-flag-configuration", "attributes": { "format": "SERVER", "createdAt": "x", "environment": { "name": 123 }, "flags": {} } } }""")] + // Missing flags + [InlineData("""{ "data": { "type": "universal-flag-configuration", "attributes": { "format": "SERVER", "createdAt": "x", "environment": { "name": "prod" } } } }""")] + // flags is not an object + [InlineData("""{ "data": { "type": "universal-flag-configuration", "attributes": { "format": "SERVER", "createdAt": "x", "environment": { "name": "prod" }, "flags": [] } } }""")] + public void RejectsInvalidAttributes(string body) + { + UfcConfigurationParser.TryParse(body, out var configuration, out var error).Should().BeFalse(); + + configuration.Should().BeNull(); + error.Should().Be("Expected a Universal Flag Configuration v1 object"); + } + + [Fact] + public void ParsesFlagsFromEnvelope() + { + var body = """ + { "data": { "type": "universal-flag-configuration", + "attributes": { "format": "SERVER", "createdAt": "2025-01-01T00:00:00Z", + "environment": { "name": "production" }, + "flags": { "test-flag": { "key": "test-flag", "enabled": true, "variationType": "BOOLEAN" } } } } } + """; + + UfcConfigurationParser.TryParse(body, out var configuration, out _).Should().BeTrue(); + + configuration!.Flags.Should().NotBeNull(); + configuration!.Flags!.Should().ContainKey("test-flag"); + configuration!.Flags!["test-flag"].Enabled.Should().BeTrue(); + } +} From 388ccfab524997d03fba21e44638764894688f5e Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 13 Aug 2026 15:47:50 +0300 Subject: [PATCH 17/86] test(feature-flags): add AgentlessConfigurationSourceTests for poller retry, ETag, gzip, and shutdown --- .../AgentlessConfigurationSourceTests.cs | 284 ++++++++++++++++++ 1 file changed, 284 insertions(+) create mode 100644 tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs new file mode 100644 index 000000000000..935c778b96f4 --- /dev/null +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs @@ -0,0 +1,284 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +#nullable enable + +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Datadog.Trace.Agent; +using Datadog.Trace.FeatureFlags.Agentless; +using Datadog.Trace.FeatureFlags.Rcm.Model; +using Datadog.Trace.TestHelpers.TransportHelpers; +using FluentAssertions; +using Xunit; + +namespace Datadog.Trace.Tests.FeatureFlags; + +public class AgentlessConfigurationSourceTests +{ + private const string Body = """ + { "data": { "type": "universal-flag-configuration", + "attributes": { "format": "SERVER", "createdAt": "2025-01-01T00:00:00Z", + "environment": { "name": "production" }, "flags": {} } } } + """; + + private static readonly Uri Endpoint = new("https://ufc-server.ff-cdn.datadoghq.com/api/v2/feature-flagging/config/rules-based/server"); + + [Fact] + public async Task AppliesConfigurationFromA200() + { + var applied = new List(); + var factory = new TestRequestFactory(uri => new TestApiRequest(uri, responseContent: Body)); + using var source = CreateSource(factory, applied); + + await source.PollAsync(); + + applied.Should().ContainSingle(); + applied[0].Environment!.Name.Should().Be("production"); + factory.RequestsSent.Should().ContainSingle(); + } + + [Fact] + public async Task SendsTheEtagOfTheLastAppliedConfiguration() + { + var applied = new List(); + var factory = new TestRequestFactory( + uri => new TestApiRequest(uri, responseContent: Body, responseHeaders: new() { { "ETag", "\"ufc-v1\"" } })); + using var source = CreateSource(factory, applied); + + await source.PollAsync(); + applied.Should().ContainSingle(); + + // Second poll should send If-None-Match + await source.PollAsync(); + factory.RequestsSent.Should().HaveCount(2); + factory.RequestsSent[1].ExtraHeaders.Should().ContainKey("If-None-Match"); + factory.RequestsSent[1].ExtraHeaders["If-None-Match"].Should().Be("\"ufc-v1\""); + } + + [Fact] + public async Task DoesNotApplyOn304() + { + var applied = new List(); + var factory = new TestRequestFactory( + uri => new TestApiRequest(uri, statusCode: 304, responseContent: "{}")); + using var source = CreateSource(factory, applied); + + await source.PollAsync(); + + applied.Should().BeEmpty(); + } + + [Fact] + public async Task DoesNotApplyOn401() + { + var applied = new List(); + var factory = new TestRequestFactory( + uri => new TestApiRequest(uri, statusCode: 401, responseContent: "Unauthorized")); + using var source = CreateSource(factory, applied); + + await source.PollAsync(); + + applied.Should().BeEmpty(); + } + + [Fact] + public async Task DoesNotApplyOnMalformedPayload() + { + var applied = new List(); + var factory = new TestRequestFactory( + uri => new TestApiRequest(uri, statusCode: 200, responseContent: "not json")); + using var source = CreateSource(factory, applied); + + await source.PollAsync(); + + applied.Should().BeEmpty(); + } + + [Fact] + public async Task DoesNotApplyAfterDisposal() + { + var applied = new List(); + var factory = new TestRequestFactory(uri => new TestApiRequest(uri, responseContent: Body)); + var source = CreateSource(factory, applied); + + // A shutdown mid-poll leaves the response unusable for a state transition. + source.Dispose(); + await source.PollAsync(); + + factory.RequestsSent.Should().ContainSingle(); + applied.Should().BeEmpty(); + } + + [Fact] + public async Task DoesNotApplyWhenDisposedAfterRequestSucceeds() + { + var applied = new List(); + AgentlessConfigurationSource? sourceRef = null; + var factory = new TestRequestFactory(uri => + { + var request = new DisposingApiRequest(uri, Body); + request.Source = sourceRef; + return request; + }); + using var source = CreateSource(factory, applied); + sourceRef = source; + + await source.PollAsync(); + + applied.Should().BeEmpty(); + } + + [Fact] + public async Task RetriesOn500ThenAppliesOnSuccess() + { + var applied = new List(); + var factory = new TestRequestFactory( + uri => new TestApiRequest(uri, statusCode: 500, responseContent: "error"), + uri => new TestApiRequest(uri, responseContent: Body)); + using var source = CreateSource(factory, applied); + + await source.PollAsync(); + + applied.Should().ContainSingle(); + factory.RequestsSent.Should().HaveCount(2); + } + + [Fact] + public async Task RetriesUpToMaxAttemptsOn500() + { + var applied = new List(); + var factory = new TestRequestFactory( + uri => new TestApiRequest(uri, statusCode: 500, responseContent: "error"), + uri => new TestApiRequest(uri, statusCode: 500, responseContent: "error"), + uri => new TestApiRequest(uri, statusCode: 500, responseContent: "error")); + using var source = CreateSource(factory, applied); + + await source.PollAsync(); + + applied.Should().BeEmpty(); + factory.RequestsSent.Should().HaveCount(3); + } + + [Fact] + public async Task DoesNotRetryOn400() + { + var applied = new List(); + var factory = new TestRequestFactory( + uri => new TestApiRequest(uri, statusCode: 400, responseContent: "bad request")); + using var source = CreateSource(factory, applied); + + await source.PollAsync(); + + applied.Should().BeEmpty(); + factory.RequestsSent.Should().ContainSingle(); + } + + [Fact] + public async Task HandlesGzipResponse() + { + var applied = new List(); + var factory = new TestRequestFactory(uri => new GzipApiRequest(uri, Body)); + using var source = CreateSource(factory, applied); + + await source.PollAsync(); + + applied.Should().ContainSingle(); + applied[0].Environment!.Name.Should().Be("production"); + } + + [Fact] + public async Task HandlesNetworkError() + { + var applied = new List(); + var factory = new TestRequestFactory( + uri => new ThrowingApiRequest(uri), + uri => new ThrowingApiRequest(uri), + uri => new ThrowingApiRequest(uri)); + using var source = CreateSource(factory, applied); + + await source.PollAsync(); + + applied.Should().BeEmpty(); + factory.RequestsSent.Should().HaveCount(3); + } + + private static AgentlessConfigurationSource CreateSource(TestRequestFactory factory, List applied) + => new( + Endpoint, + factory, + TimeSpan.FromSeconds(30), + configuration => + { + applied.Add(configuration); + return true; + }, + NoWait); + + private static Task NoWait(TimeSpan delay, CancellationToken cancellationToken) => Task.CompletedTask; + + private class ThrowingApiRequest(Uri endpoint) : TestApiRequest(endpoint) + { + public override Task GetAsync() => throw new IOException("The connection was refused"); + } + + private class GzipApiRequest(Uri endpoint, string body) : TestApiRequest(endpoint) + { + public override Task GetAsync() => Task.FromResult(new GzipApiResponse(body)); + } + + private class GzipApiResponse(string body) : IApiResponse + { + public int StatusCode => 200; + + public long ContentLength => -1; + + public string? ContentTypeHeader => "application/json"; + + public string? ContentEncodingHeader => "gzip"; + + public void Dispose() + { + } + + public string? GetHeader(string headerName) => null; + + public Encoding GetCharsetEncoding() => Encoding.UTF8; + + public ContentEncodingType GetContentEncodingType() => ContentEncodingType.GZip; + + public Task GetStreamAsync() + { + var compressed = new MemoryStream(); + using (var gzip = new GZipStream(compressed, CompressionMode.Compress, leaveOpen: true)) + { + var bytes = Encoding.UTF8.GetBytes(body); + gzip.Write(bytes, 0, bytes.Length); + } + + compressed.Position = 0; + return Task.FromResult(compressed); + } + } + + private class DisposingApiRequest(Uri endpoint, string body) : TestApiRequest(endpoint, responseContent: body) + { + public AgentlessConfigurationSource? Source { get; set; } + + public override Task GetAsync() + { + var response = base.GetAsync(); + // Simulate a shutdown arriving after the request completes but before ApplyAsync. + Source?.Dispose(); + return response; + } + } +} From 376b0ad357c49b63c002da739059ea6aa1c21df8 Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 14 Aug 2026 15:01:41 +0300 Subject: [PATCH 18/86] fix(feature-flags): reject non-string data.type, log failures as errors --- .../Agentless/AgentlessConfigurationSource.cs | 8 ++++---- .../FeatureFlags/Agentless/UfcConfigurationParser.cs | 1 + .../FeatureFlags/UfcConfigurationParserTests.cs | 4 ++++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs index 6d23a7045c31..7ec342a4fc6d 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs @@ -225,7 +225,7 @@ private async Task RunAsync() } catch (Exception ex) { - Log.Debug(ex, "Feature Flags agentless poll failed unexpectedly"); + Log.Error(ex, "Feature Flags agentless poll failed unexpectedly"); } // Fixed delay after completion, so polls never overlap. @@ -375,13 +375,13 @@ private void WarnFailure(in PollResult result, int attempts) switch (result.StatusCode) { case 401 or 403: - Log.Warning("Feature Flags agentless endpoint returned HTTP {StatusCode}; verify endpoint authentication", result.StatusCode!.Value); + Log.Error("Feature Flags agentless endpoint returned HTTP {StatusCode}; verify endpoint authentication", result.StatusCode!.Value); break; case not null: - Log.Warning("Feature Flags agentless endpoint returned HTTP {StatusCode} after {Attempts} attempts", result.StatusCode.Value, attempts); + Log.Error("Feature Flags agentless endpoint returned HTTP {StatusCode} after {Attempts} attempts", result.StatusCode.Value, attempts); break; default: - Log.Warning(result.Error, "Feature Flags agentless request failed after {Attempts} attempts", attempts); + Log.Error(result.Error, "Feature Flags agentless request failed after {Attempts} attempts", attempts); break; } } diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs index 58bbfe2691e9..a078f5f4374d 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs @@ -53,6 +53,7 @@ public static bool TryParse(string? body, [NotNullWhen(true)] out ServerConfigur if (payload is not JObject || payload["data"] is not JObject data + || data["type"]?.Type != JTokenType.String || data["type"]?.Value() != ResourceType) { error = "Expected a JSON:API Universal Flag Configuration resource"; diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/UfcConfigurationParserTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/UfcConfigurationParserTests.cs index 14fc51ab85a7..b57c9568ebcd 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/UfcConfigurationParserTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/UfcConfigurationParserTests.cs @@ -60,6 +60,10 @@ public void RejectsMalformedJson(string? body) [InlineData("""{ "meta": {} }""")] // data is not an object [InlineData("""{ "data": "string" }""")] + // data.type is not a string (object) + [InlineData("""{ "data": { "type": { "nested": true }, "attributes": { "format": "SERVER", "createdAt": "x", "environment": { "name": "prod" }, "flags": {} } } }""")] + // data.type is not a string (array) + [InlineData("""{ "data": { "type": [1, 2], "attributes": { "format": "SERVER", "createdAt": "x", "environment": { "name": "prod" }, "flags": {} } } }""")] public void RejectsInvalidEnvelope(string body) { UfcConfigurationParser.TryParse(body, out var configuration, out var error).Should().BeFalse(); From 2f2682f4a9ef82311bc51048f061335d206d1a79 Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 14 Aug 2026 15:15:13 +0300 Subject: [PATCH 19/86] fix(feature-flags): add explicit request timeout race for net461 async WebRequest --- .../Agentless/AgentlessConfigurationSource.cs | 25 +++++++++++++++++++ .../AgentlessConfigurationSourceTests.cs | 1 + 2 files changed, 26 insertions(+) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs index 7ec342a4fc6d..4f2658fda111 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs @@ -44,6 +44,7 @@ internal sealed class AgentlessConfigurationSource : IDisposable private readonly IApiRequestFactory _requestFactory; private readonly Uri _endpoint; private readonly TimeSpan _pollInterval; + private readonly TimeSpan _requestTimeout; private readonly Func _applyConfiguration; private readonly Func _waitAsync; private readonly CancellationTokenSource _shutdown = new(); @@ -61,12 +62,14 @@ internal AgentlessConfigurationSource( Uri endpoint, IApiRequestFactory requestFactory, TimeSpan pollInterval, + TimeSpan requestTimeout, Func applyConfiguration, Func? waitAsync = null) { _endpoint = endpoint; _requestFactory = requestFactory; _pollInterval = pollInterval; + _requestTimeout = requestTimeout; _applyConfiguration = applyConfiguration; _waitAsync = waitAsync ?? Task.Delay; } @@ -94,6 +97,7 @@ internal AgentlessConfigurationSource( endpoint.Uri, CreateRequestFactory(endpoint, settings), settings.PollInterval, + settings.RequestTimeout, applyConfiguration); } @@ -275,7 +279,28 @@ private async Task RequestAsync() request.AddHeader("If-None-Match", etag); } +#if NETCOREAPP + // HttpClient.Timeout applies to async calls, so no explicit race is needed. using var response = await request.GetAsync().ConfigureAwait(false); +#else + // HttpWebRequest.Timeout does not apply to async calls (GetResponseAsync), so we race + // the request against an explicit delay to bound the wait on net461/netstandard2.0. + var getTask = request.GetAsync(); + var timeoutTask = Task.Delay(_requestTimeout); + + if (await Task.WhenAny(getTask, timeoutTask).ConfigureAwait(false) == timeoutTask) + { + // The request is still in flight. Dispose the response when it eventually completes + // (success or fault) so the underlying connection is released. + _ = getTask.ContinueWith( + t => { try { using var r = t.Result; } catch { } }, + TaskContinuationOptions.None); + + return new PollResult(statusCode: null, etag: null, body: null, error: new TimeoutException($"Feature Flags agentless request timed out after {_requestTimeout.TotalSeconds}s")); + } + + using var response = await getTask.ConfigureAwait(false); +#endif // Only a 200 carries configuration; other bodies are never decoded as one. var body = response.StatusCode == 200 ? await ReadBodyAsync(response).ConfigureAwait(false) : null; diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs index 935c778b96f4..e2e39a15acde 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs @@ -216,6 +216,7 @@ private static AgentlessConfigurationSource CreateSource(TestRequestFactory fact Endpoint, factory, TimeSpan.FromSeconds(30), + TimeSpan.FromSeconds(5), configuration => { applied.Add(configuration); From 7a297353ffff91a3787e73e40f52e06629b8336c Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 13 Aug 2026 16:01:53 +0300 Subject: [PATCH 20/86] feat(feature-flags): wire source-agnostic activation and InitializeAsync into FeatureFlagsModule --- .../Configuration/TracerSettings.cs | 15 +- .../FeatureFlags/FeatureFlagsModule.cs | 177 ++++++++++++++++-- 2 files changed, 168 insertions(+), 24 deletions(-) diff --git a/tracer/src/Datadog.Trace/Configuration/TracerSettings.cs b/tracer/src/Datadog.Trace/Configuration/TracerSettings.cs index 1ce04feb0861..cf7bbe9b14d3 100644 --- a/tracer/src/Datadog.Trace/Configuration/TracerSettings.cs +++ b/tracer/src/Datadog.Trace/Configuration/TracerSettings.cs @@ -763,8 +763,13 @@ not null when string.Equals(value, "otlp", StringComparison.OrdinalIgnoreCase) = DisabledAdoNetCommandTypes.UnionWith(userSplit); } - IsFlaggingProviderEnabled = config.WithKeys(ConfigurationKeys.FeatureFlags.FlaggingProviderEnabled) - .AsBool(false); +#pragma warning disable 618 // superseded, but still honoured so existing adopters keep their source + var flaggingProviderEnabled = config.WithKeys(ConfigurationKeys.FeatureFlags.FlaggingProviderEnabled).AsBool(); +#pragma warning restore 618 + var featureFlagsEnabled = config.WithKeys(ConfigurationKeys.FeatureFlags.FeatureFlagsEnabled).AsBool(); + var configuredSource = config.WithKeys(ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSource).AsString(); + + FeatureFlags = new FeatureFlagsSettings(source, telemetry); IsSpanEnrichmentEnabled = config.WithKeys(ConfigurationKeys.FeatureFlags.SpanEnrichmentEnabled) .AsBool(false); @@ -1497,12 +1502,12 @@ not null when string.Equals(value, "otlp", StringComparison.OrdinalIgnoreCase) = internal HashSet DisabledAdoNetCommandTypes { get; } /// - /// Gets a value indicating whether remote Feature Flags Provider is enabled + /// Gets the Feature Flags configuration, including which delivery source is selected. /// - internal bool IsFlaggingProviderEnabled { get; } + internal FeatureFlagsSettings FeatureFlags { get; } /// - /// Gets a value indicating whether APM span enrichment is enabled; see . + /// Gets a value indicating whether APM span enrichment is enabled; see . /// internal bool IsSpanEnrichmentEnabled { get; } diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs index cc8833f9ff77..10862a3a84a8 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs @@ -8,7 +8,9 @@ using System; using System.Collections.Generic; using System.Threading; +using System.Threading.Tasks; using Datadog.Trace.Configuration; +using Datadog.Trace.FeatureFlags.Agentless; using Datadog.Trace.FeatureFlags.Exposure; using Datadog.Trace.FeatureFlags.Exposure.Model; using Datadog.Trace.FeatureFlags.Rcm; @@ -22,42 +24,165 @@ internal sealed class FeatureFlagsModule : IDisposable { internal static readonly IDatadogLogger Log = DatadogLogging.GetLoggerFor(typeof(FeatureFlagsModule)); - private readonly IRcmSubscriptionManager _rcmSubscriptionManager; - private readonly ISubscription _rcmSubscription; - private readonly FfeProduct _ffeProduct; + private readonly FeatureFlagsSettings _settings; private readonly ExposureApi _exposureApi; private readonly bool _spanEnrichmentEnabled; + private readonly IRcmSubscriptionManager? _rcmSubscriptionManager; + private readonly ISubscription? _rcmSubscription; + private readonly TaskCompletionSource _firstConfigReceived = new(TaskCreationOptions.RunContinuationsAsynchronously); private Action? _onNewConfigEventHander; private FeatureFlagsEvaluator? _evaluator; + private AgentlessConfigurationSource? _agentlessSource; + private int _activated; + private int _disposed; + private bool _deliveryStarted; internal FeatureFlagsModule(TracerSettings settings, IRcmSubscriptionManager rcmSubscriptionManager) { - Log.Debug("FeatureFlagsModule ENABLED"); + _settings = settings.FeatureFlags; _spanEnrichmentEnabled = settings.IsSpanEnrichmentEnabled; - _rcmSubscriptionManager = rcmSubscriptionManager; _exposureApi = new ExposureApi(settings); - _ffeProduct = new FfeProduct(UpdateRemoteConfig); - _rcmSubscription = new Subscription(_ffeProduct.UpdateFromRcm, RcmProducts.FfeFlags); - _rcmSubscriptionManager.SubscribeToChanges(_rcmSubscription!); - _rcmSubscriptionManager.SetCapability(RcmCapabilitiesIndices.FfeFlagConfigurationRules, true); + + Log.Debug("FeatureFlagsModule ENABLED with source {Source}", _settings.Source); + + if (_settings.Source == FeatureFlagsSource.RemoteConfig) + { + if (!settings.IsRemoteConfigurationAvailable) + { + // Selecting Remote Configuration explicitly and then falling back to the agentless + // endpoint would start billed requests the customer did not ask for, so the source + // stays selected and simply never delivers. + Log.Warning( + "Feature Flags are configured to use the Remote Configuration source, but Remote Configuration is not available. No flag configuration will be received."); + } + + // Subscribing advertises the FFE capability and starts a billed Remote Configuration + // subscription, so it only happens when Remote Configuration is the selected source. + // The subscription keeps the product alive, so it needs no field of its own. + var ffeProduct = new FfeProduct(configs => ApplyConfigurations(configs)); + _rcmSubscriptionManager = rcmSubscriptionManager; + _rcmSubscription = new Subscription(ffeProduct.UpdateFromRcm, RcmProducts.FfeFlags); + _rcmSubscriptionManager.SubscribeToChanges(_rcmSubscription!); + _rcmSubscriptionManager.SetCapability(RcmCapabilitiesIndices.FfeFlagConfigurationRules, true); + } } + /// + /// Gets a task that completes once configuration has been applied for the first time. + /// + internal Task FirstConfigReceived => _firstConfigReceived.Task; + + internal FeatureFlagsSettings Settings => _settings; + public static FeatureFlagsModule? Create(TracerSettings settings, IRcmSubscriptionManager rcmSubscriptionManager) { - if (settings.IsFlaggingProviderEnabled) + if (!settings.FeatureFlags.Enabled) { - return new FeatureFlagsModule(settings, rcmSubscriptionManager); + return null; } - return null; + return new FeatureFlagsModule(settings, rcmSubscriptionManager); } public void Dispose() { + if (Interlocked.CompareExchange(ref _disposed, 1, 0) != 0) + { + return; + } + + if (_rcmSubscriptionManager is not null && _rcmSubscription is not null) + { + _rcmSubscriptionManager.Unsubscribe(_rcmSubscription); + } + + Interlocked.Exchange(ref _agentlessSource, null)?.Dispose(); _exposureApi.Dispose(); } + /// + /// Signals that application code initialized the provider. Configuration is only requested + /// from this point on, because those requests are billable. Idempotent. + /// + internal void Activate() + { + if (Interlocked.CompareExchange(ref _activated, 1, 0) != 0) + { + return; + } + + switch (_settings.Source) + { + case FeatureFlagsSource.RemoteConfig: + // Remote Configuration delivery is driven by the Agent, so the subscription set up + // in the constructor is all that is needed; activation only marks intent. + _deliveryStarted = true; + Log.Debug("FeatureFlagsModule::Activate -> Remote Configuration source is already subscribed"); + break; + case FeatureFlagsSource.Agentless: + // Polling is billable, so it starts here rather than at construction. + var source = AgentlessConfigurationSource.Create(_settings, ApplyConfiguration); + if (source is null) + { + break; + } + + Interlocked.Exchange(ref _agentlessSource, source); + if (Volatile.Read(ref _disposed) == 1) + { + // Disposed while we were creating it. + Interlocked.Exchange(ref _agentlessSource, null)?.Dispose(); + break; + } + + source.Start(); + _deliveryStarted = true; + break; + } + } + + /// + /// Activates delivery and waits for the first configuration, so that a provider reported as + /// ready can resolve flags. Never throws on timeout: delivery being slow is transient, while + /// initialization typically runs at application startup where an exception is fatal. + /// + internal async Task InitializeAsync(CancellationToken cancellationToken) + { + Activate(); + + if (_firstConfigReceived.Task.IsCompleted) + { + return; + } + + // When activation could not start any delivery source (for example, agentless without + // an API key), waiting would only delay startup for a configuration that will never + // arrive. The provider stays not-ready, which is the correct state. + if (!_deliveryStarted) + { + return; + } + + using var timeoutCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); + var timeout = Task.Delay(_settings.InitializationTimeout, timeoutCancellation.Token); + var completed = await Task.WhenAny(_firstConfigReceived.Task, timeout).ConfigureAwait(false); + + // Stop the timer, otherwise it holds a callback for the whole initialization timeout. + timeoutCancellation.Cancel(); + + if (completed != timeout) + { + return; + } + + // Evaluations keep returning the caller's default with PROVIDER_NOT_READY until + // configuration lands, which promotes the provider then. + Log.Warning( + "Feature Flags configuration did not arrive within {TimeoutMs}ms. Evaluations use their default values until it does.", + _settings.InitializationTimeout.TotalMilliseconds); + } + internal void RegisterOnNewConfigEventHandler(Action? onNewConfig) { _onNewConfigEventHander = onNewConfig; @@ -76,28 +201,42 @@ internal Evaluation Evaluate(string flagKey, ValueType resultType, object? defau return evaluator.Evaluate(flagKey, resultType, defaultValue, new EvaluationContext(targetingKey, attributes)); } - private void UpdateRemoteConfig(List> list) + internal bool ApplyConfiguration(ServerConfiguration configuration) { - Log.Debug("FeatureFlagsModule::UpdateRemoteConfig -> New config received. {Count}", list.Count); try { - // Feed configs to the rules evaluator + Interlocked.Exchange(ref _evaluator, new FeatureFlagsEvaluator(ReportExposure, configuration, _spanEnrichmentEnabled)); + _firstConfigReceived.TrySetResult(true); + _onNewConfigEventHander?.Invoke(); + return true; + } + catch (Exception ex) + { + Log.Warning(ex, "FeatureFlagsModule::ApplyConfiguration -> Error applying configuration"); + return false; + } + } + + private void ApplyConfigurations(List> list) + { + Log.Debug("FeatureFlagsModule::ApplyConfigurations -> New config received. {Count}", list.Count); + try + { if (list.Count > 0) { var selectedConfig = MergeConfigs(list); - Interlocked.Exchange(ref _evaluator, new FeatureFlagsEvaluator(ReportExposure, selectedConfig, _spanEnrichmentEnabled)); + ApplyConfiguration(selectedConfig); } else { // RC reset: clear evaluator so Evaluate() returns PROVIDER_NOT_READY Interlocked.Exchange(ref _evaluator, null); + _onNewConfigEventHander?.Invoke(); } - - _onNewConfigEventHander?.Invoke(); } catch (Exception ex) { - Log.Warning(ex, "FeatureFlagsModule::UpdateRemoteConfig -> Error processing new config"); + Log.Warning(ex, "FeatureFlagsModule::ApplyConfigurations -> Error processing new config"); } static ServerConfiguration MergeConfigs(List> list) From aeea2cb9aa4d3e898c0869c98647b9688c363052 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 13 Aug 2026 16:09:35 +0300 Subject: [PATCH 21/86] feat(feature-flags): add OpenFeature InitializeAsync CallTarget instrumentation --- .../DatadogProvider.cs | 12 ++++++++++++ .../Sdk/FeatureFlagsSdk.cs | 10 ++++++++++ 2 files changed, 22 insertions(+) diff --git a/tracer/src/Datadog.FeatureFlags.OpenFeature/DatadogProvider.cs b/tracer/src/Datadog.FeatureFlags.OpenFeature/DatadogProvider.cs index f83c9ccd4434..cec9ace37388 100644 --- a/tracer/src/Datadog.FeatureFlags.OpenFeature/DatadogProvider.cs +++ b/tracer/src/Datadog.FeatureFlags.OpenFeature/DatadogProvider.cs @@ -73,6 +73,18 @@ private void SignalGeneralUpdate() catch { } } + /// + /// Starts flag configuration delivery and waits for the first configuration, so that a ready + /// provider can actually resolve flags. It returns normally when the wait times out instead of + /// throwing: slow delivery is transient, and initialization commonly runs at startup, where an + /// exception would take the application down. + /// + /// Evaluation context + /// Async cancellation token + /// A task that completes when initialization is complete + public override Task InitializeAsync(EvaluationContext context, CancellationToken cancellationToken = default) + => FeatureFlagsSdk.InitializeAsync(cancellationToken); + /// Gets provider metadata /// Returns provider metadata public override Metadata? GetMetadata() => _metadata; diff --git a/tracer/src/Datadog.FeatureFlags.OpenFeature/Sdk/FeatureFlagsSdk.cs b/tracer/src/Datadog.FeatureFlags.OpenFeature/Sdk/FeatureFlagsSdk.cs index 980a2aedf178..cd77621ae839 100644 --- a/tracer/src/Datadog.FeatureFlags.OpenFeature/Sdk/FeatureFlagsSdk.cs +++ b/tracer/src/Datadog.FeatureFlags.OpenFeature/Sdk/FeatureFlagsSdk.cs @@ -32,6 +32,16 @@ internal static class FeatureFlagsSdk [MethodImpl(MethodImplOptions.NoInlining)] internal static bool IsSpanEnrichmentEnabled() => false; + /// + /// Activates flag configuration delivery and waits for the first configuration to arrive. + /// Delivery only starts here, because requesting configuration is billable and installing the + /// tracer alone must not do it. + /// + /// Cancellation token supplied by OpenFeature + /// A task that completes once configuration has arrived, or the initialization timeout has elapsed + [MethodImpl(MethodImplOptions.NoInlining)] + public static Task InitializeAsync(CancellationToken cancellationToken) => Task.CompletedTask; + /// Installs an event handler to be fired when a new config has been received /// Action to be called when the event is fired [MethodImpl(MethodImplOptions.NoInlining)] From 5647ccb11d996e49edade57e23570e52d18801db Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 13 Aug 2026 16:26:02 +0300 Subject: [PATCH 22/86] test(feature-flags): add FeatureFlagsModuleTests for activation, InitializeAsync, and source selection --- tracer/build/supported_calltargets.g.json | 24 +++ ...penFeatureSdkInitializeAsyncIntegration.cs | 52 +++++++ .../InstrumentationDefinitions.g.cs | 1 + .../InstrumentationDefinitions.g.cs | 1 + .../InstrumentationDefinitions.g.cs | 1 + .../InstrumentationDefinitions.g.cs | 1 + .../SpanEnrichmentIntegrationTests.cs | 2 + .../FeatureFlags/FeatureFlagsModuleTests.cs | 141 +++++++++++++++++- 8 files changed, 221 insertions(+), 2 deletions(-) create mode 100644 tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/ManualInstrumentation/OpenFeature/OpenFeatureSdkInitializeAsyncIntegration.cs diff --git a/tracer/build/supported_calltargets.g.json b/tracer/build/supported_calltargets.g.json index 694129eae9f1..e610b91f6fb3 100644 --- a/tracer/build/supported_calltargets.g.json +++ b/tracer/build/supported_calltargets.g.json @@ -14054,6 +14054,30 @@ "IsAdoNetIntegration": false, "InstrumentationCategory": 1 }, + { + "IntegrationName": "OpenFeature", + "AssemblyName": "Datadog.FeatureFlags.OpenFeature", + "TargetTypeName": "Datadog.FeatureFlags.OpenFeature.FeatureFlagsSdk", + "TargetMethodName": "InitializeAsync", + "TargetReturnType": "System.Threading.Tasks.Task", + "TargetParameterTypes": [ + "System.Threading.CancellationToken" + ], + "MinimumVersion": { + "Item1": 2, + "Item2": 0, + "Item3": 0 + }, + "MaximumVersion": { + "Item1": 2, + "Item2": 65535, + "Item3": 65535 + }, + "InstrumentationTypeName": "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkInitializeAsyncIntegration", + "IntegrationKind": 0, + "IsAdoNetIntegration": false, + "InstrumentationCategory": 1 + }, { "IntegrationName": "OpenFeature", "AssemblyName": "Datadog.FeatureFlags.OpenFeature", diff --git a/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/ManualInstrumentation/OpenFeature/OpenFeatureSdkInitializeAsyncIntegration.cs b/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/ManualInstrumentation/OpenFeature/OpenFeatureSdkInitializeAsyncIntegration.cs new file mode 100644 index 000000000000..ae703643300c --- /dev/null +++ b/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/ManualInstrumentation/OpenFeature/OpenFeatureSdkInitializeAsyncIntegration.cs @@ -0,0 +1,52 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// +#nullable enable + +using System; +using System.ComponentModel; +using System.Threading; +using System.Threading.Tasks; +using Datadog.Trace.ClrProfiler.CallTarget; +using Datadog.Trace.Configuration; + +namespace Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature; + +/// +/// System.Threading.Tasks.Task Datadog.FeatureFlags.OpenFeature.FeatureFlagsSdk::InitializeAsync(System.Threading.CancellationToken) calltarget instrumentation +/// +[InstrumentMethod( + AssemblyName = "Datadog.FeatureFlags.OpenFeature", + TypeName = "Datadog.FeatureFlags.OpenFeature.FeatureFlagsSdk", + MethodName = "InitializeAsync", + ReturnTypeName = ClrNames.Task, + ParameterTypeNames = [ClrNames.CancellationToken], + MinimumVersion = "2.0.0", + MaximumVersion = "2.*.*", + IntegrationName = nameof(IntegrationId.OpenFeature))] +[Browsable(false)] +[EditorBrowsable(EditorBrowsableState.Never)] +public sealed class OpenFeatureSdkInitializeAsyncIntegration +{ + internal static CallTargetState OnMethodBegin(ref CancellationToken cancellationToken) + => new CallTargetState(scope: null, state: cancellationToken); + + internal static CallTargetReturn OnMethodEnd(Task returnValue, Exception? exception, in CallTargetState state) + { + if (exception is not null) + { + return new CallTargetReturn(returnValue); + } + + // Delivery only starts here, because requesting configuration is billable, and the tracer + // must not start until application code adopts the provider. + if (TracerManager.Instance.FeatureFlags is { } featureFlags) + { + var cancellationToken = state.State is CancellationToken token ? token : default; + return new CallTargetReturn(featureFlags.InitializeAsync(cancellationToken)); + } + + return new CallTargetReturn(returnValue); + } +} diff --git a/tracer/src/Datadog.Trace/Generated/net461/Datadog.Trace.SourceGenerators/InstrumentationDefinitionsGenerator/InstrumentationDefinitions.g.cs b/tracer/src/Datadog.Trace/Generated/net461/Datadog.Trace.SourceGenerators/InstrumentationDefinitionsGenerator/InstrumentationDefinitions.g.cs index ed7f8bb91541..da754bf817a9 100644 --- a/tracer/src/Datadog.Trace/Generated/net461/Datadog.Trace.SourceGenerators/InstrumentationDefinitionsGenerator/InstrumentationDefinitions.g.cs +++ b/tracer/src/Datadog.Trace/Generated/net461/Datadog.Trace.SourceGenerators/InstrumentationDefinitionsGenerator/InstrumentationDefinitions.g.cs @@ -549,6 +549,7 @@ internal static bool IsInstrumentedAssembly(string assemblyName) => Datadog.Trace.Configuration.IntegrationId.NUnit, "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkAccumulateSpanEnrichmentIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkEvaluateIntegration" + or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkInitializeAsyncIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkIsAvailableIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkIsSpanEnrichmentEnabledIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkRegisterOnNewConfigEventHandlerIntegration" diff --git a/tracer/src/Datadog.Trace/Generated/net6.0/Datadog.Trace.SourceGenerators/InstrumentationDefinitionsGenerator/InstrumentationDefinitions.g.cs b/tracer/src/Datadog.Trace/Generated/net6.0/Datadog.Trace.SourceGenerators/InstrumentationDefinitionsGenerator/InstrumentationDefinitions.g.cs index c9bc620f079f..1683faa598c2 100644 --- a/tracer/src/Datadog.Trace/Generated/net6.0/Datadog.Trace.SourceGenerators/InstrumentationDefinitionsGenerator/InstrumentationDefinitions.g.cs +++ b/tracer/src/Datadog.Trace/Generated/net6.0/Datadog.Trace.SourceGenerators/InstrumentationDefinitionsGenerator/InstrumentationDefinitions.g.cs @@ -584,6 +584,7 @@ internal static bool IsInstrumentedAssembly(string assemblyName) => Datadog.Trace.Configuration.IntegrationId.NUnit, "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkAccumulateSpanEnrichmentIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkEvaluateIntegration" + or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkInitializeAsyncIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkIsAvailableIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkIsSpanEnrichmentEnabledIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkRegisterOnNewConfigEventHandlerIntegration" diff --git a/tracer/src/Datadog.Trace/Generated/netcoreapp3.1/Datadog.Trace.SourceGenerators/InstrumentationDefinitionsGenerator/InstrumentationDefinitions.g.cs b/tracer/src/Datadog.Trace/Generated/netcoreapp3.1/Datadog.Trace.SourceGenerators/InstrumentationDefinitionsGenerator/InstrumentationDefinitions.g.cs index 3e3b7e8d240c..3798b9500361 100644 --- a/tracer/src/Datadog.Trace/Generated/netcoreapp3.1/Datadog.Trace.SourceGenerators/InstrumentationDefinitionsGenerator/InstrumentationDefinitions.g.cs +++ b/tracer/src/Datadog.Trace/Generated/netcoreapp3.1/Datadog.Trace.SourceGenerators/InstrumentationDefinitionsGenerator/InstrumentationDefinitions.g.cs @@ -576,6 +576,7 @@ internal static bool IsInstrumentedAssembly(string assemblyName) => Datadog.Trace.Configuration.IntegrationId.NUnit, "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkAccumulateSpanEnrichmentIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkEvaluateIntegration" + or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkInitializeAsyncIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkIsAvailableIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkIsSpanEnrichmentEnabledIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkRegisterOnNewConfigEventHandlerIntegration" diff --git a/tracer/src/Datadog.Trace/Generated/netstandard2.0/Datadog.Trace.SourceGenerators/InstrumentationDefinitionsGenerator/InstrumentationDefinitions.g.cs b/tracer/src/Datadog.Trace/Generated/netstandard2.0/Datadog.Trace.SourceGenerators/InstrumentationDefinitionsGenerator/InstrumentationDefinitions.g.cs index 3e3b7e8d240c..3798b9500361 100644 --- a/tracer/src/Datadog.Trace/Generated/netstandard2.0/Datadog.Trace.SourceGenerators/InstrumentationDefinitionsGenerator/InstrumentationDefinitions.g.cs +++ b/tracer/src/Datadog.Trace/Generated/netstandard2.0/Datadog.Trace.SourceGenerators/InstrumentationDefinitionsGenerator/InstrumentationDefinitions.g.cs @@ -576,6 +576,7 @@ internal static bool IsInstrumentedAssembly(string assemblyName) => Datadog.Trace.Configuration.IntegrationId.NUnit, "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkAccumulateSpanEnrichmentIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkEvaluateIntegration" + or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkInitializeAsyncIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkIsAvailableIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkIsSpanEnrichmentEnabledIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkRegisterOnNewConfigEventHandlerIntegration" diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/FeatureFlags/SpanEnrichmentIntegrationTests.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/FeatureFlags/SpanEnrichmentIntegrationTests.cs index a20837e0ee41..f52ca2b7d754 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/FeatureFlags/SpanEnrichmentIntegrationTests.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/FeatureFlags/SpanEnrichmentIntegrationTests.cs @@ -202,7 +202,9 @@ private static List DecodeDeltaVarint(string base64) private async Task RunTest(MockTracerAgent agent, bool spanEnrichmentEnabled) { SetEnvironmentVariable(ConfigurationKeys.Rcm.PollInterval, "0.5"); +#pragma warning disable 618 // superseded, but still honoured for existing adopters SetEnvironmentVariable(ConfigurationKeys.FeatureFlags.FlaggingProviderEnabled, "1"); +#pragma warning restore 618 SetEnvironmentVariable(ConfigurationKeys.FeatureFlags.SpanEnrichmentEnabled, spanEnrichmentEnabled ? "1" : "0"); using var telemetry = this.ConfigureTelemetry(); diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs index 1488e0c2bac8..d23a4725116b 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs @@ -7,6 +7,9 @@ using System.Collections.Generic; using System.Collections.Specialized; +using System.Diagnostics; +using System.Threading; +using System.Threading.Tasks; using Datadog.Trace.Configuration; using Datadog.Trace.FeatureFlags; using Datadog.Trace.FeatureFlags.Rcm.Model; @@ -75,13 +78,147 @@ public void UpdateRemoteConfig_WithEmptyList_InvokesCallbackAndReturnsProviderNo result.Reason.Should().Be(EvaluationReason.Error); } - private static TracerSettings CreateSettings() + [Fact] + public void Create_WithAgentlessSource_DoesNotSubscribeToRc() + { + var rcmManager = new MockRcmSubscriptionManager(); + var settings = CreateSettings((ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSource, "agentless")); + + using var module = FeatureFlagsModule.Create(settings, rcmManager); + + module.Should().NotBeNull(); + module!.Settings.Source.Should().Be(FeatureFlagsSource.Agentless); + + // Subscribing would advertise the FFE capability and start a billed Remote Configuration + // subscription, which must not happen for a source that never uses it. + rcmManager.HasAnySubscription.Should().BeFalse(); + rcmManager.ProductKeys.Should().NotContain(RcmProducts.FfeFlags); + } + + [Fact] + public void Create_WithRemoteConfigSource_SubscribesAndAdvertisesCapability() + { + var rcmManager = new MockRcmSubscriptionManager(); + var settings = CreateSettings((ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSource, "remote_config")); + + using var module = FeatureFlagsModule.Create(settings, rcmManager); + + module.Should().NotBeNull(); + rcmManager.HasAnySubscription.Should().BeTrue(); + rcmManager.ProductKeys.Should().Contain(RcmProducts.FfeFlags); + } + + [Fact] + public void Create_WhenDisabled_ReturnsNull() + { + var rcmManager = new MockRcmSubscriptionManager(); + var settings = CreateSettings((ConfigurationKeys.FeatureFlags.FeatureFlagsEnabled, "false")); + + var module = FeatureFlagsModule.Create(settings, rcmManager); + + module.Should().BeNull(); + } + + [Fact] + public async Task InitializeAsync_WhenConfigurationAlreadyApplied_ReturnsImmediately() + { + var settings = CreateInitializationSettings("60000"); + using var module = FeatureFlagsModule.Create(settings, new MockRcmSubscriptionManager()); + + module!.ApplyConfiguration(new ServerConfiguration + { + Flags = new Dictionary + { + ["test-flag"] = new Flag { Key = "test-flag", Enabled = true, VariationType = FeatureFlagsValueType.Boolean } + } + }).Should().BeTrue(); + + module.FirstConfigReceived.IsCompleted.Should().BeTrue(); + + await module.InitializeAsync(CancellationToken.None); + } + + [Fact] + public async Task InitializeAsync_WhenConfigurationArrivesWhileWaiting_Returns() + { + var settings = CreateInitializationSettings("60000"); + using var module = FeatureFlagsModule.Create(settings, new MockRcmSubscriptionManager()); + + var initialization = module!.InitializeAsync(CancellationToken.None); + initialization.IsCompleted.Should().BeFalse(); + + module.ApplyConfiguration(new ServerConfiguration()).Should().BeTrue(); + + await initialization; + } + + [Fact] + public async Task InitializeAsync_OnTimeout_ReturnsWithoutThrowing() + { + var settings = CreateInitializationSettings("1"); + using var module = FeatureFlagsModule.Create(settings, new MockRcmSubscriptionManager()); + + // Initialization commonly runs at application startup, where throwing would take the + // application down, so a missing configuration is only reported through evaluations. + await module!.InitializeAsync(CancellationToken.None); + + module.FirstConfigReceived.IsCompleted.Should().BeFalse(); + module.Evaluate("test-flag", FeatureFlagsValueType.Boolean, false, "user-1", null) + .Error.Should().Be("PROVIDER_NOT_READY"); + } + + [Fact] + public async Task InitializeAsync_OnCancellation_ReturnsWithoutThrowing() + { + var settings = CreateInitializationSettings("60000"); + using var module = FeatureFlagsModule.Create(settings, new MockRcmSubscriptionManager()); + using var cancellation = new CancellationTokenSource(); + + var initialization = module!.InitializeAsync(cancellation.Token); + cancellation.Cancel(); + + await initialization; + } + + [Fact] + public async Task InitializeAsync_WhenAgentlessSourceCannotStart_ReturnsImmediately() + { + // Agentless without an API key cannot start the poller. Initialization should return + // immediately instead of waiting the full timeout for a configuration that will never arrive. + var settings = CreateSettings( + (ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSource, "agentless"), + (ConfigurationKeys.FeatureFlags.FlaggingProviderInitializationTimeoutMs, "60000")); + using var module = FeatureFlagsModule.Create(settings, new MockRcmSubscriptionManager()); + + var stopwatch = Stopwatch.StartNew(); + await module!.InitializeAsync(CancellationToken.None); + stopwatch.Stop(); + + // Should return near-instantly, not after the 60s timeout. + stopwatch.Elapsed.Should().BeLessThan(System.TimeSpan.FromSeconds(5)); + module.FirstConfigReceived.IsCompleted.Should().BeFalse(); + } + + private static TracerSettings CreateSettings(params (string Key, string Value)[] settings) { var collection = new NameValueCollection { - { ConfigurationKeys.FeatureFlags.FlaggingProviderEnabled, "true" } + { ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSource, "remote_config" }, +#pragma warning disable 618 // superseded, but still honoured for existing adopters + { ConfigurationKeys.FeatureFlags.FlaggingProviderEnabled, "true" }, +#pragma warning restore 618 }; + foreach (var (key, value) in settings) + { + collection[key] = value; + } + return new TracerSettings(new NameValueConfigurationSource(collection)); } + + private static TracerSettings CreateInitializationSettings(string timeoutMs) + => CreateSettings( + (ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSource, "remote_config"), + (ConfigurationKeys.FeatureFlags.FlaggingProviderInitializationTimeoutMs, timeoutMs)); } From a31e0843bc36f7c4d9ffbf71d89ebe0b62b556d0 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 13 Aug 2026 16:46:10 +0300 Subject: [PATCH 23/86] fix(feature-flags): add missing using directives for Task and CancellationToken --- .../src/Datadog.FeatureFlags.OpenFeature/Sdk/FeatureFlagsSdk.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tracer/src/Datadog.FeatureFlags.OpenFeature/Sdk/FeatureFlagsSdk.cs b/tracer/src/Datadog.FeatureFlags.OpenFeature/Sdk/FeatureFlagsSdk.cs index cd77621ae839..7ae5ac8438f4 100644 --- a/tracer/src/Datadog.FeatureFlags.OpenFeature/Sdk/FeatureFlagsSdk.cs +++ b/tracer/src/Datadog.FeatureFlags.OpenFeature/Sdk/FeatureFlagsSdk.cs @@ -9,6 +9,8 @@ using System.ComponentModel; using System.Linq; using System.Runtime.CompilerServices; +using System.Threading; +using System.Threading.Tasks; using Datadog.Trace.FeatureFlags; using OpenFeature.Constant; using OpenFeature.Model; From a31ba4ce54c30d6636360da12586dd92707ffd1d Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 13 Aug 2026 17:14:53 +0300 Subject: [PATCH 24/86] fix(feature-flags): commit regenerated native calltarget definitions for OpenFeature InitializeAsync --- tracer/build/supported_calltargets.g.json | 24 +- .../Generated/generated_calltargets.g.cpp | 1176 +++++++++-------- 2 files changed, 601 insertions(+), 599 deletions(-) diff --git a/tracer/build/supported_calltargets.g.json b/tracer/build/supported_calltargets.g.json index e610b91f6fb3..ee02f8645bcb 100644 --- a/tracer/build/supported_calltargets.g.json +++ b/tracer/build/supported_calltargets.g.json @@ -14058,10 +14058,14 @@ "IntegrationName": "OpenFeature", "AssemblyName": "Datadog.FeatureFlags.OpenFeature", "TargetTypeName": "Datadog.FeatureFlags.OpenFeature.FeatureFlagsSdk", - "TargetMethodName": "InitializeAsync", - "TargetReturnType": "System.Threading.Tasks.Task", + "TargetMethodName": "Evaluate", + "TargetReturnType": "Datadog.Trace.FeatureFlags.IEvaluation", "TargetParameterTypes": [ - "System.Threading.CancellationToken" + "System.String", + "Datadog.Trace.FeatureFlags.ValueType", + "System.Object", + "System.String", + "System.Collections.Generic.IDictionary`2[System.String,System.Object]" ], "MinimumVersion": { "Item1": 2, @@ -14073,7 +14077,7 @@ "Item2": 65535, "Item3": 65535 }, - "InstrumentationTypeName": "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkInitializeAsyncIntegration", + "InstrumentationTypeName": "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkEvaluateIntegration", "IntegrationKind": 0, "IsAdoNetIntegration": false, "InstrumentationCategory": 1 @@ -14082,14 +14086,10 @@ "IntegrationName": "OpenFeature", "AssemblyName": "Datadog.FeatureFlags.OpenFeature", "TargetTypeName": "Datadog.FeatureFlags.OpenFeature.FeatureFlagsSdk", - "TargetMethodName": "Evaluate", - "TargetReturnType": "Datadog.Trace.FeatureFlags.IEvaluation", + "TargetMethodName": "InitializeAsync", + "TargetReturnType": "System.Threading.Tasks.Task", "TargetParameterTypes": [ - "System.String", - "Datadog.Trace.FeatureFlags.ValueType", - "System.Object", - "System.String", - "System.Collections.Generic.IDictionary`2[System.String,System.Object]" + "System.Threading.CancellationToken" ], "MinimumVersion": { "Item1": 2, @@ -14101,7 +14101,7 @@ "Item2": 65535, "Item3": 65535 }, - "InstrumentationTypeName": "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkEvaluateIntegration", + "InstrumentationTypeName": "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkInitializeAsyncIntegration", "IntegrationKind": 0, "IsAdoNetIntegration": false, "InstrumentationCategory": 1 diff --git a/tracer/src/Datadog.Tracer.Native/Generated/generated_calltargets.g.cpp b/tracer/src/Datadog.Tracer.Native/Generated/generated_calltargets.g.cpp index abe33e902eec..deb5d2182031 100644 --- a/tracer/src/Datadog.Tracer.Native/Generated/generated_calltargets.g.cpp +++ b/tracer/src/Datadog.Tracer.Native/Generated/generated_calltargets.g.cpp @@ -232,253 +232,254 @@ WCHAR* sig213[]={(WCHAR*)WStr("System.Threading.Tasks.Task"),(WCHAR*)WStr("Syste WCHAR* sig214[]={(WCHAR*)WStr("System.Threading.Tasks.Task"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.Object]"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; WCHAR* sig215[]={(WCHAR*)WStr("System.Threading.Tasks.Task"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.UInt64"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("RabbitMQ.Client.IBasicProperties"),(WCHAR*)WStr("_"),}; WCHAR* sig216[]={(WCHAR*)WStr("System.Threading.Tasks.Task"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.UInt64"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("RabbitMQ.Client.IReadOnlyBasicProperties"),(WCHAR*)WStr("System.ReadOnlyMemory`1[System.Byte]"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig217[]={(WCHAR*)WStr("System.Threading.Tasks.Task"),(WCHAR*)WStr("_"),}; -WCHAR* sig218[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1"),(WCHAR*)WStr("StackExchange.Redis.Message"),(WCHAR*)WStr("StackExchange.Redis.ResultProcessor`1[!!0]"),(WCHAR*)WStr("!!0"),(WCHAR*)WStr("StackExchange.Redis.ServerEndPoint"),}; -WCHAR* sig219[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1"),(WCHAR*)WStr("StackExchange.Redis.Message"),(WCHAR*)WStr("StackExchange.Redis.ResultProcessor`1[!!0]"),(WCHAR*)WStr("StackExchange.Redis.ServerEndPoint"),}; -WCHAR* sig220[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1"),(WCHAR*)WStr("GraphQL.Execution.ExecutionContext"),}; -WCHAR* sig221[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1"),}; -WCHAR* sig222[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[!!0]"),(WCHAR*)WStr("StackExchange.Redis.Message"),(WCHAR*)WStr("StackExchange.Redis.ResultProcessor`1[!!0]"),(WCHAR*)WStr("System.Object"),(WCHAR*)WStr("StackExchange.Redis.ServerEndPoint"),}; -WCHAR* sig223[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[!!0]"),(WCHAR*)WStr("StackExchange.Redis.Message"),(WCHAR*)WStr("StackExchange.Redis.ResultProcessor`1[!!0]"),(WCHAR*)WStr("System.Object"),(WCHAR*)WStr("StackExchange.Redis.ServerEndPoint"),(WCHAR*)WStr("!!0"),}; -WCHAR* sig224[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[!0]"),(WCHAR*)WStr("Amazon.Runtime.IExecutionContext"),}; -WCHAR* sig225[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[!0]"),(WCHAR*)WStr("Elasticsearch.Net.HttpMethod"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Threading.CancellationToken"),(WCHAR*)WStr("Elasticsearch.Net.PostData"),(WCHAR*)WStr("Elasticsearch.Net.IRequestParameters"),}; -WCHAR* sig226[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[!0]"),(WCHAR*)WStr("Elasticsearch.Net.RequestData"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig227[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[!0]"),(WCHAR*)WStr("GraphQL.Types.ISchema"),(WCHAR*)WStr("GraphQL.Language.AST.Document"),(WCHAR*)WStr("GraphQL.Language.AST.VariableDefinitions"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[GraphQL.Validation.IValidationRule]"),(WCHAR*)WStr("_"),(WCHAR*)WStr("GraphQL.Inputs"),}; -WCHAR* sig228[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[!0]"),(WCHAR*)WStr("GraphQL.Validation.ValidationContext"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[GraphQL.Validation.IValidationRule]"),}; -WCHAR* sig229[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[!0]"),(WCHAR*)WStr("MongoDB.Driver.Core.Connections.IConnection"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig230[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[!0]"),(WCHAR*)WStr("MongoDB.Driver.OperationContext"),(WCHAR*)WStr("MongoDB.Driver.Core.Connections.IConnection"),}; -WCHAR* sig231[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[!0]"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("GraphQL.Types.ISchema"),(WCHAR*)WStr("GraphQL.Language.AST.Document"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[GraphQL.Validation.IValidationRule]"),(WCHAR*)WStr("_"),(WCHAR*)WStr("GraphQL.Inputs"),}; -WCHAR* sig232[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.DynamoDBv2.Model.BatchGetItemResponse]"),(WCHAR*)WStr("Amazon.DynamoDBv2.Model.BatchGetItemRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig233[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.DynamoDBv2.Model.BatchWriteItemResponse]"),(WCHAR*)WStr("Amazon.DynamoDBv2.Model.BatchWriteItemRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig234[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.DynamoDBv2.Model.DeleteItemResponse]"),(WCHAR*)WStr("Amazon.DynamoDBv2.Model.DeleteItemRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig235[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.DynamoDBv2.Model.GetItemResponse]"),(WCHAR*)WStr("Amazon.DynamoDBv2.Model.GetItemRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig236[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.DynamoDBv2.Model.PutItemResponse]"),(WCHAR*)WStr("Amazon.DynamoDBv2.Model.PutItemRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig237[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.DynamoDBv2.Model.ScanResponse]"),(WCHAR*)WStr("Amazon.DynamoDBv2.Model.ScanRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig238[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.DynamoDBv2.Model.UpdateItemResponse]"),(WCHAR*)WStr("Amazon.DynamoDBv2.Model.UpdateItemRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig239[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.EventBridge.Model.PutEventsResponse]"),(WCHAR*)WStr("Amazon.EventBridge.Model.PutEventsRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig240[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.Kinesis.Model.GetRecordsResponse]"),(WCHAR*)WStr("Amazon.Kinesis.Model.GetRecordsRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig241[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.Kinesis.Model.PutRecordResponse]"),(WCHAR*)WStr("Amazon.Kinesis.Model.PutRecordRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig242[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.Kinesis.Model.PutRecordsResponse]"),(WCHAR*)WStr("Amazon.Kinesis.Model.PutRecordsRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig243[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.S3.Model.CompleteMultipartUploadResponse]"),(WCHAR*)WStr("Amazon.S3.Model.CompleteMultipartUploadRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig244[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.S3.Model.CopyObjectResponse]"),(WCHAR*)WStr("Amazon.S3.Model.CopyObjectRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig245[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.S3.Model.DeleteBucketResponse]"),(WCHAR*)WStr("Amazon.S3.Model.DeleteBucketRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig246[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.S3.Model.DeleteObjectResponse]"),(WCHAR*)WStr("Amazon.S3.Model.DeleteObjectRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig247[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.S3.Model.DeleteObjectsResponse]"),(WCHAR*)WStr("Amazon.S3.Model.DeleteObjectsRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig248[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.S3.Model.GetObjectResponse]"),(WCHAR*)WStr("Amazon.S3.Model.GetObjectRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig249[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.S3.Model.InitiateMultipartUploadResponse]"),(WCHAR*)WStr("Amazon.S3.Model.InitiateMultipartUploadRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig250[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.S3.Model.ListBucketsResponse]"),(WCHAR*)WStr("Amazon.S3.Model.ListBucketsRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig251[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.S3.Model.ListObjectsV2Response]"),(WCHAR*)WStr("Amazon.S3.Model.ListObjectsV2Request"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig252[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.S3.Model.PutBucketResponse]"),(WCHAR*)WStr("Amazon.S3.Model.PutBucketRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig253[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.S3.Model.PutObjectResponse]"),(WCHAR*)WStr("Amazon.S3.Model.PutObjectRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig254[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.S3.Model.UploadPartResponse]"),(WCHAR*)WStr("Amazon.S3.Model.UploadPartRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig255[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.SimpleNotificationService.Model.PublishBatchResponse]"),(WCHAR*)WStr("Amazon.SimpleNotificationService.Model.PublishBatchRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig256[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.SimpleNotificationService.Model.PublishResponse]"),(WCHAR*)WStr("Amazon.SimpleNotificationService.Model.PublishRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig257[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.SQS.Model.CreateQueueResponse]"),(WCHAR*)WStr("Amazon.SQS.Model.CreateQueueRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig258[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.SQS.Model.DeleteMessageBatchResponse]"),(WCHAR*)WStr("Amazon.SQS.Model.DeleteMessageBatchRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig259[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.SQS.Model.DeleteMessageResponse]"),(WCHAR*)WStr("Amazon.SQS.Model.DeleteMessageRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig260[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.SQS.Model.DeleteQueueResponse]"),(WCHAR*)WStr("Amazon.SQS.Model.DeleteQueueRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig261[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.SQS.Model.ReceiveMessageResponse]"),(WCHAR*)WStr("Amazon.SQS.Model.ReceiveMessageRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig262[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.SQS.Model.SendMessageBatchResponse]"),(WCHAR*)WStr("Amazon.SQS.Model.SendMessageBatchRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig263[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.SQS.Model.SendMessageResponse]"),(WCHAR*)WStr("Amazon.SQS.Model.SendMessageRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig264[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Confluent.Kafka.DeliveryReport`2[!0,!1]]"),(WCHAR*)WStr("Confluent.Kafka.TopicPartition"),(WCHAR*)WStr("Confluent.Kafka.Message`2[!0,!1]"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig265[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Elasticsearch.Net.ElasticsearchResponse`1[!0]]"),(WCHAR*)WStr("Elasticsearch.Net.RequestData"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig266[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[HotChocolate.Execution.IExecutionResult]"),(WCHAR*)WStr("HotChocolate.Execution.IOperationRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig267[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[HotChocolate.Execution.IExecutionResult]"),(WCHAR*)WStr("HotChocolate.Execution.IQueryRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig268[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[HotChocolate.Execution.IExecutionResult]"),(WCHAR*)WStr("HotChocolate.Execution.Processing.IOperationContext"),}; -WCHAR* sig269[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[HotChocolate.Execution.IExecutionResult]"),(WCHAR*)WStr("HotChocolate.Execution.Processing.OperationContext"),}; -WCHAR* sig270[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[HotChocolate.Execution.IOperationResult]"),(WCHAR*)WStr("HotChocolate.Execution.Processing.OperationContext"),}; -WCHAR* sig271[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[HotChocolate.Execution.IQueryResult]"),(WCHAR*)WStr("HotChocolate.Execution.Processing.OperationContext"),}; -WCHAR* sig272[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Identity.IdentityResult]"),(WCHAR*)WStr("!0"),}; -WCHAR* sig273[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Identity.SignInResult]"),(WCHAR*)WStr("!0"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Boolean"),}; -WCHAR* sig274[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Identity.SignInResult]"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Boolean"),}; -WCHAR* sig275[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ResponseMessage]"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("Microsoft.Azure.Documents.ResourceType"),(WCHAR*)WStr("Microsoft.Azure.Documents.OperationType"),(WCHAR*)WStr("Microsoft.Azure.Cosmos.RequestOptions"),(WCHAR*)WStr("Microsoft.Azure.Cosmos.ContainerInternal"),(WCHAR*)WStr("_"),(WCHAR*)WStr("System.IO.Stream"),(WCHAR*)WStr("System.Action`1[Microsoft.Azure.Cosmos.RequestMessage]"),(WCHAR*)WStr("_"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig276[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.Azure.WebJobs.Host.Executors.IDelayedException]"),(WCHAR*)WStr("Microsoft.Azure.WebJobs.Host.Executors.IFunctionInstance"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig277[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.Azure.WebJobs.Script.Grpc.Messages.TypedData]"),(WCHAR*)WStr("Microsoft.AspNetCore.Http.HttpRequest"),(WCHAR*)WStr("Microsoft.Extensions.Logging.ILogger"),(WCHAR*)WStr("Microsoft.Azure.WebJobs.Script.Grpc.GrpcCapabilities"),}; -WCHAR* sig278[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.Data.SqlClient.SqlDataReader]"),}; -WCHAR* sig279[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.Data.SqlClient.SqlDataReader]"),(WCHAR*)WStr("System.Data.CommandBehavior"),}; -WCHAR* sig280[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.Data.SqlClient.SqlDataReader]"),(WCHAR*)WStr("System.Data.CommandBehavior"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig281[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.Data.SqlClient.SqlDataReader]"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig282[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.Data.Sqlite.SqliteDataReader]"),(WCHAR*)WStr("System.Data.CommandBehavior"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig283[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.VisualStudio.TestTools.UnitTesting.TestResult[]]"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestMethodInfo"),}; -WCHAR* sig284[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.VisualStudio.TestTools.UnitTesting.TestResult[]]"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel.TestMethod"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.Object]"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging.IMessageLogger"),}; -WCHAR* sig285[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.VisualStudio.TestTools.UnitTesting.TestResult[]]"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel.UnitTestElement"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.Object]"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging.IMessageLogger"),}; -WCHAR* sig286[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.VisualStudio.TestTools.UnitTesting.TestResult[]]"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel.UnitTestElement"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.Object]"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.Object]"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging.IMessageLogger"),}; -WCHAR* sig287[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.VisualStudio.TestTools.UnitTesting.TestResult[]]"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestContext"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestMethodInfo"),}; -WCHAR* sig288[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.VisualStudio.TestTools.UnitTesting.TestResult[]]"),(WCHAR*)WStr("Microsoft.VisualStudio.TestTools.UnitTesting.ITestMethod"),}; -WCHAR* sig289[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[MySql.Data.MySqlClient.MySqlDataReader]"),(WCHAR*)WStr("System.Data.CommandBehavior"),}; -WCHAR* sig290[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[MySql.Data.MySqlClient.MySqlDataReader]"),(WCHAR*)WStr("System.Data.CommandBehavior"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig291[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[MySqlConnector.MySqlDataReader]"),(WCHAR*)WStr("System.Data.CommandBehavior"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig292[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[MySqlConnector.MySqlDataReader]"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig293[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Npgsql.NpgsqlDataReader]"),(WCHAR*)WStr("System.Data.CommandBehavior"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig294[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Oracle.DataAccess.Client.OracleDataReader]"),}; -WCHAR* sig295[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Oracle.DataAccess.Client.OracleDataReader]"),(WCHAR*)WStr("System.Data.CommandBehavior"),}; -WCHAR* sig296[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Oracle.DataAccess.Client.OracleDataReader]"),(WCHAR*)WStr("System.Data.CommandBehavior"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig297[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Oracle.DataAccess.Client.OracleDataReader]"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig298[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Oracle.ManagedDataAccess.Client.OracleDataReader]"),}; -WCHAR* sig299[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Oracle.ManagedDataAccess.Client.OracleDataReader]"),(WCHAR*)WStr("System.Data.CommandBehavior"),}; -WCHAR* sig300[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Oracle.ManagedDataAccess.Client.OracleDataReader]"),(WCHAR*)WStr("System.Data.CommandBehavior"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig301[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Oracle.ManagedDataAccess.Client.OracleDataReader]"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig302[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[RabbitMQ.Client.BasicGetResult]"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig303[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[RabbitMQ.Client.QueueDeclareOk]"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.Object]"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig304[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[System.Collections.Generic.IReadOnlyList`1[Azure.Messaging.EventHubs.EventData]]"),(WCHAR*)WStr("System.Int32"),(WCHAR*)WStr("System.Nullable`1[System.TimeSpan]"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig305[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[System.Collections.Generic.IReadOnlyList`1[Azure.Messaging.ServiceBus.ServiceBusReceivedMessage]]"),(WCHAR*)WStr("System.Int32"),(WCHAR*)WStr("System.Nullable`1[System.TimeSpan]"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig306[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[System.Collections.Generic.IReadOnlyList`1[System.Int64]]"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Azure.Messaging.ServiceBus.ServiceBusMessage]"),(WCHAR*)WStr("System.DateTimeOffset"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig307[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[System.Data.Common.DbDataReader]"),(WCHAR*)WStr("System.Data.CommandBehavior"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig308[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[System.Data.SqlClient.SqlDataReader]"),(WCHAR*)WStr("System.Data.CommandBehavior"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig309[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[System.Decimal]"),}; -WCHAR* sig310[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[System.Int32]"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig311[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[System.Net.Http.HttpResponseMessage]"),(WCHAR*)WStr("System.Net.Http.HttpRequestMessage"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig312[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[System.Net.Http.HttpResponseMessage]"),(WCHAR*)WStr("System.Web.Http.Controllers.HttpControllerContext"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.Object]"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig313[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[System.Net.Http.HttpResponseMessage]"),(WCHAR*)WStr("System.Web.Http.Controllers.HttpControllerContext"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig314[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[System.Net.Http.HttpResponseMessage]"),(WCHAR*)WStr("System.Web.Http.ExceptionHandling.IExceptionHandler"),(WCHAR*)WStr("System.Web.Http.ExceptionHandling.ExceptionContext"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig315[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[System.Object]"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig316[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[System.String]"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.Object]"),(WCHAR*)WStr("RabbitMQ.Client.IAsyncBasicConsumer"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig317[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[System.Tuple`2[System.Object, System.Object[]]]"),(WCHAR*)WStr("System.Object"),(WCHAR*)WStr("System.Object[]"),}; -WCHAR* sig318[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Xunit.Sdk.RunSummary]"),}; -WCHAR* sig319[]={(WCHAR*)WStr("System.Threading.Tasks.ValueTask"),(WCHAR*)WStr("RabbitMQ.Client.CachedString"),(WCHAR*)WStr("RabbitMQ.Client.CachedString"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("!!0"),(WCHAR*)WStr("System.ReadOnlyMemory`1[System.Byte]"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig320[]={(WCHAR*)WStr("System.Threading.Tasks.ValueTask"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("!!0"),(WCHAR*)WStr("System.ReadOnlyMemory`1[System.Byte]"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig321[]={(WCHAR*)WStr("System.Threading.Tasks.ValueTask`1[System.TimeSpan]"),(WCHAR*)WStr("_"),}; -WCHAR* sig322[]={(WCHAR*)WStr("System.Threading.Tasks.ValueTask`1[Xunit.v3.RunSummary]"),(WCHAR*)WStr("!0"),}; -WCHAR* sig323[]={(WCHAR*)WStr("System.Threading.Tasks.ValueTask`1[Xunit.v3.RunSummary]"),(WCHAR*)WStr("!0"),(WCHAR*)WStr("!2"),}; -WCHAR* sig324[]={(WCHAR*)WStr("System.Uri"),}; -WCHAR* sig325[]={(WCHAR*)WStr("System.Void"),}; -WCHAR* sig326[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("!!0"),(WCHAR*)WStr("System.Action`3[!!0,System.String,System.String]"),(WCHAR*)WStr("Datadog.Trace.ISpanContext"),}; -WCHAR* sig327[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("!!0"),(WCHAR*)WStr("System.Action`3[!!0,System.String,System.String]"),(WCHAR*)WStr("Datadog.Trace.ISpanContext"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),}; -WCHAR* sig328[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Amazon.Lambda.RuntimeSupport.LambdaBootstrapHandler"),}; -WCHAR* sig329[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Confluent.Kafka.ConsumerBuilder`2[!0,!1]"),}; -WCHAR* sig330[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Confluent.Kafka.ProducerBuilder`2[!0,!1]"),}; -WCHAR* sig331[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Confluent.Kafka.TopicPartition"),(WCHAR*)WStr("Confluent.Kafka.Message`2[!0,!1]"),(WCHAR*)WStr("System.Action`1[Confluent.Kafka.DeliveryReport`2[!0,!1]]"),}; -WCHAR* sig332[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Datadog.Trace.Ci.ITest"),(WCHAR*)WStr("Datadog.Trace.Ci.BenchmarkHostInfo&"),(WCHAR*)WStr("Datadog.Trace.Ci.BenchmarkJobInfo&"),}; -WCHAR* sig333[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Datadog.Trace.Ci.ITest"),(WCHAR*)WStr("Datadog.Trace.Ci.BenchmarkMeasureType"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("Datadog.Trace.Ci.BenchmarkDiscreteStats&"),}; -WCHAR* sig334[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Datadog.Trace.Ci.ITest"),(WCHAR*)WStr("Datadog.Trace.Ci.TestParameters"),}; -WCHAR* sig335[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Datadog.Trace.ISpan"),(WCHAR*)WStr("Datadog.Trace.SamplingPriority"),}; -WCHAR* sig336[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Datadog.Trace.ISpan"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),}; -WCHAR* sig337[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Google.Protobuf.CodedInputStream"),}; -WCHAR* sig338[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Google.Protobuf.CodedOutputStream"),}; -WCHAR* sig339[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Google.Protobuf.ParseContext&"),}; -WCHAR* sig340[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Google.Protobuf.WriteContext&"),}; -WCHAR* sig341[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("IBM.WMQ.MQMessage"),(WCHAR*)WStr("IBM.WMQ.MQGetMessageOptions"),(WCHAR*)WStr("System.Int32"),}; -WCHAR* sig342[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("IBM.WMQ.MQMessage"),(WCHAR*)WStr("IBM.WMQ.MQPutMessageOptions"),}; -WCHAR* sig343[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Microsoft.AspNetCore.Builder.IApplicationBuilder"),(WCHAR*)WStr("Microsoft.AspNetCore.Http.RequestDelegate"),}; -WCHAR* sig344[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Microsoft.AspNetCore.Http.HttpResponse"),(WCHAR*)WStr("System.Int32"),(WCHAR*)WStr("Grpc.Core.StatusCode"),(WCHAR*)WStr("System.String"),}; -WCHAR* sig345[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingResult"),}; -WCHAR* sig346[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Microsoft.VisualStudio.TestTools.UnitTesting.TestContext"),}; -WCHAR* sig347[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Microsoft.VisualStudio.TestTools.UnitTesting.TestContext"),(WCHAR*)WStr("_"),}; -WCHAR* sig348[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("MongoDB.Driver.Core.Connections.IConnection"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; -WCHAR* sig349[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("NLog.Config.LoggingConfiguration"),}; -WCHAR* sig350[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("NUnit.Framework.Internal.TestMethod"),(WCHAR*)WStr("NUnit.Framework.Interfaces.ITestFilter"),}; -WCHAR* sig351[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("NUnit.Framework.Internal.TestMethod"),(WCHAR*)WStr("NUnit.Framework.Interfaces.ITestFilter"),(WCHAR*)WStr("NUnit.Framework.Internal.Abstractions.IDebugger"),}; -WCHAR* sig352[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("OpenQA.Selenium.Remote.SendingRemoteHttpRequestEventArgs"),}; -WCHAR* sig353[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("OpenTelemetry.Baggage"),}; -WCHAR* sig354[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Serilog.Events.LogEvent"),}; -WCHAR* sig355[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Action"),}; -WCHAR* sig356[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Action`2[System.Object,!!0]"),(WCHAR*)WStr("!!0"),}; -WCHAR* sig357[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Boolean"),}; -WCHAR* sig358[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("Grpc.Core.Internal.ClientSideStatus"),}; -WCHAR* sig359[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("Grpc.Core.Internal.ClientSideStatus"),(WCHAR*)WStr("Grpc.Core.Internal.IBufferReader"),(WCHAR*)WStr("Grpc.Core.Metadata"),}; -WCHAR* sig360[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.Dictionary`2[System.String,System.Object]"),}; -WCHAR* sig361[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.Dictionary`2[System.String,System.Object]"),(WCHAR*)WStr("System.Boolean"),}; -WCHAR* sig362[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.ICollection`1[System.Reflection.MethodInfo]"),(WCHAR*)WStr("System.Func`1[System.IDisposable]"),}; -WCHAR* sig363[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.Object]"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String&"),(WCHAR*)WStr("System.String&"),}; -WCHAR* sig364[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.String]"),}; -WCHAR* sig365[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Confluent.Kafka.TopicPartitionOffset]"),}; -WCHAR* sig366[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Microsoft.Extensions.Logging.ILoggerProvider]"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.Extensions.Logging.LoggerFilterOptions]"),}; -WCHAR* sig367[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Microsoft.Extensions.Logging.ILoggerProvider]"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.Extensions.Logging.LoggerFilterOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptions`1[Microsoft.Extensions.Logging.LoggerFactoryOptions]"),}; -WCHAR* sig368[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Microsoft.Extensions.Logging.ILoggerProvider]"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.Extensions.Logging.LoggerFilterOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptions`1[Microsoft.Extensions.Logging.LoggerFactoryOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Logging.IExternalScopeProvider"),}; -WCHAR* sig369[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Microsoft.Extensions.Logging.ILoggerProvider]"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Microsoft.Extensions.Diagnostics.Enrichment.ILogEnricher]"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Microsoft.Extensions.Diagnostics.Enrichment.IStaticLogEnricher]"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.Extensions.Logging.LoggerFilterOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Logging.LoggingSampler"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptions`1[Microsoft.Extensions.Logging.LoggerFactoryOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Logging.IExternalScopeProvider"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.Extensions.Logging.LoggerEnrichmentOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.Extensions.Logging.LoggerRedactionOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Compliance.Redaction.IRedactorProvider"),}; -WCHAR* sig370[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Microsoft.Extensions.Logging.ILoggerProvider]"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Microsoft.Extensions.Diagnostics.Enrichment.ILogEnricher]"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Microsoft.Extensions.Diagnostics.Enrichment.IStaticLogEnricher]"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.Extensions.Logging.LoggerFilterOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Logging.LoggingSampler"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptions`1[Microsoft.Extensions.Logging.LoggerFactoryOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Logging.IExternalScopeProvider"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.Extensions.Logging.LoggerEnrichmentOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.Extensions.Logging.LoggerRedactionOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Compliance.Redaction.IRedactorProvider"),(WCHAR*)WStr("Microsoft.Extensions.Diagnostics.Buffering.LogBuffer"),}; -WCHAR* sig371[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Microsoft.Extensions.Logging.ILoggerProvider]"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Microsoft.Extensions.Diagnostics.Enrichment.ILogEnricher]"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Microsoft.Extensions.Diagnostics.Enrichment.IStaticLogEnricher]"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.Extensions.Logging.LoggerFilterOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptions`1[Microsoft.Extensions.Logging.LoggerFactoryOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Logging.IExternalScopeProvider"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.Extensions.Logging.LoggerEnrichmentOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.Extensions.Logging.LoggerRedactionOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Compliance.Redaction.IRedactorProvider"),}; -WCHAR* sig372[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel.UnitTestElement]"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter.ITestCaseDiscoverySink"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter.IDiscoveryContext"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging.IMessageLogger"),}; -WCHAR* sig373[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[System.String]"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.String"),}; -WCHAR* sig374[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[System.String]"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[System.String]"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[System.String]"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.String"),}; -WCHAR* sig375[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Exception"),(WCHAR*)WStr("System.Boolean"),}; -WCHAR* sig376[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.IO.Stream"),(WCHAR*)WStr("System.Object"),}; -WCHAR* sig377[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Net.Http.HttpRequestMessage"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Diagnostics.Activity"),(WCHAR*)WStr("Grpc.Core.Status"),}; -WCHAR* sig378[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Net.Http.HttpRequestMessage"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Diagnostics.Activity"),(WCHAR*)WStr("System.Nullable`1[Grpc.Core.Status]"),}; -WCHAR* sig379[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Net.HttpWebResponse"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.ITransportHeaders&"),(WCHAR*)WStr("System.IO.Stream&"),}; -WCHAR* sig380[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Net.WebException"),(WCHAR*)WStr("System.Net.HttpWebResponse&"),}; -WCHAR* sig381[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Nullable`1[System.Int64]"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Object"),}; -WCHAR* sig382[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Object"),(WCHAR*)WStr("System.Collections.Generic.Dictionary`2[System.String,System.Object]"),}; -WCHAR* sig383[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Object"),(WCHAR*)WStr("System.Messaging.MessageQueueTransaction"),(WCHAR*)WStr("System.Messaging.MessageQueueTransactionType"),}; -WCHAR* sig384[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.IServerResponseChannelSinkStack"),(WCHAR*)WStr("System.Runtime.Remoting.Messaging.IMessage"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.ITransportHeaders&"),(WCHAR*)WStr("System.IO.Stream&"),}; -WCHAR* sig385[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.IServerResponseChannelSinkStack"),(WCHAR*)WStr("System.Runtime.Remoting.Messaging.IMessage"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.ITransportHeaders&"),(WCHAR*)WStr("System.IO.Stream&"),}; -WCHAR* sig386[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Runtime.Remoting.Messaging.IMessage"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.ITransportHeaders"),(WCHAR*)WStr("System.IO.Stream"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.ITransportHeaders&"),(WCHAR*)WStr("System.IO.Stream&"),}; -WCHAR* sig387[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.ServiceModel.Dispatcher.MessageRpc&"),}; -WCHAR* sig388[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.ServiceModel.Dispatcher.MessageRpc&"),(WCHAR*)WStr("System.Exception&"),(WCHAR*)WStr("System.Boolean&"),}; -WCHAR* sig389[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),}; -WCHAR* sig390[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("!0"),(WCHAR*)WStr("!1"),(WCHAR*)WStr("System.Action`1[Confluent.Kafka.DeliveryReport`2[!0,!1]]"),}; -WCHAR* sig391[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("Datadog.Trace.UserDetails"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.String]"),}; -WCHAR* sig392[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("NLog.Config.LoggingConfiguration"),}; -WCHAR* sig393[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),}; -WCHAR* sig394[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("Datadog.Trace.UserDetails"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.String]"),}; -WCHAR* sig395[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.Object]"),}; -WCHAR* sig396[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.String]"),}; -WCHAR* sig397[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.String]"),}; -WCHAR* sig398[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.String]"),}; -WCHAR* sig399[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel.UnitTestElement]"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter.ITestCaseDiscoverySink"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter.IDiscoveryContext"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging.IMessageLogger"),}; -WCHAR* sig400[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),}; -WCHAR* sig401[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("RabbitMQ.Client.IBasicProperties"),(WCHAR*)WStr("_"),}; -WCHAR* sig402[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.Object]"),}; -WCHAR* sig403[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.String]"),}; -WCHAR* sig404[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.Object]"),}; -WCHAR* sig405[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.UInt64"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("RabbitMQ.Client.IBasicProperties"),(WCHAR*)WStr("_"),}; -WCHAR* sig406[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.TimeSpan"),}; -WCHAR* sig407[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Type"),(WCHAR*)WStr("NLog.Internal.TargetWithFilterChain"),(WCHAR*)WStr("NLog.LogEventInfo"),(WCHAR*)WStr("NLog.LogFactory"),}; -WCHAR* sig408[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Xml.XmlDictionaryWriter"),(WCHAR*)WStr("System.Object"),}; -WCHAR* sig409[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Xml.XmlWriter"),(WCHAR*)WStr("System.Object"),}; -WCHAR* sig410[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Xunit.v3.IXunitTestMethod"),(WCHAR*)WStr("System.Collections.Generic.IReadOnlyCollection`1[Xunit.v3.IXunitTestCase]"),(WCHAR*)WStr("Xunit.Sdk.ExplicitOption"),(WCHAR*)WStr("Xunit.v3.IMessageBus"),(WCHAR*)WStr("Xunit.v3.ExceptionAggregator"),(WCHAR*)WStr("System.Threading.CancellationTokenSource"),(WCHAR*)WStr("System.Object[]"),}; -WCHAR* sig411[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Yarp.ReverseProxy.Forwarder.ForwarderHttpClientContext"),(WCHAR*)WStr("System.Net.Http.SocketsHttpHandler"),}; -WCHAR* sig412[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("_"),}; -WCHAR* sig413[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("_"),(WCHAR*)WStr("_"),}; -WCHAR* sig414[]={(WCHAR*)WStr("System.Web.Mvc.ActionResult"),(WCHAR*)WStr("System.Web.Mvc.ControllerContext"),(WCHAR*)WStr("System.Web.Mvc.ActionDescriptor"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.Object]"),}; -WCHAR* sig415[]={(WCHAR*)WStr("_"),(WCHAR*)WStr("_"),}; -WCHAR* sig416[]={(WCHAR*)WStr("_"),(WCHAR*)WStr("_"),(WCHAR*)WStr("_"),}; +WCHAR* sig217[]={(WCHAR*)WStr("System.Threading.Tasks.Task"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig218[]={(WCHAR*)WStr("System.Threading.Tasks.Task"),(WCHAR*)WStr("_"),}; +WCHAR* sig219[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1"),(WCHAR*)WStr("StackExchange.Redis.Message"),(WCHAR*)WStr("StackExchange.Redis.ResultProcessor`1[!!0]"),(WCHAR*)WStr("!!0"),(WCHAR*)WStr("StackExchange.Redis.ServerEndPoint"),}; +WCHAR* sig220[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1"),(WCHAR*)WStr("StackExchange.Redis.Message"),(WCHAR*)WStr("StackExchange.Redis.ResultProcessor`1[!!0]"),(WCHAR*)WStr("StackExchange.Redis.ServerEndPoint"),}; +WCHAR* sig221[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1"),(WCHAR*)WStr("GraphQL.Execution.ExecutionContext"),}; +WCHAR* sig222[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1"),}; +WCHAR* sig223[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[!!0]"),(WCHAR*)WStr("StackExchange.Redis.Message"),(WCHAR*)WStr("StackExchange.Redis.ResultProcessor`1[!!0]"),(WCHAR*)WStr("System.Object"),(WCHAR*)WStr("StackExchange.Redis.ServerEndPoint"),}; +WCHAR* sig224[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[!!0]"),(WCHAR*)WStr("StackExchange.Redis.Message"),(WCHAR*)WStr("StackExchange.Redis.ResultProcessor`1[!!0]"),(WCHAR*)WStr("System.Object"),(WCHAR*)WStr("StackExchange.Redis.ServerEndPoint"),(WCHAR*)WStr("!!0"),}; +WCHAR* sig225[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[!0]"),(WCHAR*)WStr("Amazon.Runtime.IExecutionContext"),}; +WCHAR* sig226[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[!0]"),(WCHAR*)WStr("Elasticsearch.Net.HttpMethod"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Threading.CancellationToken"),(WCHAR*)WStr("Elasticsearch.Net.PostData"),(WCHAR*)WStr("Elasticsearch.Net.IRequestParameters"),}; +WCHAR* sig227[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[!0]"),(WCHAR*)WStr("Elasticsearch.Net.RequestData"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig228[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[!0]"),(WCHAR*)WStr("GraphQL.Types.ISchema"),(WCHAR*)WStr("GraphQL.Language.AST.Document"),(WCHAR*)WStr("GraphQL.Language.AST.VariableDefinitions"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[GraphQL.Validation.IValidationRule]"),(WCHAR*)WStr("_"),(WCHAR*)WStr("GraphQL.Inputs"),}; +WCHAR* sig229[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[!0]"),(WCHAR*)WStr("GraphQL.Validation.ValidationContext"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[GraphQL.Validation.IValidationRule]"),}; +WCHAR* sig230[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[!0]"),(WCHAR*)WStr("MongoDB.Driver.Core.Connections.IConnection"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig231[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[!0]"),(WCHAR*)WStr("MongoDB.Driver.OperationContext"),(WCHAR*)WStr("MongoDB.Driver.Core.Connections.IConnection"),}; +WCHAR* sig232[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[!0]"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("GraphQL.Types.ISchema"),(WCHAR*)WStr("GraphQL.Language.AST.Document"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[GraphQL.Validation.IValidationRule]"),(WCHAR*)WStr("_"),(WCHAR*)WStr("GraphQL.Inputs"),}; +WCHAR* sig233[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.DynamoDBv2.Model.BatchGetItemResponse]"),(WCHAR*)WStr("Amazon.DynamoDBv2.Model.BatchGetItemRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig234[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.DynamoDBv2.Model.BatchWriteItemResponse]"),(WCHAR*)WStr("Amazon.DynamoDBv2.Model.BatchWriteItemRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig235[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.DynamoDBv2.Model.DeleteItemResponse]"),(WCHAR*)WStr("Amazon.DynamoDBv2.Model.DeleteItemRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig236[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.DynamoDBv2.Model.GetItemResponse]"),(WCHAR*)WStr("Amazon.DynamoDBv2.Model.GetItemRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig237[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.DynamoDBv2.Model.PutItemResponse]"),(WCHAR*)WStr("Amazon.DynamoDBv2.Model.PutItemRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig238[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.DynamoDBv2.Model.ScanResponse]"),(WCHAR*)WStr("Amazon.DynamoDBv2.Model.ScanRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig239[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.DynamoDBv2.Model.UpdateItemResponse]"),(WCHAR*)WStr("Amazon.DynamoDBv2.Model.UpdateItemRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig240[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.EventBridge.Model.PutEventsResponse]"),(WCHAR*)WStr("Amazon.EventBridge.Model.PutEventsRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig241[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.Kinesis.Model.GetRecordsResponse]"),(WCHAR*)WStr("Amazon.Kinesis.Model.GetRecordsRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig242[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.Kinesis.Model.PutRecordResponse]"),(WCHAR*)WStr("Amazon.Kinesis.Model.PutRecordRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig243[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.Kinesis.Model.PutRecordsResponse]"),(WCHAR*)WStr("Amazon.Kinesis.Model.PutRecordsRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig244[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.S3.Model.CompleteMultipartUploadResponse]"),(WCHAR*)WStr("Amazon.S3.Model.CompleteMultipartUploadRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig245[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.S3.Model.CopyObjectResponse]"),(WCHAR*)WStr("Amazon.S3.Model.CopyObjectRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig246[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.S3.Model.DeleteBucketResponse]"),(WCHAR*)WStr("Amazon.S3.Model.DeleteBucketRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig247[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.S3.Model.DeleteObjectResponse]"),(WCHAR*)WStr("Amazon.S3.Model.DeleteObjectRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig248[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.S3.Model.DeleteObjectsResponse]"),(WCHAR*)WStr("Amazon.S3.Model.DeleteObjectsRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig249[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.S3.Model.GetObjectResponse]"),(WCHAR*)WStr("Amazon.S3.Model.GetObjectRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig250[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.S3.Model.InitiateMultipartUploadResponse]"),(WCHAR*)WStr("Amazon.S3.Model.InitiateMultipartUploadRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig251[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.S3.Model.ListBucketsResponse]"),(WCHAR*)WStr("Amazon.S3.Model.ListBucketsRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig252[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.S3.Model.ListObjectsV2Response]"),(WCHAR*)WStr("Amazon.S3.Model.ListObjectsV2Request"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig253[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.S3.Model.PutBucketResponse]"),(WCHAR*)WStr("Amazon.S3.Model.PutBucketRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig254[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.S3.Model.PutObjectResponse]"),(WCHAR*)WStr("Amazon.S3.Model.PutObjectRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig255[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.S3.Model.UploadPartResponse]"),(WCHAR*)WStr("Amazon.S3.Model.UploadPartRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig256[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.SimpleNotificationService.Model.PublishBatchResponse]"),(WCHAR*)WStr("Amazon.SimpleNotificationService.Model.PublishBatchRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig257[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.SimpleNotificationService.Model.PublishResponse]"),(WCHAR*)WStr("Amazon.SimpleNotificationService.Model.PublishRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig258[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.SQS.Model.CreateQueueResponse]"),(WCHAR*)WStr("Amazon.SQS.Model.CreateQueueRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig259[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.SQS.Model.DeleteMessageBatchResponse]"),(WCHAR*)WStr("Amazon.SQS.Model.DeleteMessageBatchRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig260[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.SQS.Model.DeleteMessageResponse]"),(WCHAR*)WStr("Amazon.SQS.Model.DeleteMessageRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig261[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.SQS.Model.DeleteQueueResponse]"),(WCHAR*)WStr("Amazon.SQS.Model.DeleteQueueRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig262[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.SQS.Model.ReceiveMessageResponse]"),(WCHAR*)WStr("Amazon.SQS.Model.ReceiveMessageRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig263[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.SQS.Model.SendMessageBatchResponse]"),(WCHAR*)WStr("Amazon.SQS.Model.SendMessageBatchRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig264[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Amazon.SQS.Model.SendMessageResponse]"),(WCHAR*)WStr("Amazon.SQS.Model.SendMessageRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig265[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Confluent.Kafka.DeliveryReport`2[!0,!1]]"),(WCHAR*)WStr("Confluent.Kafka.TopicPartition"),(WCHAR*)WStr("Confluent.Kafka.Message`2[!0,!1]"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig266[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Elasticsearch.Net.ElasticsearchResponse`1[!0]]"),(WCHAR*)WStr("Elasticsearch.Net.RequestData"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig267[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[HotChocolate.Execution.IExecutionResult]"),(WCHAR*)WStr("HotChocolate.Execution.IOperationRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig268[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[HotChocolate.Execution.IExecutionResult]"),(WCHAR*)WStr("HotChocolate.Execution.IQueryRequest"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig269[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[HotChocolate.Execution.IExecutionResult]"),(WCHAR*)WStr("HotChocolate.Execution.Processing.IOperationContext"),}; +WCHAR* sig270[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[HotChocolate.Execution.IExecutionResult]"),(WCHAR*)WStr("HotChocolate.Execution.Processing.OperationContext"),}; +WCHAR* sig271[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[HotChocolate.Execution.IOperationResult]"),(WCHAR*)WStr("HotChocolate.Execution.Processing.OperationContext"),}; +WCHAR* sig272[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[HotChocolate.Execution.IQueryResult]"),(WCHAR*)WStr("HotChocolate.Execution.Processing.OperationContext"),}; +WCHAR* sig273[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Identity.IdentityResult]"),(WCHAR*)WStr("!0"),}; +WCHAR* sig274[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Identity.SignInResult]"),(WCHAR*)WStr("!0"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Boolean"),}; +WCHAR* sig275[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Identity.SignInResult]"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Boolean"),}; +WCHAR* sig276[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ResponseMessage]"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("Microsoft.Azure.Documents.ResourceType"),(WCHAR*)WStr("Microsoft.Azure.Documents.OperationType"),(WCHAR*)WStr("Microsoft.Azure.Cosmos.RequestOptions"),(WCHAR*)WStr("Microsoft.Azure.Cosmos.ContainerInternal"),(WCHAR*)WStr("_"),(WCHAR*)WStr("System.IO.Stream"),(WCHAR*)WStr("System.Action`1[Microsoft.Azure.Cosmos.RequestMessage]"),(WCHAR*)WStr("_"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig277[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.Azure.WebJobs.Host.Executors.IDelayedException]"),(WCHAR*)WStr("Microsoft.Azure.WebJobs.Host.Executors.IFunctionInstance"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig278[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.Azure.WebJobs.Script.Grpc.Messages.TypedData]"),(WCHAR*)WStr("Microsoft.AspNetCore.Http.HttpRequest"),(WCHAR*)WStr("Microsoft.Extensions.Logging.ILogger"),(WCHAR*)WStr("Microsoft.Azure.WebJobs.Script.Grpc.GrpcCapabilities"),}; +WCHAR* sig279[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.Data.SqlClient.SqlDataReader]"),}; +WCHAR* sig280[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.Data.SqlClient.SqlDataReader]"),(WCHAR*)WStr("System.Data.CommandBehavior"),}; +WCHAR* sig281[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.Data.SqlClient.SqlDataReader]"),(WCHAR*)WStr("System.Data.CommandBehavior"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig282[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.Data.SqlClient.SqlDataReader]"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig283[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.Data.Sqlite.SqliteDataReader]"),(WCHAR*)WStr("System.Data.CommandBehavior"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig284[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.VisualStudio.TestTools.UnitTesting.TestResult[]]"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestMethodInfo"),}; +WCHAR* sig285[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.VisualStudio.TestTools.UnitTesting.TestResult[]]"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel.TestMethod"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.Object]"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging.IMessageLogger"),}; +WCHAR* sig286[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.VisualStudio.TestTools.UnitTesting.TestResult[]]"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel.UnitTestElement"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.Object]"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging.IMessageLogger"),}; +WCHAR* sig287[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.VisualStudio.TestTools.UnitTesting.TestResult[]]"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel.UnitTestElement"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.Object]"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.Object]"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging.IMessageLogger"),}; +WCHAR* sig288[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.VisualStudio.TestTools.UnitTesting.TestResult[]]"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestContext"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestMethodInfo"),}; +WCHAR* sig289[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Microsoft.VisualStudio.TestTools.UnitTesting.TestResult[]]"),(WCHAR*)WStr("Microsoft.VisualStudio.TestTools.UnitTesting.ITestMethod"),}; +WCHAR* sig290[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[MySql.Data.MySqlClient.MySqlDataReader]"),(WCHAR*)WStr("System.Data.CommandBehavior"),}; +WCHAR* sig291[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[MySql.Data.MySqlClient.MySqlDataReader]"),(WCHAR*)WStr("System.Data.CommandBehavior"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig292[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[MySqlConnector.MySqlDataReader]"),(WCHAR*)WStr("System.Data.CommandBehavior"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig293[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[MySqlConnector.MySqlDataReader]"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig294[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Npgsql.NpgsqlDataReader]"),(WCHAR*)WStr("System.Data.CommandBehavior"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig295[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Oracle.DataAccess.Client.OracleDataReader]"),}; +WCHAR* sig296[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Oracle.DataAccess.Client.OracleDataReader]"),(WCHAR*)WStr("System.Data.CommandBehavior"),}; +WCHAR* sig297[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Oracle.DataAccess.Client.OracleDataReader]"),(WCHAR*)WStr("System.Data.CommandBehavior"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig298[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Oracle.DataAccess.Client.OracleDataReader]"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig299[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Oracle.ManagedDataAccess.Client.OracleDataReader]"),}; +WCHAR* sig300[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Oracle.ManagedDataAccess.Client.OracleDataReader]"),(WCHAR*)WStr("System.Data.CommandBehavior"),}; +WCHAR* sig301[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Oracle.ManagedDataAccess.Client.OracleDataReader]"),(WCHAR*)WStr("System.Data.CommandBehavior"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig302[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Oracle.ManagedDataAccess.Client.OracleDataReader]"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig303[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[RabbitMQ.Client.BasicGetResult]"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig304[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[RabbitMQ.Client.QueueDeclareOk]"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.Object]"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig305[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[System.Collections.Generic.IReadOnlyList`1[Azure.Messaging.EventHubs.EventData]]"),(WCHAR*)WStr("System.Int32"),(WCHAR*)WStr("System.Nullable`1[System.TimeSpan]"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig306[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[System.Collections.Generic.IReadOnlyList`1[Azure.Messaging.ServiceBus.ServiceBusReceivedMessage]]"),(WCHAR*)WStr("System.Int32"),(WCHAR*)WStr("System.Nullable`1[System.TimeSpan]"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig307[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[System.Collections.Generic.IReadOnlyList`1[System.Int64]]"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Azure.Messaging.ServiceBus.ServiceBusMessage]"),(WCHAR*)WStr("System.DateTimeOffset"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig308[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[System.Data.Common.DbDataReader]"),(WCHAR*)WStr("System.Data.CommandBehavior"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig309[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[System.Data.SqlClient.SqlDataReader]"),(WCHAR*)WStr("System.Data.CommandBehavior"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig310[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[System.Decimal]"),}; +WCHAR* sig311[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[System.Int32]"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig312[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[System.Net.Http.HttpResponseMessage]"),(WCHAR*)WStr("System.Net.Http.HttpRequestMessage"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig313[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[System.Net.Http.HttpResponseMessage]"),(WCHAR*)WStr("System.Web.Http.Controllers.HttpControllerContext"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.Object]"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig314[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[System.Net.Http.HttpResponseMessage]"),(WCHAR*)WStr("System.Web.Http.Controllers.HttpControllerContext"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig315[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[System.Net.Http.HttpResponseMessage]"),(WCHAR*)WStr("System.Web.Http.ExceptionHandling.IExceptionHandler"),(WCHAR*)WStr("System.Web.Http.ExceptionHandling.ExceptionContext"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig316[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[System.Object]"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig317[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[System.String]"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.Object]"),(WCHAR*)WStr("RabbitMQ.Client.IAsyncBasicConsumer"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig318[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[System.Tuple`2[System.Object, System.Object[]]]"),(WCHAR*)WStr("System.Object"),(WCHAR*)WStr("System.Object[]"),}; +WCHAR* sig319[]={(WCHAR*)WStr("System.Threading.Tasks.Task`1[Xunit.Sdk.RunSummary]"),}; +WCHAR* sig320[]={(WCHAR*)WStr("System.Threading.Tasks.ValueTask"),(WCHAR*)WStr("RabbitMQ.Client.CachedString"),(WCHAR*)WStr("RabbitMQ.Client.CachedString"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("!!0"),(WCHAR*)WStr("System.ReadOnlyMemory`1[System.Byte]"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig321[]={(WCHAR*)WStr("System.Threading.Tasks.ValueTask"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("!!0"),(WCHAR*)WStr("System.ReadOnlyMemory`1[System.Byte]"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig322[]={(WCHAR*)WStr("System.Threading.Tasks.ValueTask`1[System.TimeSpan]"),(WCHAR*)WStr("_"),}; +WCHAR* sig323[]={(WCHAR*)WStr("System.Threading.Tasks.ValueTask`1[Xunit.v3.RunSummary]"),(WCHAR*)WStr("!0"),}; +WCHAR* sig324[]={(WCHAR*)WStr("System.Threading.Tasks.ValueTask`1[Xunit.v3.RunSummary]"),(WCHAR*)WStr("!0"),(WCHAR*)WStr("!2"),}; +WCHAR* sig325[]={(WCHAR*)WStr("System.Uri"),}; +WCHAR* sig326[]={(WCHAR*)WStr("System.Void"),}; +WCHAR* sig327[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("!!0"),(WCHAR*)WStr("System.Action`3[!!0,System.String,System.String]"),(WCHAR*)WStr("Datadog.Trace.ISpanContext"),}; +WCHAR* sig328[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("!!0"),(WCHAR*)WStr("System.Action`3[!!0,System.String,System.String]"),(WCHAR*)WStr("Datadog.Trace.ISpanContext"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),}; +WCHAR* sig329[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Amazon.Lambda.RuntimeSupport.LambdaBootstrapHandler"),}; +WCHAR* sig330[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Confluent.Kafka.ConsumerBuilder`2[!0,!1]"),}; +WCHAR* sig331[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Confluent.Kafka.ProducerBuilder`2[!0,!1]"),}; +WCHAR* sig332[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Confluent.Kafka.TopicPartition"),(WCHAR*)WStr("Confluent.Kafka.Message`2[!0,!1]"),(WCHAR*)WStr("System.Action`1[Confluent.Kafka.DeliveryReport`2[!0,!1]]"),}; +WCHAR* sig333[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Datadog.Trace.Ci.ITest"),(WCHAR*)WStr("Datadog.Trace.Ci.BenchmarkHostInfo&"),(WCHAR*)WStr("Datadog.Trace.Ci.BenchmarkJobInfo&"),}; +WCHAR* sig334[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Datadog.Trace.Ci.ITest"),(WCHAR*)WStr("Datadog.Trace.Ci.BenchmarkMeasureType"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("Datadog.Trace.Ci.BenchmarkDiscreteStats&"),}; +WCHAR* sig335[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Datadog.Trace.Ci.ITest"),(WCHAR*)WStr("Datadog.Trace.Ci.TestParameters"),}; +WCHAR* sig336[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Datadog.Trace.ISpan"),(WCHAR*)WStr("Datadog.Trace.SamplingPriority"),}; +WCHAR* sig337[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Datadog.Trace.ISpan"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),}; +WCHAR* sig338[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Google.Protobuf.CodedInputStream"),}; +WCHAR* sig339[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Google.Protobuf.CodedOutputStream"),}; +WCHAR* sig340[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Google.Protobuf.ParseContext&"),}; +WCHAR* sig341[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Google.Protobuf.WriteContext&"),}; +WCHAR* sig342[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("IBM.WMQ.MQMessage"),(WCHAR*)WStr("IBM.WMQ.MQGetMessageOptions"),(WCHAR*)WStr("System.Int32"),}; +WCHAR* sig343[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("IBM.WMQ.MQMessage"),(WCHAR*)WStr("IBM.WMQ.MQPutMessageOptions"),}; +WCHAR* sig344[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Microsoft.AspNetCore.Builder.IApplicationBuilder"),(WCHAR*)WStr("Microsoft.AspNetCore.Http.RequestDelegate"),}; +WCHAR* sig345[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Microsoft.AspNetCore.Http.HttpResponse"),(WCHAR*)WStr("System.Int32"),(WCHAR*)WStr("Grpc.Core.StatusCode"),(WCHAR*)WStr("System.String"),}; +WCHAR* sig346[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingResult"),}; +WCHAR* sig347[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Microsoft.VisualStudio.TestTools.UnitTesting.TestContext"),}; +WCHAR* sig348[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Microsoft.VisualStudio.TestTools.UnitTesting.TestContext"),(WCHAR*)WStr("_"),}; +WCHAR* sig349[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("MongoDB.Driver.Core.Connections.IConnection"),(WCHAR*)WStr("System.Threading.CancellationToken"),}; +WCHAR* sig350[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("NLog.Config.LoggingConfiguration"),}; +WCHAR* sig351[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("NUnit.Framework.Internal.TestMethod"),(WCHAR*)WStr("NUnit.Framework.Interfaces.ITestFilter"),}; +WCHAR* sig352[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("NUnit.Framework.Internal.TestMethod"),(WCHAR*)WStr("NUnit.Framework.Interfaces.ITestFilter"),(WCHAR*)WStr("NUnit.Framework.Internal.Abstractions.IDebugger"),}; +WCHAR* sig353[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("OpenQA.Selenium.Remote.SendingRemoteHttpRequestEventArgs"),}; +WCHAR* sig354[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("OpenTelemetry.Baggage"),}; +WCHAR* sig355[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Serilog.Events.LogEvent"),}; +WCHAR* sig356[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Action"),}; +WCHAR* sig357[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Action`2[System.Object,!!0]"),(WCHAR*)WStr("!!0"),}; +WCHAR* sig358[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Boolean"),}; +WCHAR* sig359[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("Grpc.Core.Internal.ClientSideStatus"),}; +WCHAR* sig360[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("Grpc.Core.Internal.ClientSideStatus"),(WCHAR*)WStr("Grpc.Core.Internal.IBufferReader"),(WCHAR*)WStr("Grpc.Core.Metadata"),}; +WCHAR* sig361[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.Dictionary`2[System.String,System.Object]"),}; +WCHAR* sig362[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.Dictionary`2[System.String,System.Object]"),(WCHAR*)WStr("System.Boolean"),}; +WCHAR* sig363[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.ICollection`1[System.Reflection.MethodInfo]"),(WCHAR*)WStr("System.Func`1[System.IDisposable]"),}; +WCHAR* sig364[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.Object]"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String&"),(WCHAR*)WStr("System.String&"),}; +WCHAR* sig365[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.String]"),}; +WCHAR* sig366[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Confluent.Kafka.TopicPartitionOffset]"),}; +WCHAR* sig367[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Microsoft.Extensions.Logging.ILoggerProvider]"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.Extensions.Logging.LoggerFilterOptions]"),}; +WCHAR* sig368[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Microsoft.Extensions.Logging.ILoggerProvider]"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.Extensions.Logging.LoggerFilterOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptions`1[Microsoft.Extensions.Logging.LoggerFactoryOptions]"),}; +WCHAR* sig369[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Microsoft.Extensions.Logging.ILoggerProvider]"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.Extensions.Logging.LoggerFilterOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptions`1[Microsoft.Extensions.Logging.LoggerFactoryOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Logging.IExternalScopeProvider"),}; +WCHAR* sig370[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Microsoft.Extensions.Logging.ILoggerProvider]"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Microsoft.Extensions.Diagnostics.Enrichment.ILogEnricher]"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Microsoft.Extensions.Diagnostics.Enrichment.IStaticLogEnricher]"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.Extensions.Logging.LoggerFilterOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Logging.LoggingSampler"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptions`1[Microsoft.Extensions.Logging.LoggerFactoryOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Logging.IExternalScopeProvider"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.Extensions.Logging.LoggerEnrichmentOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.Extensions.Logging.LoggerRedactionOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Compliance.Redaction.IRedactorProvider"),}; +WCHAR* sig371[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Microsoft.Extensions.Logging.ILoggerProvider]"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Microsoft.Extensions.Diagnostics.Enrichment.ILogEnricher]"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Microsoft.Extensions.Diagnostics.Enrichment.IStaticLogEnricher]"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.Extensions.Logging.LoggerFilterOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Logging.LoggingSampler"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptions`1[Microsoft.Extensions.Logging.LoggerFactoryOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Logging.IExternalScopeProvider"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.Extensions.Logging.LoggerEnrichmentOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.Extensions.Logging.LoggerRedactionOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Compliance.Redaction.IRedactorProvider"),(WCHAR*)WStr("Microsoft.Extensions.Diagnostics.Buffering.LogBuffer"),}; +WCHAR* sig372[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Microsoft.Extensions.Logging.ILoggerProvider]"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Microsoft.Extensions.Diagnostics.Enrichment.ILogEnricher]"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Microsoft.Extensions.Diagnostics.Enrichment.IStaticLogEnricher]"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.Extensions.Logging.LoggerFilterOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptions`1[Microsoft.Extensions.Logging.LoggerFactoryOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Logging.IExternalScopeProvider"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.Extensions.Logging.LoggerEnrichmentOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Options.IOptionsMonitor`1[Microsoft.Extensions.Logging.LoggerRedactionOptions]"),(WCHAR*)WStr("Microsoft.Extensions.Compliance.Redaction.IRedactorProvider"),}; +WCHAR* sig373[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel.UnitTestElement]"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter.ITestCaseDiscoverySink"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter.IDiscoveryContext"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging.IMessageLogger"),}; +WCHAR* sig374[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[System.String]"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.String"),}; +WCHAR* sig375[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[System.String]"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[System.String]"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[System.String]"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.String"),}; +WCHAR* sig376[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Exception"),(WCHAR*)WStr("System.Boolean"),}; +WCHAR* sig377[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.IO.Stream"),(WCHAR*)WStr("System.Object"),}; +WCHAR* sig378[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Net.Http.HttpRequestMessage"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Diagnostics.Activity"),(WCHAR*)WStr("Grpc.Core.Status"),}; +WCHAR* sig379[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Net.Http.HttpRequestMessage"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Diagnostics.Activity"),(WCHAR*)WStr("System.Nullable`1[Grpc.Core.Status]"),}; +WCHAR* sig380[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Net.HttpWebResponse"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.ITransportHeaders&"),(WCHAR*)WStr("System.IO.Stream&"),}; +WCHAR* sig381[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Net.WebException"),(WCHAR*)WStr("System.Net.HttpWebResponse&"),}; +WCHAR* sig382[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Nullable`1[System.Int64]"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Object"),}; +WCHAR* sig383[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Object"),(WCHAR*)WStr("System.Collections.Generic.Dictionary`2[System.String,System.Object]"),}; +WCHAR* sig384[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Object"),(WCHAR*)WStr("System.Messaging.MessageQueueTransaction"),(WCHAR*)WStr("System.Messaging.MessageQueueTransactionType"),}; +WCHAR* sig385[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.IServerResponseChannelSinkStack"),(WCHAR*)WStr("System.Runtime.Remoting.Messaging.IMessage"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.ITransportHeaders&"),(WCHAR*)WStr("System.IO.Stream&"),}; +WCHAR* sig386[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.IServerResponseChannelSinkStack"),(WCHAR*)WStr("System.Runtime.Remoting.Messaging.IMessage"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.ITransportHeaders&"),(WCHAR*)WStr("System.IO.Stream&"),}; +WCHAR* sig387[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Runtime.Remoting.Messaging.IMessage"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.ITransportHeaders"),(WCHAR*)WStr("System.IO.Stream"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.ITransportHeaders&"),(WCHAR*)WStr("System.IO.Stream&"),}; +WCHAR* sig388[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.ServiceModel.Dispatcher.MessageRpc&"),}; +WCHAR* sig389[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.ServiceModel.Dispatcher.MessageRpc&"),(WCHAR*)WStr("System.Exception&"),(WCHAR*)WStr("System.Boolean&"),}; +WCHAR* sig390[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),}; +WCHAR* sig391[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("!0"),(WCHAR*)WStr("!1"),(WCHAR*)WStr("System.Action`1[Confluent.Kafka.DeliveryReport`2[!0,!1]]"),}; +WCHAR* sig392[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("Datadog.Trace.UserDetails"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.String]"),}; +WCHAR* sig393[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("NLog.Config.LoggingConfiguration"),}; +WCHAR* sig394[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),}; +WCHAR* sig395[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("Datadog.Trace.UserDetails"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.String]"),}; +WCHAR* sig396[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.Object]"),}; +WCHAR* sig397[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.String]"),}; +WCHAR* sig398[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.String]"),}; +WCHAR* sig399[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.String]"),}; +WCHAR* sig400[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Collections.Generic.IEnumerable`1[Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel.UnitTestElement]"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter.ITestCaseDiscoverySink"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter.IDiscoveryContext"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging.IMessageLogger"),}; +WCHAR* sig401[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),}; +WCHAR* sig402[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("RabbitMQ.Client.IBasicProperties"),(WCHAR*)WStr("_"),}; +WCHAR* sig403[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.Object]"),}; +WCHAR* sig404[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.String]"),}; +WCHAR* sig405[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.Object]"),}; +WCHAR* sig406[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.UInt64"),(WCHAR*)WStr("System.Boolean"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("System.String"),(WCHAR*)WStr("RabbitMQ.Client.IBasicProperties"),(WCHAR*)WStr("_"),}; +WCHAR* sig407[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.TimeSpan"),}; +WCHAR* sig408[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Type"),(WCHAR*)WStr("NLog.Internal.TargetWithFilterChain"),(WCHAR*)WStr("NLog.LogEventInfo"),(WCHAR*)WStr("NLog.LogFactory"),}; +WCHAR* sig409[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Xml.XmlDictionaryWriter"),(WCHAR*)WStr("System.Object"),}; +WCHAR* sig410[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("System.Xml.XmlWriter"),(WCHAR*)WStr("System.Object"),}; +WCHAR* sig411[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Xunit.v3.IXunitTestMethod"),(WCHAR*)WStr("System.Collections.Generic.IReadOnlyCollection`1[Xunit.v3.IXunitTestCase]"),(WCHAR*)WStr("Xunit.Sdk.ExplicitOption"),(WCHAR*)WStr("Xunit.v3.IMessageBus"),(WCHAR*)WStr("Xunit.v3.ExceptionAggregator"),(WCHAR*)WStr("System.Threading.CancellationTokenSource"),(WCHAR*)WStr("System.Object[]"),}; +WCHAR* sig412[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("Yarp.ReverseProxy.Forwarder.ForwarderHttpClientContext"),(WCHAR*)WStr("System.Net.Http.SocketsHttpHandler"),}; +WCHAR* sig413[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("_"),}; +WCHAR* sig414[]={(WCHAR*)WStr("System.Void"),(WCHAR*)WStr("_"),(WCHAR*)WStr("_"),}; +WCHAR* sig415[]={(WCHAR*)WStr("System.Web.Mvc.ActionResult"),(WCHAR*)WStr("System.Web.Mvc.ControllerContext"),(WCHAR*)WStr("System.Web.Mvc.ActionDescriptor"),(WCHAR*)WStr("System.Collections.Generic.IDictionary`2[System.String,System.Object]"),}; +WCHAR* sig416[]={(WCHAR*)WStr("_"),(WCHAR*)WStr("_"),}; +WCHAR* sig417[]={(WCHAR*)WStr("_"),(WCHAR*)WStr("_"),(WCHAR*)WStr("_"),}; std::vector callTargets = { {(WCHAR*)WStr("netstandard"),(WCHAR*)WStr("System.Data.Common.DbCommand"),(WCHAR*)WStr("ExecuteDbDataReader"),sig143,2,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Derived,1,15}, {(WCHAR*)WStr("netstandard"),(WCHAR*)WStr("System.Data.Common.DbCommand"),(WCHAR*)WStr("ExecuteNonQuery"),sig154,1,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryIntegration"),CallTargetKind::Derived,1,15}, {(WCHAR*)WStr("netstandard"),(WCHAR*)WStr("System.Data.Common.DbCommand"),(WCHAR*)WStr("ExecuteScalar"),sig170,1,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarIntegration"),CallTargetKind::Derived,1,15}, -{(WCHAR*)WStr("netstandard"),(WCHAR*)WStr("System.Data.Common.DbDataReader"),(WCHAR*)WStr("Close"),sig325,1,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("netstandard"),(WCHAR*)WStr("System.Data.Common.DbDataReader"),(WCHAR*)WStr("Close"),sig326,1,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("netstandard"),(WCHAR*)WStr("System.Data.Common.DbDataReader"),(WCHAR*)WStr("GetString"),sig179,2,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("netstandard"),(WCHAR*)WStr("System.Data.Common.DbDataReader"),(WCHAR*)WStr("GetValue"),sig172,2,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("netstandard"),(WCHAR*)WStr("System.Data.Common.DbDataReader"),(WCHAR*)WStr("Read"),sig129,1,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadIntegration"),CallTargetKind::Default,4,15}, -{(WCHAR*)WStr("netstandard"),(WCHAR*)WStr("System.Data.Common.DbDataReader"),(WCHAR*)WStr("ReadAsync"),sig315,2,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("netstandard"),(WCHAR*)WStr("System.Data.Common.DbDataReader"),(WCHAR*)WStr("ReadAsync"),sig316,2,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.Common.DbCommand"),(WCHAR*)WStr("ExecuteDbDataReader"),sig143,2,2,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Derived,1,15}, -{(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.Common.DbCommand"),(WCHAR*)WStr("ExecuteDbDataReaderAsync"),sig307,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.Common.DbCommand"),(WCHAR*)WStr("ExecuteDbDataReaderAsync"),sig308,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.Common.DbCommand"),(WCHAR*)WStr("ExecuteNonQuery"),sig154,1,2,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryIntegration"),CallTargetKind::Derived,1,15}, -{(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.Common.DbCommand"),(WCHAR*)WStr("ExecuteNonQueryAsync"),sig310,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.Common.DbCommand"),(WCHAR*)WStr("ExecuteNonQueryAsync"),sig311,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.Common.DbCommand"),(WCHAR*)WStr("ExecuteScalar"),sig170,1,2,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarIntegration"),CallTargetKind::Derived,1,15}, -{(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.Common.DbCommand"),(WCHAR*)WStr("ExecuteScalarAsync"),sig315,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.Common.DbDataReader"),(WCHAR*)WStr("Close"),sig325,1,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, -{(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.Common.DbDataReader"),(WCHAR*)WStr("Close"),sig325,1,2,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.Common.DbCommand"),(WCHAR*)WStr("ExecuteScalarAsync"),sig316,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.Common.DbDataReader"),(WCHAR*)WStr("Close"),sig326,1,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.Common.DbDataReader"),(WCHAR*)WStr("Close"),sig326,1,2,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.Common.DbDataReader"),(WCHAR*)WStr("GetString"),sig179,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.Common.DbDataReader"),(WCHAR*)WStr("GetString"),sig179,2,2,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.Common.DbDataReader"),(WCHAR*)WStr("GetValue"),sig172,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.Common.DbDataReader"),(WCHAR*)WStr("GetValue"),sig172,2,2,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.Common.DbDataReader"),(WCHAR*)WStr("Read"),sig129,1,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.Common.DbDataReader"),(WCHAR*)WStr("Read"),sig129,1,2,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadIntegration"),CallTargetKind::Default,4,15}, -{(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.Common.DbDataReader"),(WCHAR*)WStr("ReadAsync"),sig315,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, -{(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.Common.DbDataReader"),(WCHAR*)WStr("ReadAsync"),sig315,2,2,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.Common.DbDataReader"),(WCHAR*)WStr("ReadAsync"),sig316,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.Common.DbDataReader"),(WCHAR*)WStr("ReadAsync"),sig316,2,2,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("System.Data.Common"),(WCHAR*)WStr("System.Data.Common.DbCommand"),(WCHAR*)WStr("ExecuteDbDataReader"),sig143,2,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Derived,1,15}, -{(WCHAR*)WStr("System.Data.Common"),(WCHAR*)WStr("System.Data.Common.DbCommand"),(WCHAR*)WStr("ExecuteDbDataReaderAsync"),sig307,3,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("System.Data.Common"),(WCHAR*)WStr("System.Data.Common.DbCommand"),(WCHAR*)WStr("ExecuteDbDataReaderAsync"),sig308,3,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("System.Data.Common"),(WCHAR*)WStr("System.Data.Common.DbCommand"),(WCHAR*)WStr("ExecuteNonQuery"),sig154,1,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryIntegration"),CallTargetKind::Derived,1,15}, -{(WCHAR*)WStr("System.Data.Common"),(WCHAR*)WStr("System.Data.Common.DbCommand"),(WCHAR*)WStr("ExecuteNonQueryAsync"),sig310,2,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("System.Data.Common"),(WCHAR*)WStr("System.Data.Common.DbCommand"),(WCHAR*)WStr("ExecuteNonQueryAsync"),sig311,2,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("System.Data.Common"),(WCHAR*)WStr("System.Data.Common.DbCommand"),(WCHAR*)WStr("ExecuteScalar"),sig170,1,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarIntegration"),CallTargetKind::Derived,1,15}, -{(WCHAR*)WStr("System.Data.Common"),(WCHAR*)WStr("System.Data.Common.DbCommand"),(WCHAR*)WStr("ExecuteScalarAsync"),sig315,2,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("System.Data.Common"),(WCHAR*)WStr("System.Data.Common.DbDataReader"),(WCHAR*)WStr("Close"),sig325,1,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("System.Data.Common"),(WCHAR*)WStr("System.Data.Common.DbCommand"),(WCHAR*)WStr("ExecuteScalarAsync"),sig316,2,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("System.Data.Common"),(WCHAR*)WStr("System.Data.Common.DbDataReader"),(WCHAR*)WStr("Close"),sig326,1,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("System.Data.Common"),(WCHAR*)WStr("System.Data.Common.DbDataReader"),(WCHAR*)WStr("GetString"),sig179,2,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("System.Data.Common"),(WCHAR*)WStr("System.Data.Common.DbDataReader"),(WCHAR*)WStr("GetValue"),sig172,2,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("System.Data.Common"),(WCHAR*)WStr("System.Data.Common.DbDataReader"),(WCHAR*)WStr("Read"),sig129,1,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadIntegration"),CallTargetKind::Default,4,15}, -{(WCHAR*)WStr("System.Data.Common"),(WCHAR*)WStr("System.Data.Common.DbDataReader"),(WCHAR*)WStr("ReadAsync"),sig315,2,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, -{(WCHAR*)WStr("AerospikeClient"),(WCHAR*)WStr("Aerospike.Client.AsyncCommand"),(WCHAR*)WStr("ExecuteCommand"),sig325,1,4,0,0,8,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Aerospike.AsyncCommandIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AerospikeClient"),(WCHAR*)WStr("Aerospike.Client.SyncCommand"),(WCHAR*)WStr("ExecuteCommand"),sig325,1,4,0,0,8,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Aerospike.SyncCommandIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("System.Data.Common"),(WCHAR*)WStr("System.Data.Common.DbDataReader"),(WCHAR*)WStr("ReadAsync"),sig316,2,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("AerospikeClient"),(WCHAR*)WStr("Aerospike.Client.AsyncCommand"),(WCHAR*)WStr("ExecuteCommand"),sig326,1,4,0,0,8,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Aerospike.AsyncCommandIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AerospikeClient"),(WCHAR*)WStr("Aerospike.Client.SyncCommand"),(WCHAR*)WStr("ExecuteCommand"),sig326,1,4,0,0,8,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Aerospike.SyncCommandIntegration"),CallTargetKind::Default,1,15}, #if _WIN32 -{(WCHAR*)WStr("System.Runtime.Serialization"),(WCHAR*)WStr("System.Runtime.Serialization.Json.DataContractJsonSerializer"),(WCHAR*)WStr("WriteObject"),sig408,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNet.DataContractJsonSerializer_WriteObject_XmlDictionaryWriter_Integration"),CallTargetKind::Default,2,1}, -{(WCHAR*)WStr("System.Runtime.Serialization"),(WCHAR*)WStr("System.Runtime.Serialization.XmlObjectSerializer"),(WCHAR*)WStr("WriteObject"),sig376,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNet.DataContractJsonSerializer_WriteObject_Integration"),CallTargetKind::Derived,2,1}, -{(WCHAR*)WStr("System.Runtime.Serialization"),(WCHAR*)WStr("System.Runtime.Serialization.XmlObjectSerializer"),(WCHAR*)WStr("WriteObject"),sig409,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNet.DataContractJsonSerializer_WriteObject_XmlWriter_Integration"),CallTargetKind::Derived,2,1}, -{(WCHAR*)WStr("System.Web"),(WCHAR*)WStr("System.Web.Compilation.BuildManager"),(WCHAR*)WStr("InvokePreStartInitMethodsCore"),sig362,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNet.HttpModule_Integration"),CallTargetKind::Default,1,1}, -{(WCHAR*)WStr("System.Web"),(WCHAR*)WStr("System.Web.ThreadContext"),(WCHAR*)WStr("AssociateWithCurrentThread"),sig357,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNet.ThreadContext_AssociateWithCurrentThread_Integration"),CallTargetKind::Default,1,1}, -{(WCHAR*)WStr("System.Web"),(WCHAR*)WStr("System.Web.ThreadContext"),(WCHAR*)WStr("DisassociateFromCurrentThread"),sig325,1,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNet.ThreadContext_DisassociateFromCurrentThread_Integration"),CallTargetKind::Default,1,1}, +{(WCHAR*)WStr("System.Runtime.Serialization"),(WCHAR*)WStr("System.Runtime.Serialization.Json.DataContractJsonSerializer"),(WCHAR*)WStr("WriteObject"),sig409,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNet.DataContractJsonSerializer_WriteObject_XmlDictionaryWriter_Integration"),CallTargetKind::Default,2,1}, +{(WCHAR*)WStr("System.Runtime.Serialization"),(WCHAR*)WStr("System.Runtime.Serialization.XmlObjectSerializer"),(WCHAR*)WStr("WriteObject"),sig377,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNet.DataContractJsonSerializer_WriteObject_Integration"),CallTargetKind::Derived,2,1}, +{(WCHAR*)WStr("System.Runtime.Serialization"),(WCHAR*)WStr("System.Runtime.Serialization.XmlObjectSerializer"),(WCHAR*)WStr("WriteObject"),sig410,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNet.DataContractJsonSerializer_WriteObject_XmlWriter_Integration"),CallTargetKind::Derived,2,1}, +{(WCHAR*)WStr("System.Web"),(WCHAR*)WStr("System.Web.Compilation.BuildManager"),(WCHAR*)WStr("InvokePreStartInitMethodsCore"),sig363,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNet.HttpModule_Integration"),CallTargetKind::Default,1,1}, +{(WCHAR*)WStr("System.Web"),(WCHAR*)WStr("System.Web.ThreadContext"),(WCHAR*)WStr("AssociateWithCurrentThread"),sig358,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNet.ThreadContext_AssociateWithCurrentThread_Integration"),CallTargetKind::Default,1,1}, +{(WCHAR*)WStr("System.Web"),(WCHAR*)WStr("System.Web.ThreadContext"),(WCHAR*)WStr("DisassociateFromCurrentThread"),sig326,1,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNet.ThreadContext_DisassociateFromCurrentThread_Integration"),CallTargetKind::Default,1,1}, #endif {(WCHAR*)WStr("Microsoft.AspNetCore.Authentication.Abstractions"),(WCHAR*)WStr("Microsoft.AspNetCore.Authentication.AuthenticationHttpContextExtensions"),(WCHAR*)WStr("SignInAsync"),sig204,5,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.UserEvents.AuthenticationHttpContextExtensionsIntegration"),CallTargetKind::Default,1,14}, {(WCHAR*)WStr("Microsoft.AspNetCore.Http"),(WCHAR*)WStr("Microsoft.AspNetCore.Builder.ApplicationBuilder"),(WCHAR*)WStr("Build"),sig079,1,3,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.AspNetCoreBlockMiddlewareIntegrationEnd"),CallTargetKind::Default,1,14}, @@ -486,122 +487,122 @@ std::vector callTargets = {(WCHAR*)WStr("Microsoft.AspNetCore.Http"),(WCHAR*)WStr("Microsoft.AspNetCore.Http.DefaultHttpContext"),(WCHAR*)WStr("set_User"),sig212,2,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.UserEvents.HttpContextSetUser"),CallTargetKind::Default,2,14}, {(WCHAR*)WStr("Microsoft.AspNetCore.Http.Abstractions"),(WCHAR*)WStr("Microsoft.AspNetCore.Builder.MapExtensions"),(WCHAR*)WStr("Map"),sig077,4,2,2,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.EndpointsCollection.MapExtensionsMapIntegrationV2V3"),CallTargetKind::Default,1,14}, {(WCHAR*)WStr("Microsoft.AspNetCore.Http.Abstractions"),(WCHAR*)WStr("Microsoft.AspNetCore.Builder.MapExtensions"),(WCHAR*)WStr("Map"),sig078,5,5,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.EndpointsCollection.MapExtensionsMapIntegrationV5Plus"),CallTargetKind::Default,1,14}, -{(WCHAR*)WStr("Microsoft.AspNetCore.Http.Abstractions"),(WCHAR*)WStr("Microsoft.AspNetCore.Builder.RunExtensions"),(WCHAR*)WStr("Run"),sig343,3,2,2,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.EndpointsCollection.RunExtensionsRunIntegration"),CallTargetKind::Default,1,14}, -{(WCHAR*)WStr("Microsoft.AspNetCore.Identity"),(WCHAR*)WStr("Microsoft.AspNetCore.Identity.SignInManager`1"),(WCHAR*)WStr("PasswordSignInAsync"),sig274,5,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.UserEvents.SignInManagerPasswordSignInIntegration"),CallTargetKind::Default,2,14}, -{(WCHAR*)WStr("Microsoft.AspNetCore.Identity"),(WCHAR*)WStr("Microsoft.AspNetCore.Identity.SignInManager`1"),(WCHAR*)WStr("PasswordSignInAsync"),sig274,5,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.UserEvents.SignInManagerPasswordSignInIntegration"),CallTargetKind::Derived,2,14}, -{(WCHAR*)WStr("Microsoft.AspNetCore.Identity"),(WCHAR*)WStr("Microsoft.AspNetCore.Identity.SignInManager`1"),(WCHAR*)WStr("PasswordSignInAsync"),sig273,5,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.UserEvents.SignInManagerPasswordSignInUserIntegration"),CallTargetKind::Default,2,14}, -{(WCHAR*)WStr("Microsoft.AspNetCore.Identity"),(WCHAR*)WStr("Microsoft.AspNetCore.Identity.SignInManager`1"),(WCHAR*)WStr("PasswordSignInAsync"),sig274,5,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.UserEvents.SignInManagerPasswordSignInUserIntegration"),CallTargetKind::Derived,2,14}, -{(WCHAR*)WStr("Microsoft.AspNetCore.Mvc.Core"),(WCHAR*)WStr("Microsoft.AspNetCore.Mvc.ModelBinding.DefaultModelBindingContext"),(WCHAR*)WStr("set_Result"),sig345,2,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.DefaultModelBindingContext_SetResult_Integration"),CallTargetKind::Default,6,14}, -{(WCHAR*)WStr("Microsoft.AspNetCore.Mvc.Core"),(WCHAR*)WStr("Microsoft.AspNetCore.Mvc.ModelBinding.DefaultModelBindingContext"),(WCHAR*)WStr("set_Result"),sig345,2,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.DefaultModelBindingContext_SetResult_Integration"),CallTargetKind::Derived,6,14}, -{(WCHAR*)WStr("Microsoft.AspNetCore.Mvc.Core"),(WCHAR*)WStr("Microsoft.AspNetCore.Mvc.MvcOptions"),(WCHAR*)WStr(".ctor"),sig325,1,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.MvcOptionsIntegration"),CallTargetKind::Default,2,14}, +{(WCHAR*)WStr("Microsoft.AspNetCore.Http.Abstractions"),(WCHAR*)WStr("Microsoft.AspNetCore.Builder.RunExtensions"),(WCHAR*)WStr("Run"),sig344,3,2,2,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.EndpointsCollection.RunExtensionsRunIntegration"),CallTargetKind::Default,1,14}, +{(WCHAR*)WStr("Microsoft.AspNetCore.Identity"),(WCHAR*)WStr("Microsoft.AspNetCore.Identity.SignInManager`1"),(WCHAR*)WStr("PasswordSignInAsync"),sig275,5,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.UserEvents.SignInManagerPasswordSignInIntegration"),CallTargetKind::Default,2,14}, +{(WCHAR*)WStr("Microsoft.AspNetCore.Identity"),(WCHAR*)WStr("Microsoft.AspNetCore.Identity.SignInManager`1"),(WCHAR*)WStr("PasswordSignInAsync"),sig275,5,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.UserEvents.SignInManagerPasswordSignInIntegration"),CallTargetKind::Derived,2,14}, +{(WCHAR*)WStr("Microsoft.AspNetCore.Identity"),(WCHAR*)WStr("Microsoft.AspNetCore.Identity.SignInManager`1"),(WCHAR*)WStr("PasswordSignInAsync"),sig274,5,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.UserEvents.SignInManagerPasswordSignInUserIntegration"),CallTargetKind::Default,2,14}, +{(WCHAR*)WStr("Microsoft.AspNetCore.Identity"),(WCHAR*)WStr("Microsoft.AspNetCore.Identity.SignInManager`1"),(WCHAR*)WStr("PasswordSignInAsync"),sig275,5,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.UserEvents.SignInManagerPasswordSignInUserIntegration"),CallTargetKind::Derived,2,14}, +{(WCHAR*)WStr("Microsoft.AspNetCore.Mvc.Core"),(WCHAR*)WStr("Microsoft.AspNetCore.Mvc.ModelBinding.DefaultModelBindingContext"),(WCHAR*)WStr("set_Result"),sig346,2,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.DefaultModelBindingContext_SetResult_Integration"),CallTargetKind::Default,6,14}, +{(WCHAR*)WStr("Microsoft.AspNetCore.Mvc.Core"),(WCHAR*)WStr("Microsoft.AspNetCore.Mvc.ModelBinding.DefaultModelBindingContext"),(WCHAR*)WStr("set_Result"),sig346,2,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.DefaultModelBindingContext_SetResult_Integration"),CallTargetKind::Derived,6,14}, +{(WCHAR*)WStr("Microsoft.AspNetCore.Mvc.Core"),(WCHAR*)WStr("Microsoft.AspNetCore.Mvc.MvcOptions"),(WCHAR*)WStr(".ctor"),sig326,1,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.MvcOptionsIntegration"),CallTargetKind::Default,2,14}, {(WCHAR*)WStr("Microsoft.AspNetCore.Server.IIS"),(WCHAR*)WStr("Microsoft.AspNetCore.Server.IIS.Core.IISHttpContext"),(WCHAR*)WStr("FireOnStarting"),sig185,1,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.FireOnStartCommon"),CallTargetKind::Default,6,14}, {(WCHAR*)WStr("Microsoft.AspNetCore.Server.Kestrel.Core"),(WCHAR*)WStr("Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol"),(WCHAR*)WStr("FireOnStarting"),sig185,1,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.FireOnStartCommon"),CallTargetKind::Default,6,14}, {(WCHAR*)WStr("Microsoft.AspNetCore.Server.Kestrel.Core"),(WCHAR*)WStr("Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer"),(WCHAR*)WStr("StartAsync"),sig201,3,2,2,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.EndpointsCollection.KestrelServerImplStartAsyncIntegration"),CallTargetKind::Default,1,14}, {(WCHAR*)WStr("Microsoft.AspNetCore.Server.Kestrel.Core"),(WCHAR*)WStr("Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl"),(WCHAR*)WStr("StartAsync"),sig201,3,5,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.EndpointsCollection.KestrelServerImplStartAsyncIntegration"),CallTargetKind::Default,1,14}, -{(WCHAR*)WStr("Microsoft.AspNetCore.Session"),(WCHAR*)WStr("Microsoft.AspNetCore.Builder.SessionOptions"),(WCHAR*)WStr("set_IdleTimeout"),sig406,2,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.Session.SessionOptionsIdleTimeoutIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("Microsoft.AspNetCore.Session"),(WCHAR*)WStr("Microsoft.AspNetCore.Builder.SessionOptions"),(WCHAR*)WStr("set_IdleTimeout"),sig407,2,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.Session.SessionOptionsIdleTimeoutIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("Microsoft.AspNetCore.StaticFiles"),(WCHAR*)WStr("Microsoft.AspNetCore.Builder.DirectoryBrowserExtensions"),(WCHAR*)WStr("UseDirectoryBrowser"),sig075,2,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.StaticFiles.DirectoryBrowserExtensionsUseDirectoryBrowserIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.AspNetCore.StaticFiles"),(WCHAR*)WStr("Microsoft.AspNetCore.Builder.DirectoryBrowserExtensions"),(WCHAR*)WStr("UseDirectoryBrowser"),sig076,3,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.StaticFiles.DirectoryBrowserExtensionsUseDirectoryBrowserIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.Extensions.Identity.Core"),(WCHAR*)WStr("Microsoft.AspNetCore.Identity.UserManager`1"),(WCHAR*)WStr("CreateAsync"),sig272,2,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.UserEvents.UserManagerCreateIntegration"),CallTargetKind::Default,2,14}, -{(WCHAR*)WStr("Microsoft.Extensions.Identity.Core"),(WCHAR*)WStr("Microsoft.AspNetCore.Identity.UserManager`1"),(WCHAR*)WStr("CreateAsync"),sig272,2,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.UserEvents.UserManagerCreateIntegration"),CallTargetKind::Derived,2,14}, +{(WCHAR*)WStr("Microsoft.Extensions.Identity.Core"),(WCHAR*)WStr("Microsoft.AspNetCore.Identity.UserManager`1"),(WCHAR*)WStr("CreateAsync"),sig273,2,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.UserEvents.UserManagerCreateIntegration"),CallTargetKind::Default,2,14}, +{(WCHAR*)WStr("Microsoft.Extensions.Identity.Core"),(WCHAR*)WStr("Microsoft.AspNetCore.Identity.UserManager`1"),(WCHAR*)WStr("CreateAsync"),sig273,2,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.UserEvents.UserManagerCreateIntegration"),CallTargetKind::Derived,2,14}, #if _WIN32 {(WCHAR*)WStr("System.Web.Mvc"),(WCHAR*)WStr("System.Web.Mvc.Async.AsyncControllerActionInvoker"),(WCHAR*)WStr("BeginInvokeAction"),sig153,5,4,0,0,5,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNet.AsyncControllerActionInvoker_BeginInvokeAction_Integration"),CallTargetKind::Default,1,1}, {(WCHAR*)WStr("System.Web.Mvc"),(WCHAR*)WStr("System.Web.Mvc.Async.AsyncControllerActionInvoker"),(WCHAR*)WStr("EndInvokeAction"),sig132,2,4,0,0,5,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNet.AsyncControllerActionInvoker_EndInvokeAction_Integration"),CallTargetKind::Default,1,1}, -{(WCHAR*)WStr("System.Web.Mvc"),(WCHAR*)WStr("System.Web.Mvc.ControllerActionInvoker"),(WCHAR*)WStr("InvokeActionMethod"),sig414,4,4,0,0,5,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNet.ControllerActionInvoker_InvokeAction_Integration"),CallTargetKind::Default,6,1}, -{(WCHAR*)WStr("System.Web.Http"),(WCHAR*)WStr("System.Web.Http.ApiController"),(WCHAR*)WStr("ExecuteAsync"),sig313,3,5,1,0,5,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNet.ApiController_ExecuteAsync_Integration"),CallTargetKind::Default,1,1}, -{(WCHAR*)WStr("System.Web.Http"),(WCHAR*)WStr("System.Web.Http.Controllers.ReflectedHttpActionDescriptor"),(WCHAR*)WStr("ExecuteAsync"),sig312,4,5,1,0,5,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNet.ReflectedHttpActionDescriptor_ExecuteAsync_Integration"),CallTargetKind::Default,6,1}, -{(WCHAR*)WStr("System.Web.Http"),(WCHAR*)WStr("System.Web.Http.ExceptionHandling.ExceptionHandlerExtensions"),(WCHAR*)WStr("HandleAsync"),sig314,4,5,1,0,5,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNet.ExceptionHandlerExtensions_HandleAsync_Integration"),CallTargetKind::Default,1,1}, +{(WCHAR*)WStr("System.Web.Mvc"),(WCHAR*)WStr("System.Web.Mvc.ControllerActionInvoker"),(WCHAR*)WStr("InvokeActionMethod"),sig415,4,4,0,0,5,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNet.ControllerActionInvoker_InvokeAction_Integration"),CallTargetKind::Default,6,1}, +{(WCHAR*)WStr("System.Web.Http"),(WCHAR*)WStr("System.Web.Http.ApiController"),(WCHAR*)WStr("ExecuteAsync"),sig314,3,5,1,0,5,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNet.ApiController_ExecuteAsync_Integration"),CallTargetKind::Default,1,1}, +{(WCHAR*)WStr("System.Web.Http"),(WCHAR*)WStr("System.Web.Http.Controllers.ReflectedHttpActionDescriptor"),(WCHAR*)WStr("ExecuteAsync"),sig313,4,5,1,0,5,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNet.ReflectedHttpActionDescriptor_ExecuteAsync_Integration"),CallTargetKind::Default,6,1}, +{(WCHAR*)WStr("System.Web.Http"),(WCHAR*)WStr("System.Web.Http.ExceptionHandling.ExceptionHandlerExtensions"),(WCHAR*)WStr("HandleAsync"),sig315,4,5,1,0,5,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNet.ExceptionHandlerExtensions_HandleAsync_Integration"),CallTargetKind::Default,1,1}, #endif {(WCHAR*)WStr("AWSSDK.DynamoDBv2"),(WCHAR*)WStr("Amazon.DynamoDBv2.AmazonDynamoDBClient"),(WCHAR*)WStr("BatchGetItem"),sig008,2,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.DynamoDb.BatchGetItemIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.DynamoDBv2"),(WCHAR*)WStr("Amazon.DynamoDBv2.AmazonDynamoDBClient"),(WCHAR*)WStr("BatchGetItemAsync"),sig232,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.DynamoDb.BatchGetItemAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.DynamoDBv2"),(WCHAR*)WStr("Amazon.DynamoDBv2.AmazonDynamoDBClient"),(WCHAR*)WStr("BatchGetItemAsync"),sig233,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.DynamoDb.BatchGetItemAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.DynamoDBv2"),(WCHAR*)WStr("Amazon.DynamoDBv2.AmazonDynamoDBClient"),(WCHAR*)WStr("BatchWriteItem"),sig009,2,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.DynamoDb.BatchWriteItemIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.DynamoDBv2"),(WCHAR*)WStr("Amazon.DynamoDBv2.AmazonDynamoDBClient"),(WCHAR*)WStr("BatchWriteItemAsync"),sig233,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.DynamoDb.BatchWriteItemAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.DynamoDBv2"),(WCHAR*)WStr("Amazon.DynamoDBv2.AmazonDynamoDBClient"),(WCHAR*)WStr("BatchWriteItemAsync"),sig234,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.DynamoDb.BatchWriteItemAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.DynamoDBv2"),(WCHAR*)WStr("Amazon.DynamoDBv2.AmazonDynamoDBClient"),(WCHAR*)WStr("DeleteItem"),sig010,2,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.DynamoDb.DeleteItemIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.DynamoDBv2"),(WCHAR*)WStr("Amazon.DynamoDBv2.AmazonDynamoDBClient"),(WCHAR*)WStr("DeleteItemAsync"),sig234,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.DynamoDb.DeleteItemAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.DynamoDBv2"),(WCHAR*)WStr("Amazon.DynamoDBv2.AmazonDynamoDBClient"),(WCHAR*)WStr("DeleteItemAsync"),sig235,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.DynamoDb.DeleteItemAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.DynamoDBv2"),(WCHAR*)WStr("Amazon.DynamoDBv2.AmazonDynamoDBClient"),(WCHAR*)WStr("GetItem"),sig011,2,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.DynamoDb.GetItemIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.DynamoDBv2"),(WCHAR*)WStr("Amazon.DynamoDBv2.AmazonDynamoDBClient"),(WCHAR*)WStr("GetItemAsync"),sig235,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.DynamoDb.GetItemAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.DynamoDBv2"),(WCHAR*)WStr("Amazon.DynamoDBv2.AmazonDynamoDBClient"),(WCHAR*)WStr("GetItemAsync"),sig236,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.DynamoDb.GetItemAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.DynamoDBv2"),(WCHAR*)WStr("Amazon.DynamoDBv2.AmazonDynamoDBClient"),(WCHAR*)WStr("PutItem"),sig012,2,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.DynamoDb.PutItemIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.DynamoDBv2"),(WCHAR*)WStr("Amazon.DynamoDBv2.AmazonDynamoDBClient"),(WCHAR*)WStr("PutItemAsync"),sig236,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.DynamoDb.PutItemAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.DynamoDBv2"),(WCHAR*)WStr("Amazon.DynamoDBv2.AmazonDynamoDBClient"),(WCHAR*)WStr("PutItemAsync"),sig237,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.DynamoDb.PutItemAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.DynamoDBv2"),(WCHAR*)WStr("Amazon.DynamoDBv2.AmazonDynamoDBClient"),(WCHAR*)WStr("Scan"),sig013,2,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.DynamoDb.ScanIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.DynamoDBv2"),(WCHAR*)WStr("Amazon.DynamoDBv2.AmazonDynamoDBClient"),(WCHAR*)WStr("ScanAsync"),sig237,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.DynamoDb.ScanAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.DynamoDBv2"),(WCHAR*)WStr("Amazon.DynamoDBv2.AmazonDynamoDBClient"),(WCHAR*)WStr("ScanAsync"),sig238,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.DynamoDb.ScanAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.DynamoDBv2"),(WCHAR*)WStr("Amazon.DynamoDBv2.AmazonDynamoDBClient"),(WCHAR*)WStr("UpdateItem"),sig014,2,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.DynamoDb.UpdateItemIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.DynamoDBv2"),(WCHAR*)WStr("Amazon.DynamoDBv2.AmazonDynamoDBClient"),(WCHAR*)WStr("UpdateItemAsync"),sig238,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.DynamoDb.UpdateItemAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.DynamoDBv2"),(WCHAR*)WStr("Amazon.DynamoDBv2.AmazonDynamoDBClient"),(WCHAR*)WStr("UpdateItemAsync"),sig239,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.DynamoDb.UpdateItemAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.EventBridge"),(WCHAR*)WStr("Amazon.EventBridge.AmazonEventBridgeClient"),(WCHAR*)WStr("PutEvents"),sig015,2,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.EventBridge.PutEventsIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.EventBridge"),(WCHAR*)WStr("Amazon.EventBridge.AmazonEventBridgeClient"),(WCHAR*)WStr("PutEventsAsync"),sig239,3,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.EventBridge.PutEventsAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.EventBridge"),(WCHAR*)WStr("Amazon.EventBridge.AmazonEventBridgeClient"),(WCHAR*)WStr("PutEventsAsync"),sig240,3,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.EventBridge.PutEventsAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.Kinesis"),(WCHAR*)WStr("Amazon.Kinesis.AmazonKinesisClient"),(WCHAR*)WStr("GetRecords"),sig016,2,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.Kinesis.GetRecordsIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.Kinesis"),(WCHAR*)WStr("Amazon.Kinesis.AmazonKinesisClient"),(WCHAR*)WStr("GetRecordsAsync"),sig240,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.Kinesis.GetRecordsAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.Kinesis"),(WCHAR*)WStr("Amazon.Kinesis.AmazonKinesisClient"),(WCHAR*)WStr("GetRecordsAsync"),sig241,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.Kinesis.GetRecordsAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.Kinesis"),(WCHAR*)WStr("Amazon.Kinesis.AmazonKinesisClient"),(WCHAR*)WStr("PutRecord"),sig017,2,3,0,0,3,6,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.Kinesis.PutRecordIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.Kinesis"),(WCHAR*)WStr("Amazon.Kinesis.AmazonKinesisClient"),(WCHAR*)WStr("PutRecord"),sig017,2,3,7,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.Kinesis.PutRecordV3_7Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.Kinesis"),(WCHAR*)WStr("Amazon.Kinesis.AmazonKinesisClient"),(WCHAR*)WStr("PutRecordAsync"),sig241,3,3,0,0,3,6,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.Kinesis.PutRecordAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.Kinesis"),(WCHAR*)WStr("Amazon.Kinesis.AmazonKinesisClient"),(WCHAR*)WStr("PutRecordAsync"),sig241,3,3,7,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.Kinesis.PutRecordAsyncV3_7Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.Kinesis"),(WCHAR*)WStr("Amazon.Kinesis.AmazonKinesisClient"),(WCHAR*)WStr("PutRecordAsync"),sig242,3,3,0,0,3,6,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.Kinesis.PutRecordAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.Kinesis"),(WCHAR*)WStr("Amazon.Kinesis.AmazonKinesisClient"),(WCHAR*)WStr("PutRecordAsync"),sig242,3,3,7,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.Kinesis.PutRecordAsyncV3_7Integration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.Kinesis"),(WCHAR*)WStr("Amazon.Kinesis.AmazonKinesisClient"),(WCHAR*)WStr("PutRecords"),sig018,2,3,0,0,3,6,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.Kinesis.PutRecordsIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.Kinesis"),(WCHAR*)WStr("Amazon.Kinesis.AmazonKinesisClient"),(WCHAR*)WStr("PutRecords"),sig018,2,3,7,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.Kinesis.PutRecordsV3_7Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.Kinesis"),(WCHAR*)WStr("Amazon.Kinesis.AmazonKinesisClient"),(WCHAR*)WStr("PutRecordsAsync"),sig242,3,3,0,0,3,6,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.Kinesis.PutRecordsAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.Kinesis"),(WCHAR*)WStr("Amazon.Kinesis.AmazonKinesisClient"),(WCHAR*)WStr("PutRecordsAsync"),sig242,3,3,7,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.Kinesis.PutRecordsAsyncV3_7Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Amazon.Lambda.RuntimeSupport"),(WCHAR*)WStr("Amazon.Lambda.RuntimeSupport.HandlerWrapper"),(WCHAR*)WStr("set_Handler"),sig328,2,1,4,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.Lambda.HandlerWrapperSetHandlerIntegration"),CallTargetKind::Default,1,8}, +{(WCHAR*)WStr("AWSSDK.Kinesis"),(WCHAR*)WStr("Amazon.Kinesis.AmazonKinesisClient"),(WCHAR*)WStr("PutRecordsAsync"),sig243,3,3,0,0,3,6,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.Kinesis.PutRecordsAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.Kinesis"),(WCHAR*)WStr("Amazon.Kinesis.AmazonKinesisClient"),(WCHAR*)WStr("PutRecordsAsync"),sig243,3,3,7,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.Kinesis.PutRecordsAsyncV3_7Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Amazon.Lambda.RuntimeSupport"),(WCHAR*)WStr("Amazon.Lambda.RuntimeSupport.HandlerWrapper"),(WCHAR*)WStr("set_Handler"),sig329,2,1,4,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.Lambda.HandlerWrapperSetHandlerIntegration"),CallTargetKind::Default,1,8}, {(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("CompleteMultipartUpload"),sig021,2,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.MultipartUploadManagement.CompleteMultipartUploadIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("CompleteMultipartUploadAsync"),sig243,3,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.MultipartUploadManagement.CompleteMultipartUploadAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("CompleteMultipartUploadAsync"),sig244,3,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.MultipartUploadManagement.CompleteMultipartUploadAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("CopyObject"),sig022,2,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.ObjectManagement.CopyObjectIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("CopyObjectAsync"),sig244,3,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.ObjectManagement.CopyObjectAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("CopyObjectAsync"),sig245,3,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.ObjectManagement.CopyObjectAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("DeleteBucket"),sig023,2,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.BucketManagement.DeleteBucketIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("DeleteBucketAsync"),sig245,3,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.BucketManagement.DeleteBucketAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("DeleteBucketAsync"),sig246,3,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.BucketManagement.DeleteBucketAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("DeleteObject"),sig024,2,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.ObjectManagement.DeleteObjectIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("DeleteObjectAsync"),sig246,3,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.ObjectManagement.DeleteObjectAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("DeleteObjectAsync"),sig247,3,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.ObjectManagement.DeleteObjectAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("DeleteObjects"),sig025,2,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.ObjectManagement.DeleteObjectsIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("DeleteObjectsAsync"),sig247,3,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.ObjectManagement.DeleteObjectsAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("DeleteObjectsAsync"),sig248,3,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.ObjectManagement.DeleteObjectsAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("GetObject"),sig026,2,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.ObjectManagement.GetObjectIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("GetObjectAsync"),sig248,3,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.ObjectManagement.GetObjectAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("GetObjectAsync"),sig249,3,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.ObjectManagement.GetObjectAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("InitiateMultipartUpload"),sig027,2,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.MultipartUploadManagement.InitiateMultipartUploadIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("InitiateMultipartUploadAsync"),sig249,3,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.MultipartUploadManagement.InitiateMultipartUploadAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("InitiateMultipartUploadAsync"),sig250,3,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.MultipartUploadManagement.InitiateMultipartUploadAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("ListBuckets"),sig028,2,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.BucketManagement.ListBucketsIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("ListBucketsAsync"),sig250,3,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.BucketManagement.ListBucketsAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("ListBucketsAsync"),sig251,3,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.BucketManagement.ListBucketsAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("ListObjectsV2"),sig029,2,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.ObjectManagement.ListObjectsV2Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("ListObjectsV2Async"),sig251,3,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.ObjectManagement.ListObjectsV2AsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("ListObjectsV2Async"),sig252,3,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.ObjectManagement.ListObjectsV2AsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("PutBucket"),sig030,2,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.BucketManagement.PutBucketIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("PutBucketAsync"),sig252,3,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.BucketManagement.PutBucketAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("PutBucketAsync"),sig253,3,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.BucketManagement.PutBucketAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("PutObject"),sig031,2,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.ObjectManagement.PutObjectIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("PutObjectAsync"),sig253,3,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.ObjectManagement.PutObjectAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("PutObjectAsync"),sig254,3,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.ObjectManagement.PutObjectAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("UploadPart"),sig032,2,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.MultipartUploadManagement.UploadPartIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("UploadPartAsync"),sig254,3,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.MultipartUploadManagement.UploadPartAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.S3"),(WCHAR*)WStr("Amazon.S3.AmazonS3Client"),(WCHAR*)WStr("UploadPartAsync"),sig255,3,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.S3.MultipartUploadManagement.UploadPartAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.Core"),(WCHAR*)WStr("Amazon.Runtime.HttpWebRequestMessage"),(WCHAR*)WStr("ProcessHttpResponseMessage"),sig019,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SDK.HttpWebRequestMessageProcessHttpResponseMessageIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.Core"),(WCHAR*)WStr("Amazon.Runtime.Internal.RuntimePipeline"),(WCHAR*)WStr("InvokeAsync"),sig224,2,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SDK.RuntimePipelineInvokeAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.Core"),(WCHAR*)WStr("Amazon.Runtime.Internal.RuntimePipeline"),(WCHAR*)WStr("InvokeAsync"),sig225,2,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SDK.RuntimePipelineInvokeAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.Core"),(WCHAR*)WStr("Amazon.Runtime.Internal.RuntimePipeline"),(WCHAR*)WStr("InvokeSync"),sig020,2,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SDK.RuntimePipelineInvokeSyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.SimpleNotificationService"),(WCHAR*)WStr("Amazon.SimpleNotificationService.AmazonSimpleNotificationServiceClient"),(WCHAR*)WStr("Publish"),sig034,2,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SNS.PublishIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.SimpleNotificationService"),(WCHAR*)WStr("Amazon.SimpleNotificationService.AmazonSimpleNotificationServiceClient"),(WCHAR*)WStr("PublishAsync"),sig256,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SNS.PublishAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.SimpleNotificationService"),(WCHAR*)WStr("Amazon.SimpleNotificationService.AmazonSimpleNotificationServiceClient"),(WCHAR*)WStr("PublishAsync"),sig257,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SNS.PublishAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.SimpleNotificationService"),(WCHAR*)WStr("Amazon.SimpleNotificationService.AmazonSimpleNotificationServiceClient"),(WCHAR*)WStr("PublishBatch"),sig033,2,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SNS.PublishBatchIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.SimpleNotificationService"),(WCHAR*)WStr("Amazon.SimpleNotificationService.AmazonSimpleNotificationServiceClient"),(WCHAR*)WStr("PublishBatchAsync"),sig255,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SNS.PublishBatchAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.SimpleNotificationService"),(WCHAR*)WStr("Amazon.SimpleNotificationService.AmazonSimpleNotificationServiceClient"),(WCHAR*)WStr("PublishBatchAsync"),sig256,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SNS.PublishBatchAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.SQS"),(WCHAR*)WStr("Amazon.SQS.AmazonSQSClient"),(WCHAR*)WStr("CreateQueue"),sig035,2,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SQS.CreateQueueIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.SQS"),(WCHAR*)WStr("Amazon.SQS.AmazonSQSClient"),(WCHAR*)WStr("CreateQueueAsync"),sig257,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SQS.CreateQueueAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.SQS"),(WCHAR*)WStr("Amazon.SQS.AmazonSQSClient"),(WCHAR*)WStr("CreateQueueAsync"),sig258,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SQS.CreateQueueAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.SQS"),(WCHAR*)WStr("Amazon.SQS.AmazonSQSClient"),(WCHAR*)WStr("DeleteMessage"),sig037,2,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SQS.DeleteMessageIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.SQS"),(WCHAR*)WStr("Amazon.SQS.AmazonSQSClient"),(WCHAR*)WStr("DeleteMessageAsync"),sig259,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SQS.DeleteMessageAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.SQS"),(WCHAR*)WStr("Amazon.SQS.AmazonSQSClient"),(WCHAR*)WStr("DeleteMessageAsync"),sig260,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SQS.DeleteMessageAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.SQS"),(WCHAR*)WStr("Amazon.SQS.AmazonSQSClient"),(WCHAR*)WStr("DeleteMessageBatch"),sig036,2,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SQS.DeleteMessageBatchIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.SQS"),(WCHAR*)WStr("Amazon.SQS.AmazonSQSClient"),(WCHAR*)WStr("DeleteMessageBatchAsync"),sig258,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SQS.DeleteMessageBatchAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.SQS"),(WCHAR*)WStr("Amazon.SQS.AmazonSQSClient"),(WCHAR*)WStr("DeleteMessageBatchAsync"),sig259,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SQS.DeleteMessageBatchAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.SQS"),(WCHAR*)WStr("Amazon.SQS.AmazonSQSClient"),(WCHAR*)WStr("DeleteQueue"),sig038,2,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SQS.DeleteQueueIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.SQS"),(WCHAR*)WStr("Amazon.SQS.AmazonSQSClient"),(WCHAR*)WStr("DeleteQueueAsync"),sig260,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SQS.DeleteQueueAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.SQS"),(WCHAR*)WStr("Amazon.SQS.AmazonSQSClient"),(WCHAR*)WStr("DeleteQueueAsync"),sig261,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SQS.DeleteQueueAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.SQS"),(WCHAR*)WStr("Amazon.SQS.AmazonSQSClient"),(WCHAR*)WStr("ReceiveMessage"),sig039,2,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SQS.ReceiveMessageIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.SQS"),(WCHAR*)WStr("Amazon.SQS.AmazonSQSClient"),(WCHAR*)WStr("ReceiveMessageAsync"),sig261,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SQS.ReceiveMessageAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.SQS"),(WCHAR*)WStr("Amazon.SQS.AmazonSQSClient"),(WCHAR*)WStr("ReceiveMessageAsync"),sig262,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SQS.ReceiveMessageAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.SQS"),(WCHAR*)WStr("Amazon.SQS.AmazonSQSClient"),(WCHAR*)WStr("SendMessage"),sig041,2,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SQS.SendMessageIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.SQS"),(WCHAR*)WStr("Amazon.SQS.AmazonSQSClient"),(WCHAR*)WStr("SendMessageAsync"),sig263,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SQS.SendMessageAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.SQS"),(WCHAR*)WStr("Amazon.SQS.AmazonSQSClient"),(WCHAR*)WStr("SendMessageAsync"),sig264,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SQS.SendMessageAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.SQS"),(WCHAR*)WStr("Amazon.SQS.AmazonSQSClient"),(WCHAR*)WStr("SendMessageBatch"),sig040,2,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SQS.SendMessageBatchIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("AWSSDK.SQS"),(WCHAR*)WStr("Amazon.SQS.AmazonSQSClient"),(WCHAR*)WStr("SendMessageBatchAsync"),sig262,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SQS.SendMessageBatchAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("AWSSDK.SQS"),(WCHAR*)WStr("Amazon.SQS.AmazonSQSClient"),(WCHAR*)WStr("SendMessageBatchAsync"),sig263,3,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.SQS.SendMessageBatchAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.StepFunctions"),(WCHAR*)WStr("Amazon.StepFunctions.AmazonStepFunctionsClient"),(WCHAR*)WStr("StartExecution"),sig042,2,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.StepFunctions.StartExecutionIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.StepFunctions"),(WCHAR*)WStr("Amazon.StepFunctions.AmazonStepFunctionsClient"),(WCHAR*)WStr("StartExecutionAsync"),sig043,3,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.StepFunctions.StartExecutionAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.StepFunctions"),(WCHAR*)WStr("Amazon.StepFunctions.AmazonStepFunctionsClient"),(WCHAR*)WStr("StartSyncExecution"),sig044,2,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.StepFunctions.StartSyncExecutionIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("AWSSDK.StepFunctions"),(WCHAR*)WStr("Amazon.StepFunctions.AmazonStepFunctionsClient"),(WCHAR*)WStr("StartSyncExecutionAsync"),sig045,3,3,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AWS.StepFunctions.StartSyncExecutionAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Azure.Messaging.EventHubs"),(WCHAR*)WStr("Azure.Core.Shared.MessagingClientDiagnostics"),(WCHAR*)WStr("InstrumentMessage"),sig363,5,5,9,2,5,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Azure.EventHubs.InstrumentMessageIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Azure.Messaging.EventHubs"),(WCHAR*)WStr("Azure.Messaging.EventHubs.Amqp.AmqpConsumer"),(WCHAR*)WStr("ReceiveAsync"),sig304,4,5,9,2,5,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Azure.EventHubs.AmqpConsumerReceiveAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Azure.Messaging.EventHubs"),(WCHAR*)WStr("Azure.Core.Shared.MessagingClientDiagnostics"),(WCHAR*)WStr("InstrumentMessage"),sig364,5,5,9,2,5,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Azure.EventHubs.InstrumentMessageIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Azure.Messaging.EventHubs"),(WCHAR*)WStr("Azure.Messaging.EventHubs.Amqp.AmqpConsumer"),(WCHAR*)WStr("ReceiveAsync"),sig305,4,5,9,2,5,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Azure.EventHubs.AmqpConsumerReceiveAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Azure.Messaging.EventHubs"),(WCHAR*)WStr("Azure.Messaging.EventHubs.Producer.EventDataBatch"),(WCHAR*)WStr("TryAdd"),sig130,2,5,9,2,5,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Azure.EventHubs.EventDataBatchTryAddIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Azure.Messaging.EventHubs"),(WCHAR*)WStr("Azure.Messaging.EventHubs.Producer.EventHubProducerClient"),(WCHAR*)WStr("SendAsync"),sig186,3,5,9,2,5,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Azure.EventHubs.EventHubProducerClientSendBatchAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Azure.Messaging.EventHubs"),(WCHAR*)WStr("Azure.Messaging.EventHubs.Producer.EventHubProducerClient"),(WCHAR*)WStr("SendAsync"),sig208,3,5,9,2,5,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Azure.EventHubs.EventHubProducerClientSendEnumerableAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.Azure.Functions.Worker.Core"),(WCHAR*)WStr("Microsoft.Azure.Functions.Worker.Pipeline.FunctionExecutionMiddleware"),(WCHAR*)WStr("Invoke"),sig205,2,1,4,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Azure.Functions.FunctionExecutionMiddlewareInvokeIntegration"),CallTargetKind::Default,1,14}, -{(WCHAR*)WStr("Microsoft.Azure.WebJobs.Host"),(WCHAR*)WStr("Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor"),(WCHAR*)WStr("TryExecuteAsync"),sig276,3,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Azure.Functions.AzureFunctionsExecutorTryExecuteAsyncIntegration"),CallTargetKind::Default,1,14}, -{(WCHAR*)WStr("Microsoft.Azure.WebJobs.Script.Grpc"),(WCHAR*)WStr("Microsoft.Azure.WebJobs.Script.Grpc.GrpcMessageConversionExtensions"),(WCHAR*)WStr("ToRpcHttp"),sig277,4,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Azure.Functions.GrpcMessageConversionExtensionsToRpcHttpIntegration"),CallTargetKind::Default,1,14}, +{(WCHAR*)WStr("Microsoft.Azure.WebJobs.Host"),(WCHAR*)WStr("Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor"),(WCHAR*)WStr("TryExecuteAsync"),sig277,3,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Azure.Functions.AzureFunctionsExecutorTryExecuteAsyncIntegration"),CallTargetKind::Default,1,14}, +{(WCHAR*)WStr("Microsoft.Azure.WebJobs.Script.Grpc"),(WCHAR*)WStr("Microsoft.Azure.WebJobs.Script.Grpc.GrpcMessageConversionExtensions"),(WCHAR*)WStr("ToRpcHttp"),sig278,4,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Azure.Functions.GrpcMessageConversionExtensionsToRpcHttpIntegration"),CallTargetKind::Default,1,14}, {(WCHAR*)WStr("Microsoft.Azure.WebJobs.Script.WebHost"),(WCHAR*)WStr("Microsoft.Azure.WebJobs.Script.WebHost.Middleware.FunctionInvocationMiddleware"),(WCHAR*)WStr("Invoke"),sig202,2,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Azure.Functions.FunctionInvocationMiddlewareInvokeIntegration"),CallTargetKind::Default,1,14}, -{(WCHAR*)WStr("Azure.Messaging.ServiceBus"),(WCHAR*)WStr("Azure.Core.Shared.MessagingClientDiagnostics"),(WCHAR*)WStr("InstrumentMessage"),sig363,5,7,14,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Azure.ServiceBus.InstrumentMessageIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Azure.Messaging.ServiceBus"),(WCHAR*)WStr("Azure.Core.Shared.MessagingClientDiagnostics"),(WCHAR*)WStr("InstrumentMessage"),sig364,5,7,14,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Azure.ServiceBus.InstrumentMessageIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Azure.Messaging.ServiceBus"),(WCHAR*)WStr("Azure.Messaging.ServiceBus.ReceiverManager"),(WCHAR*)WStr("ProcessOneMessage"),sig188,3,7,14,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Azure.ServiceBus.ProcessMessageIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Azure.Messaging.ServiceBus"),(WCHAR*)WStr("Azure.Messaging.ServiceBus.ServiceBusMessageBatch"),(WCHAR*)WStr("TryAddMessage"),sig131,2,7,14,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Azure.ServiceBus.SendServiceBusMessageBatchIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Azure.Messaging.ServiceBus"),(WCHAR*)WStr("Azure.Messaging.ServiceBus.ServiceBusReceiver"),(WCHAR*)WStr("ReceiveMessagesAsync"),sig305,5,7,14,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Azure.ServiceBus.ServiceBusReceiverReceiveMessagesAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Azure.Messaging.ServiceBus"),(WCHAR*)WStr("Azure.Messaging.ServiceBus.ServiceBusReceiver"),(WCHAR*)WStr("ReceiveMessagesAsync"),sig306,5,7,14,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Azure.ServiceBus.ServiceBusReceiverReceiveMessagesAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Azure.Messaging.ServiceBus"),(WCHAR*)WStr("Azure.Messaging.ServiceBus.ServiceBusSender"),(WCHAR*)WStr("CreateDiagnosticScope"),sig046,4,7,14,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Azure.ServiceBus.SendServiceBusMessagesIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Azure.Messaging.ServiceBus"),(WCHAR*)WStr("Azure.Messaging.ServiceBus.ServiceBusSender"),(WCHAR*)WStr("ScheduleMessagesAsync"),sig306,4,7,14,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Azure.ServiceBus.ServiceBusSenderScheduleMessagesAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Azure.Messaging.ServiceBus"),(WCHAR*)WStr("Azure.Messaging.ServiceBus.ServiceBusSender"),(WCHAR*)WStr("ScheduleMessagesAsync"),sig307,4,7,14,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Azure.ServiceBus.ServiceBusSenderScheduleMessagesAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Azure.Messaging.ServiceBus"),(WCHAR*)WStr("Azure.Messaging.ServiceBus.ServiceBusSender"),(WCHAR*)WStr("SendMessagesAsync"),sig187,3,7,14,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Azure.ServiceBus.ServiceBusSenderSendMessageBatchAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Azure.Messaging.ServiceBus"),(WCHAR*)WStr("Azure.Messaging.ServiceBus.ServiceBusSender"),(WCHAR*)WStr("SendMessagesAsync"),sig209,3,7,14,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Azure.ServiceBus.ServiceBusSenderSendMessagesAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.Azure.Cosmos.Client"),(WCHAR*)WStr("Microsoft.Azure.Cosmos.ContainerCore"),(WCHAR*)WStr("GetItemQueryIterator"),sig080,4,3,6,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.CosmosDb.ContainerQueryIteratorsIntegrations"),CallTargetKind::Default,1,15}, @@ -618,7 +619,7 @@ std::vector callTargets = {(WCHAR*)WStr("Microsoft.Azure.Cosmos.Client"),(WCHAR*)WStr("Microsoft.Azure.Cosmos.DatabaseCore"),(WCHAR*)WStr("GetContainerQueryStreamIterator"),sig081,4,3,6,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.CosmosDb.DatabaseQueryIteratorsIntegrations"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.Azure.Cosmos.Client"),(WCHAR*)WStr("Microsoft.Azure.Cosmos.DatabaseCore"),(WCHAR*)WStr("GetUserQueryIterator"),sig080,4,3,6,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.CosmosDb.DatabaseQueryIteratorsIntegrations"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.Azure.Cosmos.Client"),(WCHAR*)WStr("Microsoft.Azure.Cosmos.DatabaseCore"),(WCHAR*)WStr("GetUserQueryIterator"),sig081,4,3,6,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.CosmosDb.DatabaseQueryIteratorsIntegrations"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.Azure.Cosmos.Client"),(WCHAR*)WStr("Microsoft.Azure.Cosmos.Handlers.RequestInvokerHandler"),(WCHAR*)WStr("SendAsync"),sig275,11,3,12,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.CosmosDb.RequestInvokerHandlerSendAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.Azure.Cosmos.Client"),(WCHAR*)WStr("Microsoft.Azure.Cosmos.Handlers.RequestInvokerHandler"),(WCHAR*)WStr("SendAsync"),sig276,11,3,12,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.CosmosDb.RequestInvokerHandlerSendAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Couchbase.NetClient"),(WCHAR*)WStr("Couchbase.Core.ClusterNode"),(WCHAR*)WStr("ExecuteOp"),sig191,3,3,1,3,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Couchbase.ClusterNodeIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Couchbase.NetClient"),(WCHAR*)WStr("Couchbase.Core.ClusterNode"),(WCHAR*)WStr("ExecuteOp"),sig192,3,3,0,7,3,1,2,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Couchbase.ClusterNodeIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Couchbase.NetClient"),(WCHAR*)WStr("Couchbase.Core.ClusterNode"),(WCHAR*)WStr("ExecuteOp"),sig189,4,3,1,3,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Couchbase.ClusterNodeIntegrationBis"),CallTargetKind::Default,1,15}, @@ -645,30 +646,30 @@ std::vector callTargets = {(WCHAR*)WStr("Couchbase.NetClient"),(WCHAR*)WStr("Couchbase.IO.Services.SharedPooledIOService"),(WCHAR*)WStr("ExecuteAsync"),sig194,2,2,2,8,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Couchbase.IIOServiceExecuteAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Couchbase.NetClient"),(WCHAR*)WStr("Couchbase.IO.Services.SharedPooledIOService"),(WCHAR*)WStr("ExecuteAsync"),sig195,2,2,2,8,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Couchbase.IIOServiceExecuteAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Couchbase.NetClient"),(WCHAR*)WStr("Couchbase.IO.Services.SharedPooledIOService"),(WCHAR*)WStr("ExecuteAsync"),sig196,3,2,2,8,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Couchbase.IIOServiceExecuteAsyncIntegrationBis"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.AppSec.EventTrackingSdk"),(WCHAR*)WStr("TrackCustomEvent"),sig389,2,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.AppSec.EventTrackingSdk.EventTrackingSdkTrackCustomEventIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.AppSec.EventTrackingSdk"),(WCHAR*)WStr("TrackCustomEvent"),sig398,3,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.AppSec.EventTrackingSdk.EventTrackingSdkTrackCustomEventMetadataIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.AppSec.EventTrackingSdk"),(WCHAR*)WStr("TrackUserLoginFailureEvent"),sig393,3,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.AppSec.EventTrackingSdk.EventTrackingSdkTrackUserLoginFailureEventIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.AppSec.EventTrackingSdk"),(WCHAR*)WStr("TrackUserLoginFailureEvent"),sig396,4,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.AppSec.EventTrackingSdk.EventTrackingSdkTrackUserLoginFailureEventMetadataIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.AppSec.EventTrackingSdk"),(WCHAR*)WStr("TrackUserLoginSuccessEvent"),sig389,2,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.AppSec.EventTrackingSdk.EventTrackingSdkTrackUserLoginSuccessEventIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.AppSec.EventTrackingSdk"),(WCHAR*)WStr("TrackUserLoginSuccessEvent"),sig398,3,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.AppSec.EventTrackingSdk.EventTrackingSdkTrackUserLoginSuccessEventMetadataIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.AppSec.EventTrackingSdkV2"),(WCHAR*)WStr("TrackUserLoginFailure"),sig394,5,3,0,15,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.AppSec.EventTrackingSdkV2.EventTrackingSdkV2TrackUserLoginFailureUserDetailsIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.AppSec.EventTrackingSdkV2"),(WCHAR*)WStr("TrackUserLoginFailure"),sig397,5,3,0,15,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.AppSec.EventTrackingSdkV2.EventTrackingSdkV2TrackUserLoginFailureUserIdIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.AppSec.EventTrackingSdkV2"),(WCHAR*)WStr("TrackUserLoginSuccess"),sig391,4,3,0,15,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.AppSec.EventTrackingSdkV2.EventTrackingSdkV2TrackUserLoginSuccessUserDetailsIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.AppSec.EventTrackingSdkV2"),(WCHAR*)WStr("TrackUserLoginSuccess"),sig403,4,3,15,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.AppSec.EventTrackingSdkV2.EventTrackingSdkV2TrackUserLoginSuccessUserIdIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.AppSec.EventTrackingSdk"),(WCHAR*)WStr("TrackCustomEvent"),sig390,2,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.AppSec.EventTrackingSdk.EventTrackingSdkTrackCustomEventIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.AppSec.EventTrackingSdk"),(WCHAR*)WStr("TrackCustomEvent"),sig399,3,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.AppSec.EventTrackingSdk.EventTrackingSdkTrackCustomEventMetadataIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.AppSec.EventTrackingSdk"),(WCHAR*)WStr("TrackUserLoginFailureEvent"),sig394,3,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.AppSec.EventTrackingSdk.EventTrackingSdkTrackUserLoginFailureEventIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.AppSec.EventTrackingSdk"),(WCHAR*)WStr("TrackUserLoginFailureEvent"),sig397,4,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.AppSec.EventTrackingSdk.EventTrackingSdkTrackUserLoginFailureEventMetadataIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.AppSec.EventTrackingSdk"),(WCHAR*)WStr("TrackUserLoginSuccessEvent"),sig390,2,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.AppSec.EventTrackingSdk.EventTrackingSdkTrackUserLoginSuccessEventIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.AppSec.EventTrackingSdk"),(WCHAR*)WStr("TrackUserLoginSuccessEvent"),sig399,3,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.AppSec.EventTrackingSdk.EventTrackingSdkTrackUserLoginSuccessEventMetadataIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.AppSec.EventTrackingSdkV2"),(WCHAR*)WStr("TrackUserLoginFailure"),sig395,5,3,0,15,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.AppSec.EventTrackingSdkV2.EventTrackingSdkV2TrackUserLoginFailureUserDetailsIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.AppSec.EventTrackingSdkV2"),(WCHAR*)WStr("TrackUserLoginFailure"),sig398,5,3,0,15,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.AppSec.EventTrackingSdkV2.EventTrackingSdkV2TrackUserLoginFailureUserIdIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.AppSec.EventTrackingSdkV2"),(WCHAR*)WStr("TrackUserLoginSuccess"),sig392,4,3,0,15,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.AppSec.EventTrackingSdkV2.EventTrackingSdkV2TrackUserLoginSuccessUserDetailsIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.AppSec.EventTrackingSdkV2"),(WCHAR*)WStr("TrackUserLoginSuccess"),sig404,4,3,15,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.AppSec.EventTrackingSdkV2.EventTrackingSdkV2TrackUserLoginSuccessUserIdIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Baggage"),(WCHAR*)WStr("get_Current"),sig140,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Baggage.Baggage_GetCurrent_Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Baggage"),(WCHAR*)WStr("set_Current"),sig364,2,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Baggage.Baggage_SetCurrent_Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Ci.TestExtensions"),(WCHAR*)WStr("AddBenchmarkData"),sig333,5,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Ci.TestExtensionsAddBenchmarkDataIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Ci.TestExtensions"),(WCHAR*)WStr("SetBenchmarkMetadata"),sig332,4,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Ci.TestExtensionsSetBenchmarkMetadataIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Ci.TestExtensions"),(WCHAR*)WStr("SetParameters"),sig334,3,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Ci.TestExtensionsSetParametersIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Baggage"),(WCHAR*)WStr("set_Current"),sig365,2,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Baggage.Baggage_SetCurrent_Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Ci.TestExtensions"),(WCHAR*)WStr("AddBenchmarkData"),sig334,5,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Ci.TestExtensionsAddBenchmarkDataIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Ci.TestExtensions"),(WCHAR*)WStr("SetBenchmarkMetadata"),sig333,4,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Ci.TestExtensionsSetBenchmarkMetadataIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Ci.TestExtensions"),(WCHAR*)WStr("SetParameters"),sig335,3,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Ci.TestExtensionsSetParametersIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Ci.TestModule"),(WCHAR*)WStr("InternalCreate"),sig052,5,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Ci.TestModuleInternalCreateIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Ci.TestSession"),(WCHAR*)WStr("InternalGetOrCreate"),sig053,6,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Ci.TestSessionInternalGetOrCreateIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.GlobalSettings"),(WCHAR*)WStr("SetDebugEnabled"),sig357,2,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.GlobalSettingsSetDebugEnabledIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.GlobalSettings"),(WCHAR*)WStr("SetDebugEnabled"),sig358,2,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.GlobalSettingsSetDebugEnabledIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.ImmutableIntegrationSettings"),(WCHAR*)WStr("get_AnalyticsEnabled"),sig168,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.ImmutableIntegrationSettings.AnalyticsEnabledGetIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.ImmutableIntegrationSettings"),(WCHAR*)WStr("get_AnalyticsSampleRate"),sig150,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.ImmutableIntegrationSettings.AnalyticsSampleRateGetIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.ImmutableIntegrationSettings"),(WCHAR*)WStr("get_Enabled"),sig168,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.ImmutableIntegrationSettings.EnabledGetIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.ImmutableIntegrationSettings"),(WCHAR*)WStr("get_IntegrationName"),sig178,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.ImmutableIntegrationSettings.IntegrationNameGetIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.ImmutableIntegrationSettingsCollection"),(WCHAR*)WStr("get_Item"),sig056,2,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.ImmutableIntegrationSettingsCollectionIndexerIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.ImmutableTracerSettings"),(WCHAR*)WStr("get_AgentUri"),sig324,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.ImmutableTracerSettings.AgentUriIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.ImmutableTracerSettings"),(WCHAR*)WStr("get_AgentUri"),sig325,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.ImmutableTracerSettings.AgentUriIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.ImmutableTracerSettings"),(WCHAR*)WStr("get_AnalyticsEnabled"),sig129,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.ImmutableTracerSettings.AnalyticsEnabledGetIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.ImmutableTracerSettings"),(WCHAR*)WStr("get_CustomSamplingRules"),sig178,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.ImmutableTracerSettings.CustomSamplingRulesGetIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.ImmutableTracerSettings"),(WCHAR*)WStr("get_Environment"),sig178,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.ImmutableTracerSettings.EnvironmentGetIntegration"),CallTargetKind::Default,1,15}, @@ -692,10 +693,10 @@ std::vector callTargets = {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.IntegrationSettings"),(WCHAR*)WStr("get_Enabled"),sig168,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.IntegrationSettings.EnabledGetIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.IntegrationSettings"),(WCHAR*)WStr("get_IntegrationName"),sig178,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.IntegrationSettings.IntegrationNameGetIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.IntegrationSettingsCollection"),(WCHAR*)WStr("get_Item"),sig058,2,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.IntegrationSettingsCollectionIndexerIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.TracerSettings"),(WCHAR*)WStr(".ctor"),sig325,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.TracerSettings.CtorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.TracerSettings"),(WCHAR*)WStr(".ctor"),sig357,2,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.TracerSettings.CtorUseDefaultSourcesIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.TracerSettings"),(WCHAR*)WStr(".ctor"),sig326,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.TracerSettings.CtorIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.TracerSettings"),(WCHAR*)WStr(".ctor"),sig358,2,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.TracerSettings.CtorUseDefaultSourcesIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.TracerSettings"),(WCHAR*)WStr("FromDefaultSources"),sig060,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.TracerSettings.FromDefaultSourcesIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.TracerSettings"),(WCHAR*)WStr("get_AgentUri"),sig324,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.TracerSettings.AgentUriGetIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.TracerSettings"),(WCHAR*)WStr("get_AgentUri"),sig325,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.TracerSettings.AgentUriGetIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.TracerSettings"),(WCHAR*)WStr("get_AnalyticsEnabled"),sig129,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.TracerSettings.AnalyticsEnabledGetIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.TracerSettings"),(WCHAR*)WStr("get_CustomSamplingRules"),sig178,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.TracerSettings.CustomSamplingRulesGetIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.TracerSettings"),(WCHAR*)WStr("get_DiagnosticSourceEnabled"),sig129,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.TracerSettings.DiagnosticSourceEnabledGetIntegration"),CallTargetKind::Default,1,15}, @@ -716,24 +717,24 @@ std::vector callTargets = {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.TracerSettings"),(WCHAR*)WStr("get_StatsComputationEnabled"),sig129,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.TracerSettings.StatsComputationEnabledGetIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.TracerSettings"),(WCHAR*)WStr("get_TraceEnabled"),sig129,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.TracerSettings.TraceEnabledGetIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.TracerSettings"),(WCHAR*)WStr("get_TracerMetricsEnabled"),sig129,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.TracerSettings.TracerMetricsEnabledGetIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.TracerSettings"),(WCHAR*)WStr("PopulateDictionary"),sig361,3,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.TracerSettings.PopulateDictionaryIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.TracerSettings"),(WCHAR*)WStr("set_DiagnosticSourceEnabled"),sig357,2,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.TracerSettings.DiagnosticSourceEnabledSetIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.DataStreams"),(WCHAR*)WStr("TrackTransactionInternal"),sig400,3,3,43,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.DataStreams.DataStreamsTrackTransactionIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.ExtensionMethods.SpanExtensions"),(WCHAR*)WStr("SetTraceSamplingPriority"),sig335,3,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Extensions.SpanExtensionsSetTraceSamplingPriorityIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.TracerSettings"),(WCHAR*)WStr("PopulateDictionary"),sig362,3,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.TracerSettings.PopulateDictionaryIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Configuration.TracerSettings"),(WCHAR*)WStr("set_DiagnosticSourceEnabled"),sig358,2,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Configuration.TracerSettings.DiagnosticSourceEnabledSetIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.DataStreams"),(WCHAR*)WStr("TrackTransactionInternal"),sig401,3,3,43,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.DataStreams.DataStreamsTrackTransactionIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.ExtensionMethods.SpanExtensions"),(WCHAR*)WStr("SetTraceSamplingPriority"),sig336,3,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Extensions.SpanExtensionsSetTraceSamplingPriorityIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.FeatureFlags.FeatureFlagsSdk"),(WCHAR*)WStr("Evaluate"),sig061,6,3,31,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Datadog_Trace_Manual.FeatureFlagsSdkEvaluateIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.FeatureFlags.FeatureFlagsSdk"),(WCHAR*)WStr("IsAvailable"),sig129,1,3,31,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Datadog_Trace_Manual.FeatureFlagsSdkIsAvailableIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.FeatureFlags.FeatureFlagsSdk"),(WCHAR*)WStr("RegisterOnNewConfigEventHandler"),sig355,2,3,31,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Datadog_Trace_Manual.FeatureFlagsSdkRegisterOnNewConfigEventHandlerIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.SpanContextExtractor"),(WCHAR*)WStr(".ctor"),sig325,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Propagators.SpanContextExtractorConstructorIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.FeatureFlags.FeatureFlagsSdk"),(WCHAR*)WStr("RegisterOnNewConfigEventHandler"),sig356,2,3,31,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Datadog_Trace_Manual.FeatureFlagsSdkRegisterOnNewConfigEventHandlerIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.SpanContextExtractor"),(WCHAR*)WStr(".ctor"),sig326,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Propagators.SpanContextExtractorConstructorIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.SpanContextExtractor"),(WCHAR*)WStr("Extract"),sig068,3,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Propagators.SpanContextExtractorExtractIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.SpanContextExtractor"),(WCHAR*)WStr("ExtractIncludingDsm"),sig069,5,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Propagators.SpanContextExtractorExtractIncludingDsmIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.SpanContextInjector"),(WCHAR*)WStr(".ctor"),sig325,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Propagators.SpanContextInjectorConstructorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.SpanContextInjector"),(WCHAR*)WStr("Inject"),sig326,4,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Propagators.SpanContextInjectorInjectIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.SpanContextInjector"),(WCHAR*)WStr("InjectIncludingDsm"),sig327,6,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Propagators.SpanContextInjectorInjectIncludingDsmIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.SpanContextInjector"),(WCHAR*)WStr(".ctor"),sig326,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Propagators.SpanContextInjectorConstructorIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.SpanContextInjector"),(WCHAR*)WStr("Inject"),sig327,4,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Propagators.SpanContextInjectorInjectIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.SpanContextInjector"),(WCHAR*)WStr("InjectIncludingDsm"),sig328,6,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Propagators.SpanContextInjectorInjectIncludingDsmIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.SpanExtensions"),(WCHAR*)WStr("SetTag"),sig066,4,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Extensions.SpanExtensionsSetTagIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.SpanExtensions"),(WCHAR*)WStr("SetUser"),sig336,9,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Extensions.SpanExtensionsSetUserIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Tracer"),(WCHAR*)WStr(".ctor"),sig382,3,3,0,0,3,6,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Tracer.CtorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Tracer"),(WCHAR*)WStr("Configure"),sig360,2,3,7,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Tracer.ConfigureIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Tracer"),(WCHAR*)WStr("Configure"),sig360,2,3,0,0,3,6,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Tracer.ConfigureIntegration_Pre3_7"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.SpanExtensions"),(WCHAR*)WStr("SetUser"),sig337,9,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Extensions.SpanExtensionsSetUserIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Tracer"),(WCHAR*)WStr(".ctor"),sig383,3,3,0,0,3,6,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Tracer.CtorIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Tracer"),(WCHAR*)WStr("Configure"),sig361,2,3,7,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Tracer.ConfigureIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Tracer"),(WCHAR*)WStr("Configure"),sig361,2,3,0,0,3,6,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Tracer.ConfigureIntegration_Pre3_7"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Tracer"),(WCHAR*)WStr("Datadog.Trace.IDatadogOpenTracingTracer.StartSpan"),sig067,6,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Tracer.StartSpanIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Tracer"),(WCHAR*)WStr("ForceFlushAsync"),sig185,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Tracer.ForceFlushAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Trace.Manual"),(WCHAR*)WStr("Datadog.Trace.Tracer"),(WCHAR*)WStr("get_ActiveScope"),sig062,1,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.Tracer.GetActiveScopeIntegration"),CallTargetKind::Default,1,15}, @@ -747,37 +748,37 @@ std::vector callTargets = {(WCHAR*)WStr("Datadog.Trace.OpenTracing"),(WCHAR*)WStr("Datadog.Trace.OpenTracing.OpenTracingTracerFactory"),(WCHAR*)WStr("WrapTracer"),sig119,2,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenTracing.OpenTracingTracerFactoryWrapTracerIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Trace"),(WCHAR*)WStr("Datadog.Trace.Util.ProcessHelpers"),(WCHAR*)WStr("StartWithDoNotTrace"),sig149,3,2,49,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.VersionConflict.ProcessHelpersStartWithDoNotTraceIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("coverlet.core"),(WCHAR*)WStr("Coverlet.Core.Coverage"),(WCHAR*)WStr("GetCoverageResult"),sig051,1,3,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.DotnetTest.CoverageGetCoverageResultIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("dotnet"),(WCHAR*)WStr("Microsoft.DotNet.Tools.Test.TestCommand"),(WCHAR*)WStr(".ctor"),sig374,6,2,0,0,5,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.DotnetTest.TestCommand5ctorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("dotnet"),(WCHAR*)WStr("Microsoft.DotNet.Tools.Test.TestCommand"),(WCHAR*)WStr(".ctor"),sig373,4,6,0,0,9,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.DotnetTest.TestCommandctorIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("dotnet"),(WCHAR*)WStr("Microsoft.DotNet.Tools.Test.TestCommand"),(WCHAR*)WStr(".ctor"),sig375,6,2,0,0,5,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.DotnetTest.TestCommand5ctorIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("dotnet"),(WCHAR*)WStr("Microsoft.DotNet.Tools.Test.TestCommand"),(WCHAR*)WStr(".ctor"),sig374,4,6,0,0,9,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.DotnetTest.TestCommandctorIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("dotnet"),(WCHAR*)WStr("Microsoft.DotNet.Tools.Test.TestCommand"),(WCHAR*)WStr("Run"),sig159,2,2,0,0,9,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.DotnetTest.TestCommandRunIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.VisualStudio.TraceDataCollector"),(WCHAR*)WStr("Microsoft.VisualStudio.TraceCollector.VanguardCollector.ManagedVanguard"),(WCHAR*)WStr("Stop"),sig325,1,15,0,0,15,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.DotnetTest.ManagedVanguardStopIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.VisualStudio.TraceDataCollector"),(WCHAR*)WStr("Microsoft.VisualStudio.TraceCollector.VanguardCollector.ManagedVanguard"),(WCHAR*)WStr("Stop"),sig326,1,15,0,0,15,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.DotnetTest.ManagedVanguardStopIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("vstest.console"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.CommandLine.Executor"),(WCHAR*)WStr("Execute"),sig157,2,15,0,0,15,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.DotnetTest.ExecutorExecuteIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("vstest.console"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.CommandLine.Executor"),(WCHAR*)WStr("GetArgumentProcessors"),sig158,3,15,0,0,15,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.DotnetTest.ExecutorGetArgumentProcessorsIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("vstest.console.arm64"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.CommandLine.Executor"),(WCHAR*)WStr("Execute"),sig157,2,15,0,0,15,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.DotnetTest.ExecutorExecuteIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("vstest.console.arm64"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.CommandLine.Executor"),(WCHAR*)WStr("GetArgumentProcessors"),sig158,3,15,0,0,15,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.DotnetTest.ExecutorGetArgumentProcessorsIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Elasticsearch.Net"),(WCHAR*)WStr("Elasticsearch.Net.RequestPipeline"),(WCHAR*)WStr("CallElasticsearch"),sig005,2,6,0,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Elasticsearch.V6.RequestPipeline_CallElasticsearch_Integration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Elasticsearch.Net"),(WCHAR*)WStr("Elasticsearch.Net.RequestPipeline"),(WCHAR*)WStr("CallElasticsearch"),sig070,2,5,0,0,5,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Elasticsearch.V5.RequestPipeline_CallElasticsearch_Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Elasticsearch.Net"),(WCHAR*)WStr("Elasticsearch.Net.RequestPipeline"),(WCHAR*)WStr("CallElasticsearchAsync"),sig226,3,6,0,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Elasticsearch.V6.RequestPipeline_CallElasticsearchAsync_Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Elasticsearch.Net"),(WCHAR*)WStr("Elasticsearch.Net.RequestPipeline"),(WCHAR*)WStr("CallElasticsearchAsync"),sig265,3,5,0,0,5,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Elasticsearch.V5.RequestPipeline_CallElasticsearchAsync_Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Elasticsearch.Net"),(WCHAR*)WStr("Elasticsearch.Net.RequestPipeline"),(WCHAR*)WStr("CallElasticsearchAsync"),sig227,3,6,0,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Elasticsearch.V6.RequestPipeline_CallElasticsearchAsync_Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Elasticsearch.Net"),(WCHAR*)WStr("Elasticsearch.Net.RequestPipeline"),(WCHAR*)WStr("CallElasticsearchAsync"),sig266,3,5,0,0,5,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Elasticsearch.V5.RequestPipeline_CallElasticsearchAsync_Integration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Elasticsearch.Net"),(WCHAR*)WStr("Elasticsearch.Net.Transport`1"),(WCHAR*)WStr("Request"),sig004,5,7,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Elasticsearch.V7.Transport_Request_Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Elasticsearch.Net"),(WCHAR*)WStr("Elasticsearch.Net.Transport`1"),(WCHAR*)WStr("RequestAsync"),sig225,6,7,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Elasticsearch.V7.Transport_RequestAsync_Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("GraphQL"),(WCHAR*)WStr("GraphQL.Execution.ExecutionStrategy"),(WCHAR*)WStr("ExecuteAsync"),sig220,2,2,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.Net.ExecuteAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("GraphQL"),(WCHAR*)WStr("GraphQL.Execution.ExecutionStrategy"),(WCHAR*)WStr("ExecuteAsync"),sig220,2,5,0,0,8,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.Net.ExecuteAsyncIntegrationV5AndV7"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("GraphQL"),(WCHAR*)WStr("GraphQL.Execution.SubscriptionExecutionStrategy"),(WCHAR*)WStr("ExecuteAsync"),sig220,2,2,3,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.Net.ExecuteAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("GraphQL"),(WCHAR*)WStr("GraphQL.Execution.SubscriptionExecutionStrategy"),(WCHAR*)WStr("ExecuteAsync"),sig220,2,5,0,0,8,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.Net.ExecuteAsyncIntegrationV5AndV7"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Elasticsearch.Net"),(WCHAR*)WStr("Elasticsearch.Net.Transport`1"),(WCHAR*)WStr("RequestAsync"),sig226,6,7,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Elasticsearch.V7.Transport_RequestAsync_Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("GraphQL"),(WCHAR*)WStr("GraphQL.Execution.ExecutionStrategy"),(WCHAR*)WStr("ExecuteAsync"),sig221,2,2,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.Net.ExecuteAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("GraphQL"),(WCHAR*)WStr("GraphQL.Execution.ExecutionStrategy"),(WCHAR*)WStr("ExecuteAsync"),sig221,2,5,0,0,8,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.Net.ExecuteAsyncIntegrationV5AndV7"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("GraphQL"),(WCHAR*)WStr("GraphQL.Execution.SubscriptionExecutionStrategy"),(WCHAR*)WStr("ExecuteAsync"),sig221,2,2,3,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.Net.ExecuteAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("GraphQL"),(WCHAR*)WStr("GraphQL.Execution.SubscriptionExecutionStrategy"),(WCHAR*)WStr("ExecuteAsync"),sig221,2,5,0,0,8,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.Net.ExecuteAsyncIntegrationV5AndV7"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("GraphQL"),(WCHAR*)WStr("GraphQL.Validation.DocumentValidator"),(WCHAR*)WStr("Validate"),sig071,7,2,3,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.Net.ValidateIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("GraphQL"),(WCHAR*)WStr("GraphQL.Validation.DocumentValidator"),(WCHAR*)WStr("ValidateAsync"),sig231,7,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.Net.ValidateAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("GraphQL"),(WCHAR*)WStr("GraphQL.Validation.DocumentValidator"),(WCHAR*)WStr("ValidateAsync"),sig227,7,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.Net.ValidateAsyncIntegrationV4"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("GraphQL"),(WCHAR*)WStr("GraphQL.Validation.DocumentValidator"),(WCHAR*)WStr("ValidateAsyncCoreAsync"),sig228,3,5,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.Net.ValidateAsyncIntegrationV5AndV7"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("GraphQL"),(WCHAR*)WStr("GraphQL.Validation.DocumentValidator"),(WCHAR*)WStr("ValidateAsyncCoreAsync"),sig228,3,7,0,0,8,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.Net.ValidateAsyncIntegrationV8"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("GraphQL.SystemReactive"),(WCHAR*)WStr("GraphQL.Execution.SubscriptionExecutionStrategy"),(WCHAR*)WStr("ExecuteAsync"),sig220,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.Net.ExecuteAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("GraphQL"),(WCHAR*)WStr("GraphQL.Validation.DocumentValidator"),(WCHAR*)WStr("ValidateAsync"),sig232,7,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.Net.ValidateAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("GraphQL"),(WCHAR*)WStr("GraphQL.Validation.DocumentValidator"),(WCHAR*)WStr("ValidateAsync"),sig228,7,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.Net.ValidateAsyncIntegrationV4"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("GraphQL"),(WCHAR*)WStr("GraphQL.Validation.DocumentValidator"),(WCHAR*)WStr("ValidateAsyncCoreAsync"),sig229,3,5,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.Net.ValidateAsyncIntegrationV5AndV7"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("GraphQL"),(WCHAR*)WStr("GraphQL.Validation.DocumentValidator"),(WCHAR*)WStr("ValidateAsyncCoreAsync"),sig229,3,7,0,0,8,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.Net.ValidateAsyncIntegrationV8"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("GraphQL.SystemReactive"),(WCHAR*)WStr("GraphQL.Execution.SubscriptionExecutionStrategy"),(WCHAR*)WStr("ExecuteAsync"),sig221,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.Net.ExecuteAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Google.Protobuf"),(WCHAR*)WStr("Google.Protobuf.ParsingPrimitives"),(WCHAR*)WStr("ReadRawString"),sig180,4,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Grpc.GrpcDotNet.GrpcAspNetCoreServer.IAST.ParsingPrimitivesReadRawStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("Grpc.AspNetCore.Server"),(WCHAR*)WStr("Grpc.AspNetCore.Server.Internal.CallHandlers.ServerCallHandlerBase`3"),(WCHAR*)WStr("HandleCallAsync"),sig202,2,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Grpc.GrpcDotNet.GrpcAspNetCoreServer.ServerCallHandlerBaseHandleCallAsyncIntegration"),CallTargetKind::Default,1,14}, -{(WCHAR*)WStr("Grpc.AspNetCore.Server"),(WCHAR*)WStr("Grpc.AspNetCore.Server.Internal.GrpcProtocolHelpers"),(WCHAR*)WStr("BuildHttpErrorResponse"),sig344,5,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Grpc.GrpcDotNet.GrpcAspNetCoreServer.GrpcProtocolHelpersBuildHttpErrorResponseIntegration"),CallTargetKind::Default,1,14}, -{(WCHAR*)WStr("Grpc.AspNetCore.Server"),(WCHAR*)WStr("Grpc.AspNetCore.Server.Internal.HttpContextServerCallContext"),(WCHAR*)WStr("LogCallEnd"),sig325,1,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Grpc.GrpcDotNet.GrpcAspNetCoreServer.HttpContextServerCallContextLogCallEndIntegration"),CallTargetKind::Default,1,14}, +{(WCHAR*)WStr("Grpc.AspNetCore.Server"),(WCHAR*)WStr("Grpc.AspNetCore.Server.Internal.GrpcProtocolHelpers"),(WCHAR*)WStr("BuildHttpErrorResponse"),sig345,5,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Grpc.GrpcDotNet.GrpcAspNetCoreServer.GrpcProtocolHelpersBuildHttpErrorResponseIntegration"),CallTargetKind::Default,1,14}, +{(WCHAR*)WStr("Grpc.AspNetCore.Server"),(WCHAR*)WStr("Grpc.AspNetCore.Server.Internal.HttpContextServerCallContext"),(WCHAR*)WStr("LogCallEnd"),sig326,1,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Grpc.GrpcDotNet.GrpcAspNetCoreServer.HttpContextServerCallContextLogCallEndIntegration"),CallTargetKind::Default,1,14}, {(WCHAR*)WStr("Grpc.Core"),(WCHAR*)WStr("Grpc.Core.DefaultCallInvoker"),(WCHAR*)WStr("CreateCall"),sig072,4,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Grpc.GrpcLegacy.Client.DefaultCallInvokerInstrumentation"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Grpc.Core"),(WCHAR*)WStr("Grpc.Core.Internal.AsyncCall`2"),(WCHAR*)WStr("HandleFinished"),sig358,3,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Grpc.GrpcLegacy.Client.AsyncCallHandleFinishedInstrumentation"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Grpc.Core"),(WCHAR*)WStr("Grpc.Core.Internal.AsyncCall`2"),(WCHAR*)WStr("HandleUnaryResponse"),sig359,5,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Grpc.GrpcLegacy.Client.AsyncCallHandleUnaryResponseInstrumentation"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Grpc.Core"),(WCHAR*)WStr("Grpc.Core.Internal.AsyncCall`2"),(WCHAR*)WStr("HandleFinished"),sig359,3,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Grpc.GrpcLegacy.Client.AsyncCallHandleFinishedInstrumentation"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Grpc.Core"),(WCHAR*)WStr("Grpc.Core.Internal.AsyncCall`2"),(WCHAR*)WStr("HandleUnaryResponse"),sig360,5,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Grpc.GrpcLegacy.Client.AsyncCallHandleUnaryResponseInstrumentation"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Grpc.Core"),(WCHAR*)WStr("Grpc.Core.Internal.AsyncCallServer`2"),(WCHAR*)WStr("SendInitialMetadataAsync"),sig198,2,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Grpc.GrpcLegacy.Server.AsyncCallServerSendInitialMetadataAsyncInstrumentation"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Grpc.Core"),(WCHAR*)WStr("Grpc.Core.Internal.AsyncCallServer`2"),(WCHAR*)WStr("SendStatusFromServerAsync"),sig199,4,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Grpc.GrpcLegacy.Server.AsyncCallServerSendStatusFromServerAsyncInstrumentation"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Grpc.Core"),(WCHAR*)WStr("Grpc.Core.Internal.ClientStreamingServerCallHandler`2"),(WCHAR*)WStr("HandleCall"),sig197,3,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Grpc.GrpcLegacy.Server.ServerCallHandlerInstrumentation"),CallTargetKind::Default,1,15}, @@ -785,10 +786,10 @@ std::vector callTargets = {(WCHAR*)WStr("Grpc.Core"),(WCHAR*)WStr("Grpc.Core.Internal.MetadataArraySafeHandle"),(WCHAR*)WStr("Create"),sig073,2,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Grpc.GrpcLegacy.Client.MetadataArraySafeHandleCreateInstrumentation"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Grpc.Core"),(WCHAR*)WStr("Grpc.Core.Internal.ServerStreamingServerCallHandler`2"),(WCHAR*)WStr("HandleCall"),sig197,3,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Grpc.GrpcLegacy.Server.ServerCallHandlerInstrumentation"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Grpc.Core"),(WCHAR*)WStr("Grpc.Core.Internal.UnaryServerCallHandler`2"),(WCHAR*)WStr("HandleCall"),sig197,3,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Grpc.GrpcLegacy.Server.ServerCallHandlerInstrumentation"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Grpc.Net.Client"),(WCHAR*)WStr("Grpc.Net.Client.Internal.GrpcCall`2"),(WCHAR*)WStr("FinishCall"),sig377,5,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Grpc.GrpcDotNet.GrpcNetClient.GrpcCallFinishCallIntegration"),CallTargetKind::Default,1,14}, -{(WCHAR*)WStr("Grpc.Net.Client"),(WCHAR*)WStr("Grpc.Net.Client.Internal.GrpcCall`2"),(WCHAR*)WStr("FinishCall"),sig378,5,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Grpc.GrpcDotNet.GrpcNetClient.GrpcCallFinishCallPre243Integration"),CallTargetKind::Default,1,14}, +{(WCHAR*)WStr("Grpc.Net.Client"),(WCHAR*)WStr("Grpc.Net.Client.Internal.GrpcCall`2"),(WCHAR*)WStr("FinishCall"),sig378,5,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Grpc.GrpcDotNet.GrpcNetClient.GrpcCallFinishCallIntegration"),CallTargetKind::Default,1,14}, +{(WCHAR*)WStr("Grpc.Net.Client"),(WCHAR*)WStr("Grpc.Net.Client.Internal.GrpcCall`2"),(WCHAR*)WStr("FinishCall"),sig379,5,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Grpc.GrpcDotNet.GrpcNetClient.GrpcCallFinishCallPre243Integration"),CallTargetKind::Default,1,14}, {(WCHAR*)WStr("Grpc.Net.Client"),(WCHAR*)WStr("Grpc.Net.Client.Internal.GrpcCall`2"),(WCHAR*)WStr("RunCall"),sig211,3,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Grpc.GrpcDotNet.GrpcNetClient.GrpcCallRunCallIntegration"),CallTargetKind::Default,1,14}, -{(WCHAR*)WStr("Hangfire.Core"),(WCHAR*)WStr("Hangfire.Common.JobFilterCollection"),(WCHAR*)WStr(".ctor"),sig325,1,1,7,0,1,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Hangfire.JobFilterCollectionCtorIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Hangfire.Core"),(WCHAR*)WStr("Hangfire.Common.JobFilterCollection"),(WCHAR*)WStr(".ctor"),sig326,1,1,7,0,1,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Hangfire.JobFilterCollectionCtorIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("System.Security.Cryptography"),(WCHAR*)WStr("System.Security.Cryptography.HashAlgorithm"),(WCHAR*)WStr("ComputeHash"),sig136,4,7,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.HashAlgorithm.HashAlgorithmIntegration"),CallTargetKind::Default,4,14}, {(WCHAR*)WStr("System.Security.Cryptography"),(WCHAR*)WStr("System.Security.Cryptography.HashAlgorithm"),(WCHAR*)WStr("ComputeHash"),sig137,2,7,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.HashAlgorithm.HashAlgorithmIntegrationBis"),CallTargetKind::Default,4,14}, {(WCHAR*)WStr("System.Security.Cryptography"),(WCHAR*)WStr("System.Security.Cryptography.HashAlgorithm"),(WCHAR*)WStr("ComputeHash"),sig135,2,7,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.HashAlgorithm.HashAlgorithmIntegrationBis"),CallTargetKind::Default,4,14}, @@ -797,401 +798,402 @@ std::vector callTargets = {(WCHAR*)WStr("System.Security.Cryptography.Primitives"),(WCHAR*)WStr("System.Security.Cryptography.HashAlgorithm"),(WCHAR*)WStr("ComputeHash"),sig137,2,1,0,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.HashAlgorithm.HashAlgorithmIntegrationBis"),CallTargetKind::Default,4,14}, {(WCHAR*)WStr("System.Security.Cryptography.Primitives"),(WCHAR*)WStr("System.Security.Cryptography.HashAlgorithm"),(WCHAR*)WStr("ComputeHash"),sig135,2,1,0,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.HashAlgorithm.HashAlgorithmIntegrationBis"),CallTargetKind::Default,4,14}, {(WCHAR*)WStr("System.Security.Cryptography.Primitives"),(WCHAR*)WStr("System.Security.Cryptography.HashAlgorithm"),(WCHAR*)WStr("ComputeHashAsync"),sig210,3,1,0,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.HashAlgorithm.HashAlgorithmIntegrationTer"),CallTargetKind::Default,4,14}, -{(WCHAR*)WStr("HotChocolate.Execution"),(WCHAR*)WStr("HotChocolate.Execution.Processing.MutationExecutor"),(WCHAR*)WStr("ExecuteAsync"),sig268,2,11,0,0,11,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.HotChocolate.ExecuteAsyncIntegrationExtra"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("HotChocolate.Execution"),(WCHAR*)WStr("HotChocolate.Execution.Processing.QueryExecutor"),(WCHAR*)WStr("ExecuteAsync"),sig268,2,11,0,0,12,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.HotChocolate.ExecuteAsyncIntegrationExtra"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("HotChocolate.Execution"),(WCHAR*)WStr("HotChocolate.Execution.Processing.QueryExecutor"),(WCHAR*)WStr("ExecuteAsync"),sig271,2,13,0,0,13,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.HotChocolate.ExecuteAsyncIntegrationExtraV13"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("HotChocolate.Execution"),(WCHAR*)WStr("HotChocolate.Execution.Processing.QueryExecutor"),(WCHAR*)WStr("ExecuteAsync"),sig270,2,14,0,0,15,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.HotChocolate.ExecuteAsyncIntegrationExtraV13"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("HotChocolate.Execution"),(WCHAR*)WStr("HotChocolate.Execution.RequestExecutor"),(WCHAR*)WStr("ExecuteAsync"),sig267,3,11,0,0,12,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.HotChocolate.ExecuteAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("HotChocolate.Execution"),(WCHAR*)WStr("HotChocolate.Execution.RequestExecutor"),(WCHAR*)WStr("ExecuteAsync"),sig267,3,13,0,0,13,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.HotChocolate.ExecuteAsyncIntegrationV13"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("HotChocolate.Execution"),(WCHAR*)WStr("HotChocolate.Execution.RequestExecutor"),(WCHAR*)WStr("ExecuteAsync"),sig266,3,14,0,0,15,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.HotChocolate.ExecuteAsyncIntegrationV14"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("HotChocolate.Types"),(WCHAR*)WStr("HotChocolate.Execution.DefaultRequestExecutor"),(WCHAR*)WStr("ExecuteAsync"),sig266,3,16,0,0,16,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.HotChocolate.ExecuteAsyncIntegrationV14"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("HotChocolate.Types"),(WCHAR*)WStr("HotChocolate.Execution.Processing.QueryExecutor"),(WCHAR*)WStr("ExecuteAsync"),sig269,2,16,0,0,16,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.HotChocolate.ExecuteAsyncIntegrationExtraV16"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("HotChocolate.Execution"),(WCHAR*)WStr("HotChocolate.Execution.Processing.MutationExecutor"),(WCHAR*)WStr("ExecuteAsync"),sig269,2,11,0,0,11,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.HotChocolate.ExecuteAsyncIntegrationExtra"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("HotChocolate.Execution"),(WCHAR*)WStr("HotChocolate.Execution.Processing.QueryExecutor"),(WCHAR*)WStr("ExecuteAsync"),sig269,2,11,0,0,12,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.HotChocolate.ExecuteAsyncIntegrationExtra"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("HotChocolate.Execution"),(WCHAR*)WStr("HotChocolate.Execution.Processing.QueryExecutor"),(WCHAR*)WStr("ExecuteAsync"),sig272,2,13,0,0,13,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.HotChocolate.ExecuteAsyncIntegrationExtraV13"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("HotChocolate.Execution"),(WCHAR*)WStr("HotChocolate.Execution.Processing.QueryExecutor"),(WCHAR*)WStr("ExecuteAsync"),sig271,2,14,0,0,15,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.HotChocolate.ExecuteAsyncIntegrationExtraV13"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("HotChocolate.Execution"),(WCHAR*)WStr("HotChocolate.Execution.RequestExecutor"),(WCHAR*)WStr("ExecuteAsync"),sig268,3,11,0,0,12,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.HotChocolate.ExecuteAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("HotChocolate.Execution"),(WCHAR*)WStr("HotChocolate.Execution.RequestExecutor"),(WCHAR*)WStr("ExecuteAsync"),sig268,3,13,0,0,13,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.HotChocolate.ExecuteAsyncIntegrationV13"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("HotChocolate.Execution"),(WCHAR*)WStr("HotChocolate.Execution.RequestExecutor"),(WCHAR*)WStr("ExecuteAsync"),sig267,3,14,0,0,15,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.HotChocolate.ExecuteAsyncIntegrationV14"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("HotChocolate.Types"),(WCHAR*)WStr("HotChocolate.Execution.DefaultRequestExecutor"),(WCHAR*)WStr("ExecuteAsync"),sig267,3,16,0,0,16,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.HotChocolate.ExecuteAsyncIntegrationV14"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("HotChocolate.Types"),(WCHAR*)WStr("HotChocolate.Execution.Processing.QueryExecutor"),(WCHAR*)WStr("ExecuteAsync"),sig270,2,16,0,0,16,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.GraphQL.HotChocolate.ExecuteAsyncIntegrationExtraV16"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Ocelot"),(WCHAR*)WStr("Ocelot.Requester.MessageInvokerPool"),(WCHAR*)WStr("CreateHandler"),sig162,2,23,0,0,24,0,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.HttpClient.SocketsHttpHandler.OcelotMessageInvokerPoolIntegration"),CallTargetKind::Default,1,8}, {(WCHAR*)WStr("Ocelot"),(WCHAR*)WStr("Ocelot.Requester.MessageInvokerPool"),(WCHAR*)WStr("CreateHandler"),sig164,2,24,1,0,25,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.HttpClient.SocketsHttpHandler.OcelotMessageInvokerPoolIntegration"),CallTargetKind::Default,1,8}, -{(WCHAR*)WStr("System.Net.Http"),(WCHAR*)WStr("System.Net.Http.CurlHandler"),(WCHAR*)WStr("SendAsync"),sig311,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.HttpClient.CurlHandler.CurlHandlerIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("System.Net.Http"),(WCHAR*)WStr("System.Net.Http.CurlHandler"),(WCHAR*)WStr("SendAsync"),sig312,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.HttpClient.CurlHandler.CurlHandlerIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("System.Net.Http"),(WCHAR*)WStr("System.Net.Http.HttpClientHandler"),(WCHAR*)WStr("Send"),sig163,3,5,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.HttpClient.HttpClientHandler.HttpClientHandlerSyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("System.Net.Http"),(WCHAR*)WStr("System.Net.Http.HttpClientHandler"),(WCHAR*)WStr("SendAsync"),sig311,3,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.HttpClient.HttpClientHandler.HttpClientHandlerIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("System.Net.Http"),(WCHAR*)WStr("System.Net.Http.HttpClientHandler"),(WCHAR*)WStr("SendAsync"),sig312,3,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.HttpClient.HttpClientHandler.HttpClientHandlerIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("System.Net.Http"),(WCHAR*)WStr("System.Net.Http.SocketsHttpHandler"),(WCHAR*)WStr("Send"),sig163,3,5,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.HttpClient.SocketsHttpHandler.SocketsHttpHandlerSyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("System.Net.Http"),(WCHAR*)WStr("System.Net.Http.SocketsHttpHandler"),(WCHAR*)WStr("SendAsync"),sig311,3,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.HttpClient.SocketsHttpHandler.SocketsHttpHandlerIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("System.Net.Http"),(WCHAR*)WStr("System.Net.Http.WinHttpHandler"),(WCHAR*)WStr("SendAsync"),sig311,3,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.HttpClient.WinHttpHandler.WinHttpHandlerIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("System.Net.Http.WinHttpHandler"),(WCHAR*)WStr("System.Net.Http.WinHttpHandler"),(WCHAR*)WStr("SendAsync"),sig311,3,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.HttpClient.WinHttpHandler.WinHttpHandlerIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Yarp.ReverseProxy"),(WCHAR*)WStr("Yarp.ReverseProxy.Forwarder.ForwarderHttpClientFactory"),(WCHAR*)WStr("ConfigureHandler"),sig411,3,1,1,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.HttpClient.SocketsHttpHandler.YarpForwarderHttpClientFactoryIntegration"),CallTargetKind::Default,1,8}, -{(WCHAR*)WStr("amqmdnetstd"),(WCHAR*)WStr("IBM.WMQ.MQDestination"),(WCHAR*)WStr("Get"),sig341,4,9,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.IbmMq.GetIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("amqmdnetstd"),(WCHAR*)WStr("IBM.WMQ.MQDestination"),(WCHAR*)WStr("Put"),sig342,3,9,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.IbmMq.PutIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.Extensions.Logging"),(WCHAR*)WStr("Microsoft.Extensions.Logging.LoggerFactory"),(WCHAR*)WStr(".ctor"),sig366,3,2,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.ILogger.DirectSubmission.LoggerFactoryConstructorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.Extensions.Logging"),(WCHAR*)WStr("Microsoft.Extensions.Logging.LoggerFactory"),(WCHAR*)WStr(".ctor"),sig367,4,5,0,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.ILogger.DirectSubmission.LoggerFactoryConstructorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.Extensions.Logging"),(WCHAR*)WStr("Microsoft.Extensions.Logging.LoggerFactory"),(WCHAR*)WStr(".ctor"),sig368,5,7,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.ILogger.DirectSubmission.LoggerFactoryConstructorNet7Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.Extensions.Logging"),(WCHAR*)WStr("Microsoft.Extensions.Logging.LoggerFactoryScopeProvider"),(WCHAR*)WStr("ForEachScope"),sig356,3,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.ILogger.LoggerFactoryScopeProviderForEachScopeIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.Extensions.Logging.Abstractions"),(WCHAR*)WStr("Microsoft.Extensions.Logging.LoggerExternalScopeProvider"),(WCHAR*)WStr("ForEachScope"),sig356,3,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.ILogger.LoggerExternalScopeProviderForEachScopeIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.Extensions.Telemetry"),(WCHAR*)WStr("Microsoft.Extensions.Logging.ExtendedLoggerFactory"),(WCHAR*)WStr(".ctor"),sig370,12,9,5,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.ILogger.DirectSubmission.ExtendedLoggerFactoryConstructorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.Extensions.Telemetry"),(WCHAR*)WStr("Microsoft.Extensions.Logging.ExtendedLoggerFactory"),(WCHAR*)WStr(".ctor"),sig371,10,8,0,0,9,3,0,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.ILogger.DirectSubmission.ExtendedLoggerFactoryConstructorIntegration_8xx"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.Extensions.Telemetry"),(WCHAR*)WStr("Microsoft.Extensions.Logging.ExtendedLoggerFactory"),(WCHAR*)WStr(".ctor"),sig369,11,9,3,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.ILogger.DirectSubmission.ExtendedLoggerFactoryConstructorIntegration_930_940"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.Extensions.Telemetry"),(WCHAR*)WStr("Microsoft.Extensions.Logging.LoggerFactoryScopeProvider"),(WCHAR*)WStr("ForEachScope"),sig356,3,8,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.ILogger.LoggerFactoryScopeProviderForEachScopeIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Confluent.Kafka"),(WCHAR*)WStr("Confluent.Kafka.Consumer`2"),(WCHAR*)WStr(".ctor"),sig329,2,1,4,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Kafka.KafkaConsumerConstructorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Confluent.Kafka"),(WCHAR*)WStr("Confluent.Kafka.Consumer`2"),(WCHAR*)WStr("Close"),sig325,1,1,4,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Kafka.KafkaConsumerCloseIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("System.Net.Http"),(WCHAR*)WStr("System.Net.Http.SocketsHttpHandler"),(WCHAR*)WStr("SendAsync"),sig312,3,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.HttpClient.SocketsHttpHandler.SocketsHttpHandlerIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("System.Net.Http"),(WCHAR*)WStr("System.Net.Http.WinHttpHandler"),(WCHAR*)WStr("SendAsync"),sig312,3,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.HttpClient.WinHttpHandler.WinHttpHandlerIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("System.Net.Http.WinHttpHandler"),(WCHAR*)WStr("System.Net.Http.WinHttpHandler"),(WCHAR*)WStr("SendAsync"),sig312,3,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.HttpClient.WinHttpHandler.WinHttpHandlerIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Yarp.ReverseProxy"),(WCHAR*)WStr("Yarp.ReverseProxy.Forwarder.ForwarderHttpClientFactory"),(WCHAR*)WStr("ConfigureHandler"),sig412,3,1,1,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.HttpClient.SocketsHttpHandler.YarpForwarderHttpClientFactoryIntegration"),CallTargetKind::Default,1,8}, +{(WCHAR*)WStr("amqmdnetstd"),(WCHAR*)WStr("IBM.WMQ.MQDestination"),(WCHAR*)WStr("Get"),sig342,4,9,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.IbmMq.GetIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("amqmdnetstd"),(WCHAR*)WStr("IBM.WMQ.MQDestination"),(WCHAR*)WStr("Put"),sig343,3,9,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.IbmMq.PutIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.Extensions.Logging"),(WCHAR*)WStr("Microsoft.Extensions.Logging.LoggerFactory"),(WCHAR*)WStr(".ctor"),sig367,3,2,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.ILogger.DirectSubmission.LoggerFactoryConstructorIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.Extensions.Logging"),(WCHAR*)WStr("Microsoft.Extensions.Logging.LoggerFactory"),(WCHAR*)WStr(".ctor"),sig368,4,5,0,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.ILogger.DirectSubmission.LoggerFactoryConstructorIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.Extensions.Logging"),(WCHAR*)WStr("Microsoft.Extensions.Logging.LoggerFactory"),(WCHAR*)WStr(".ctor"),sig369,5,7,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.ILogger.DirectSubmission.LoggerFactoryConstructorNet7Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.Extensions.Logging"),(WCHAR*)WStr("Microsoft.Extensions.Logging.LoggerFactoryScopeProvider"),(WCHAR*)WStr("ForEachScope"),sig357,3,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.ILogger.LoggerFactoryScopeProviderForEachScopeIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.Extensions.Logging.Abstractions"),(WCHAR*)WStr("Microsoft.Extensions.Logging.LoggerExternalScopeProvider"),(WCHAR*)WStr("ForEachScope"),sig357,3,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.ILogger.LoggerExternalScopeProviderForEachScopeIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.Extensions.Telemetry"),(WCHAR*)WStr("Microsoft.Extensions.Logging.ExtendedLoggerFactory"),(WCHAR*)WStr(".ctor"),sig371,12,9,5,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.ILogger.DirectSubmission.ExtendedLoggerFactoryConstructorIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.Extensions.Telemetry"),(WCHAR*)WStr("Microsoft.Extensions.Logging.ExtendedLoggerFactory"),(WCHAR*)WStr(".ctor"),sig372,10,8,0,0,9,3,0,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.ILogger.DirectSubmission.ExtendedLoggerFactoryConstructorIntegration_8xx"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.Extensions.Telemetry"),(WCHAR*)WStr("Microsoft.Extensions.Logging.ExtendedLoggerFactory"),(WCHAR*)WStr(".ctor"),sig370,11,9,3,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.ILogger.DirectSubmission.ExtendedLoggerFactoryConstructorIntegration_930_940"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.Extensions.Telemetry"),(WCHAR*)WStr("Microsoft.Extensions.Logging.LoggerFactoryScopeProvider"),(WCHAR*)WStr("ForEachScope"),sig357,3,8,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.ILogger.LoggerFactoryScopeProviderForEachScopeIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Confluent.Kafka"),(WCHAR*)WStr("Confluent.Kafka.Consumer`2"),(WCHAR*)WStr(".ctor"),sig330,2,1,4,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Kafka.KafkaConsumerConstructorIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Confluent.Kafka"),(WCHAR*)WStr("Confluent.Kafka.Consumer`2"),(WCHAR*)WStr("Close"),sig326,1,1,4,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Kafka.KafkaConsumerCloseIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Confluent.Kafka"),(WCHAR*)WStr("Confluent.Kafka.Consumer`2"),(WCHAR*)WStr("Commit"),sig141,1,1,4,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Kafka.KafkaConsumerCommitAllIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Confluent.Kafka"),(WCHAR*)WStr("Confluent.Kafka.Consumer`2"),(WCHAR*)WStr("Commit"),sig365,2,1,4,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Kafka.KafkaConsumerCommitIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Confluent.Kafka"),(WCHAR*)WStr("Confluent.Kafka.Consumer`2"),(WCHAR*)WStr("Commit"),sig366,2,1,4,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Kafka.KafkaConsumerCommitIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Confluent.Kafka"),(WCHAR*)WStr("Confluent.Kafka.Consumer`2"),(WCHAR*)WStr("Consume"),sig047,2,1,4,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Kafka.KafkaConsumerConsumeIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Confluent.Kafka"),(WCHAR*)WStr("Confluent.Kafka.Consumer`2"),(WCHAR*)WStr("Dispose"),sig325,1,1,4,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Kafka.KafkaConsumerDisposeIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Confluent.Kafka"),(WCHAR*)WStr("Confluent.Kafka.Consumer`2"),(WCHAR*)WStr("Unsubscribe"),sig325,1,1,4,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Kafka.KafkaConsumerUnsubscribeIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Confluent.Kafka"),(WCHAR*)WStr("Confluent.Kafka.Producer`2"),(WCHAR*)WStr(".ctor"),sig330,2,1,4,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Kafka.KafkaProducerConstructorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Confluent.Kafka"),(WCHAR*)WStr("Confluent.Kafka.Producer`2"),(WCHAR*)WStr("Produce"),sig331,4,1,4,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Kafka.KafkaProduceSyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Confluent.Kafka"),(WCHAR*)WStr("Confluent.Kafka.Producer`2"),(WCHAR*)WStr("ProduceAsync"),sig264,4,1,4,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Kafka.KafkaProduceAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Confluent.Kafka"),(WCHAR*)WStr("Confluent.Kafka.Producer`2+TypedDeliveryHandlerShim_Action"),(WCHAR*)WStr(".ctor"),sig390,5,1,4,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Kafka.KafkaProduceSyncDeliveryHandlerIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Confluent.Kafka"),(WCHAR*)WStr("Confluent.Kafka.Consumer`2"),(WCHAR*)WStr("Dispose"),sig326,1,1,4,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Kafka.KafkaConsumerDisposeIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Confluent.Kafka"),(WCHAR*)WStr("Confluent.Kafka.Consumer`2"),(WCHAR*)WStr("Unsubscribe"),sig326,1,1,4,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Kafka.KafkaConsumerUnsubscribeIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Confluent.Kafka"),(WCHAR*)WStr("Confluent.Kafka.Producer`2"),(WCHAR*)WStr(".ctor"),sig331,2,1,4,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Kafka.KafkaProducerConstructorIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Confluent.Kafka"),(WCHAR*)WStr("Confluent.Kafka.Producer`2"),(WCHAR*)WStr("Produce"),sig332,4,1,4,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Kafka.KafkaProduceSyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Confluent.Kafka"),(WCHAR*)WStr("Confluent.Kafka.Producer`2"),(WCHAR*)WStr("ProduceAsync"),sig265,4,1,4,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Kafka.KafkaProduceAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Confluent.Kafka"),(WCHAR*)WStr("Confluent.Kafka.Producer`2+TypedDeliveryHandlerShim_Action"),(WCHAR*)WStr(".ctor"),sig391,5,1,4,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Kafka.KafkaProduceSyncDeliveryHandlerIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("log4net"),(WCHAR*)WStr("log4net.Appender.AppenderCollection"),(WCHAR*)WStr("ToArray"),sig074,1,2,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.Log4Net.DirectSubmission.AppenderCollectionIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("log4net"),(WCHAR*)WStr("log4net.Appender.AppenderCollection"),(WCHAR*)WStr("ToArray"),sig074,1,1,0,0,1,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.Log4Net.DirectSubmission.AppenderCollectionLegacyIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("log4net"),(WCHAR*)WStr("log4net.Util.AppenderAttachedImpl"),(WCHAR*)WStr("AppendLoopOnAppenders"),sig155,2,1,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Log4Net.AppenderAttachedImplIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MongoDB.Driver"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.CommandUsingCommandMessageWireProtocol`1"),(WCHAR*)WStr("Execute"),sig007,3,3,5,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_3_5_Execute_Integration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MongoDB.Driver"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.CommandUsingCommandMessageWireProtocol`1"),(WCHAR*)WStr("Execute"),sig006,3,2,2,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_Generic_Execute_Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MongoDB.Driver"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.CommandUsingCommandMessageWireProtocol`1"),(WCHAR*)WStr("ExecuteAsync"),sig230,3,3,5,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_3_5_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MongoDB.Driver"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.CommandUsingCommandMessageWireProtocol`1"),(WCHAR*)WStr("ExecuteAsync"),sig229,3,2,1,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MongoDB.Driver"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.CommandUsingCommandMessageWireProtocol`1"),(WCHAR*)WStr("ExecuteAsync"),sig231,3,3,5,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_3_5_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MongoDB.Driver"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.CommandUsingCommandMessageWireProtocol`1"),(WCHAR*)WStr("ExecuteAsync"),sig230,3,2,1,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MongoDB.Driver"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.CommandUsingQueryMessageWireProtocol`1"),(WCHAR*)WStr("Execute"),sig007,3,3,5,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_3_5_Execute_Integration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MongoDB.Driver"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.CommandUsingQueryMessageWireProtocol`1"),(WCHAR*)WStr("Execute"),sig006,3,2,2,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_Generic_Execute_Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MongoDB.Driver"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.CommandUsingQueryMessageWireProtocol`1"),(WCHAR*)WStr("ExecuteAsync"),sig230,3,3,5,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_3_5_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MongoDB.Driver"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.CommandUsingQueryMessageWireProtocol`1"),(WCHAR*)WStr("ExecuteAsync"),sig229,3,2,1,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MongoDB.Driver"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.CommandUsingQueryMessageWireProtocol`1"),(WCHAR*)WStr("ExecuteAsync"),sig231,3,3,5,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_3_5_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MongoDB.Driver"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.CommandUsingQueryMessageWireProtocol`1"),(WCHAR*)WStr("ExecuteAsync"),sig230,3,2,1,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MongoDB.Driver"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.CommandWireProtocol`1"),(WCHAR*)WStr("Execute"),sig007,3,3,5,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_3_5_Execute_Integration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MongoDB.Driver"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.CommandWireProtocol`1"),(WCHAR*)WStr("Execute"),sig006,3,2,2,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_Generic_Execute_Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MongoDB.Driver"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.CommandWireProtocol`1"),(WCHAR*)WStr("ExecuteAsync"),sig230,3,3,5,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_3_5_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MongoDB.Driver"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.CommandWireProtocol`1"),(WCHAR*)WStr("ExecuteAsync"),sig229,3,2,1,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MongoDB.Driver"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.CommandWireProtocol`1"),(WCHAR*)WStr("ExecuteAsync"),sig231,3,3,5,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_3_5_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MongoDB.Driver"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.CommandWireProtocol`1"),(WCHAR*)WStr("ExecuteAsync"),sig230,3,2,1,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MongoDB.Driver"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.GetMoreWireProtocol`1"),(WCHAR*)WStr("Execute"),sig006,3,2,2,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_Generic_Execute_Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MongoDB.Driver"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.GetMoreWireProtocol`1"),(WCHAR*)WStr("ExecuteAsync"),sig229,3,2,1,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MongoDB.Driver"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.GetMoreWireProtocol`1"),(WCHAR*)WStr("ExecuteAsync"),sig230,3,2,1,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MongoDB.Driver"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.QueryWireProtocol`1"),(WCHAR*)WStr("Execute"),sig006,3,2,2,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_Generic_Execute_Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MongoDB.Driver"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.QueryWireProtocol`1"),(WCHAR*)WStr("ExecuteAsync"),sig229,3,2,1,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MongoDB.Driver"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.QueryWireProtocol`1"),(WCHAR*)WStr("ExecuteAsync"),sig230,3,2,1,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MongoDB.Driver"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.WriteWireProtocolBase`1"),(WCHAR*)WStr("Execute"),sig006,3,2,2,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_Generic_Execute_Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MongoDB.Driver"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.WriteWireProtocolBase`1"),(WCHAR*)WStr("ExecuteAsync"),sig229,3,2,1,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MongoDB.Driver"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.WriteWireProtocolBase`1"),(WCHAR*)WStr("ExecuteAsync"),sig230,3,2,1,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MongoDB.Driver.Core"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.CommandUsingCommandMessageWireProtocol`1"),(WCHAR*)WStr("Execute"),sig006,3,2,2,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_Generic_Execute_Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MongoDB.Driver.Core"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.CommandUsingCommandMessageWireProtocol`1"),(WCHAR*)WStr("ExecuteAsync"),sig229,3,2,1,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MongoDB.Driver.Core"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.CommandUsingCommandMessageWireProtocol`1"),(WCHAR*)WStr("ExecuteAsync"),sig230,3,2,1,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MongoDB.Driver.Core"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.CommandUsingQueryMessageWireProtocol`1"),(WCHAR*)WStr("Execute"),sig006,3,2,2,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_Generic_Execute_Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MongoDB.Driver.Core"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.CommandUsingQueryMessageWireProtocol`1"),(WCHAR*)WStr("ExecuteAsync"),sig229,3,2,1,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MongoDB.Driver.Core"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.CommandUsingQueryMessageWireProtocol`1"),(WCHAR*)WStr("ExecuteAsync"),sig230,3,2,1,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MongoDB.Driver.Core"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.CommandWireProtocol`1"),(WCHAR*)WStr("Execute"),sig006,3,2,2,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_Generic_Execute_Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MongoDB.Driver.Core"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.CommandWireProtocol`1"),(WCHAR*)WStr("ExecuteAsync"),sig229,3,2,1,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MongoDB.Driver.Core"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.CommandWireProtocol`1"),(WCHAR*)WStr("ExecuteAsync"),sig230,3,2,1,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MongoDB.Driver.Core"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.GetMoreWireProtocol`1"),(WCHAR*)WStr("Execute"),sig006,3,2,2,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_Generic_Execute_Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MongoDB.Driver.Core"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.GetMoreWireProtocol`1"),(WCHAR*)WStr("ExecuteAsync"),sig229,3,2,1,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MongoDB.Driver.Core"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.KillCursorsWireProtocol"),(WCHAR*)WStr("Execute"),sig348,3,2,2,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_Execute_Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MongoDB.Driver.Core"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.GetMoreWireProtocol`1"),(WCHAR*)WStr("ExecuteAsync"),sig230,3,2,1,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MongoDB.Driver.Core"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.KillCursorsWireProtocol"),(WCHAR*)WStr("Execute"),sig349,3,2,2,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_Execute_Integration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MongoDB.Driver.Core"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.KillCursorsWireProtocol"),(WCHAR*)WStr("ExecuteAsync"),sig206,3,2,1,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MongoDB.Driver.Core"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.QueryWireProtocol`1"),(WCHAR*)WStr("Execute"),sig006,3,2,2,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_Generic_Execute_Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MongoDB.Driver.Core"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.QueryWireProtocol`1"),(WCHAR*)WStr("ExecuteAsync"),sig229,3,2,1,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MongoDB.Driver.Core"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.QueryWireProtocol`1"),(WCHAR*)WStr("ExecuteAsync"),sig230,3,2,1,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MongoDB.Driver.Core"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.WriteWireProtocolBase`1"),(WCHAR*)WStr("Execute"),sig006,3,2,2,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_Generic_Execute_Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MongoDB.Driver.Core"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.WriteWireProtocolBase`1"),(WCHAR*)WStr("ExecuteAsync"),sig229,3,2,1,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("System.Messaging"),(WCHAR*)WStr("System.Messaging.MessageQueue"),(WCHAR*)WStr("Purge"),sig325,1,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Msmq.MessageQueue_Purge_Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MongoDB.Driver.Core"),(WCHAR*)WStr("MongoDB.Driver.Core.WireProtocol.WriteWireProtocolBase`1"),(WCHAR*)WStr("ExecuteAsync"),sig230,3,2,1,0,3,5,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.MongoDb.IWireProtocol_ExecuteAsync_Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("System.Messaging"),(WCHAR*)WStr("System.Messaging.MessageQueue"),(WCHAR*)WStr("Purge"),sig326,1,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Msmq.MessageQueue_Purge_Integration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("System.Messaging"),(WCHAR*)WStr("System.Messaging.MessageQueue"),(WCHAR*)WStr("ReceiveCurrent"),sig161,7,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Msmq.MessageQueue_ReceiveCurrent_Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("System.Messaging"),(WCHAR*)WStr("System.Messaging.MessageQueue"),(WCHAR*)WStr("SendInternal"),sig383,4,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Msmq.MessageQueue_SendInternal_Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.TestPlatform.CrossPlatEngine"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Execution.RunTestsWithSources"),(WCHAR*)WStr("SendSessionEnd"),sig325,1,14,0,0,15,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.RunTestsWithSourcesSendSessionEndIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestAssemblyInfo"),(WCHAR*)WStr("ExecuteAssemblyCleanup"),sig325,1,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestAssemblyInfoExecuteAssemblyCleanupIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("System.Messaging"),(WCHAR*)WStr("System.Messaging.MessageQueue"),(WCHAR*)WStr("SendInternal"),sig384,4,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Msmq.MessageQueue_SendInternal_Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.TestPlatform.CrossPlatEngine"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Execution.RunTestsWithSources"),(WCHAR*)WStr("SendSessionEnd"),sig326,1,14,0,0,15,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.RunTestsWithSourcesSendSessionEndIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestAssemblyInfo"),(WCHAR*)WStr("ExecuteAssemblyCleanup"),sig326,1,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestAssemblyInfoExecuteAssemblyCleanupIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestAssemblyInfo"),(WCHAR*)WStr("RunAssemblyCleanup"),sig178,1,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestAssemblyInfoRunAssemblyCleanupIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestAssemblyInfo"),(WCHAR*)WStr("RunAssemblyInitialize"),sig346,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestAssemblyInfoRunAssemblyInitializeIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestAssemblyInfo"),(WCHAR*)WStr("RunAssemblyInitialize"),sig347,3,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestAssemblyInfoRunAssemblyInitializeIntegrationV3_9"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("ExecuteClassCleanup"),sig325,1,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoExecuteClassCleanupIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("ExecuteClassCleanup"),sig416,3,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoExecuteClassCleanupIntegrationV3_9"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("ExecuteClassCleanup"),sig415,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoRunClassCleanupIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestAssemblyInfo"),(WCHAR*)WStr("RunAssemblyInitialize"),sig347,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestAssemblyInfoRunAssemblyInitializeIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestAssemblyInfo"),(WCHAR*)WStr("RunAssemblyInitialize"),sig348,3,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestAssemblyInfoRunAssemblyInitializeIntegrationV3_9"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("ExecuteClassCleanup"),sig326,1,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoExecuteClassCleanupIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("ExecuteClassCleanup"),sig417,3,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoExecuteClassCleanupIntegrationV3_9"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("ExecuteClassCleanup"),sig416,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoRunClassCleanupIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("RunClassCleanup"),sig184,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoRunClassCleanupIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("RunClassInitialize"),sig412,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoRunClassInitializeIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("RunClassInitialize"),sig413,3,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoRunClassInitializeIntegrationV3_9"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("RunClassInitialize"),sig413,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoRunClassInitializeIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("RunClassInitialize"),sig414,3,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoRunClassInitializeIntegrationV3_9"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestMethodRunner"),(WCHAR*)WStr("Execute"),sig090,1,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestMethodRunnerExecuteIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestMethodRunner"),(WCHAR*)WStr("Execute"),sig093,1,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestMethodRunnerExecuteIntegration3_8"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestMethodRunner"),(WCHAR*)WStr("ExecuteTest"),sig094,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestMethodRunnerExecuteTestIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestMethodRunner"),(WCHAR*)WStr("ExecuteTestAsync"),sig283,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestMethodRunnerExecuteTestIntegrationV3_9"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestMethodRunner"),(WCHAR*)WStr("ExecuteTestAsync"),sig284,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestMethodRunnerExecuteTestIntegrationV3_9"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TypeCache"),(WCHAR*)WStr("GetTestMethodInfo"),sig089,4,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TypeCacheGetTestMethodInfoIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TypeCache"),(WCHAR*)WStr("GetTestMethodInfo"),sig088,3,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TypeCacheGetTestMethodInfoIntegrationV3_9"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.UnitTestRunner"),(WCHAR*)WStr("RunCleanup"),sig086,1,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.UnitTestRunnerRunCleanupIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.UnitTestRunner"),(WCHAR*)WStr("RunSingleTest"),sig091,3,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.UnitTestRunnerRunSingleTestIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.UnitTestRunner"),(WCHAR*)WStr("RunSingleTest"),sig095,4,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.UnitTestRunnerRunSingleTestIntegration3_8"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.UnitTestRunner"),(WCHAR*)WStr("RunSingleTestAsync"),sig284,4,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.UnitTestRunnerRunSingleTestAsyncIntegration3_8"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.UnitTestDiscoverer"),(WCHAR*)WStr("SendTestCases"),sig399,6,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.UnitTestDiscovererSendTestCasesIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestAssemblyInfo"),(WCHAR*)WStr("ExecuteAssemblyCleanup"),sig325,1,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestAssemblyInfoExecuteAssemblyCleanupIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.UnitTestRunner"),(WCHAR*)WStr("RunSingleTestAsync"),sig285,4,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.UnitTestRunnerRunSingleTestAsyncIntegration3_8"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.UnitTestDiscoverer"),(WCHAR*)WStr("SendTestCases"),sig400,6,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.UnitTestDiscovererSendTestCasesIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestAssemblyInfo"),(WCHAR*)WStr("ExecuteAssemblyCleanup"),sig326,1,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestAssemblyInfoExecuteAssemblyCleanupIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestAssemblyInfo"),(WCHAR*)WStr("RunAssemblyCleanup"),sig178,1,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestAssemblyInfoRunAssemblyCleanupIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestAssemblyInfo"),(WCHAR*)WStr("RunAssemblyInitialize"),sig346,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestAssemblyInfoRunAssemblyInitializeIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestAssemblyInfo"),(WCHAR*)WStr("RunAssemblyInitialize"),sig347,3,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestAssemblyInfoRunAssemblyInitializeIntegrationV3_9"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("ExecuteClassCleanup"),sig325,1,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoExecuteClassCleanupIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("ExecuteClassCleanup"),sig416,3,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoExecuteClassCleanupIntegrationV3_9"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("ExecuteClassCleanup"),sig415,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoRunClassCleanupIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("ExecuteClassCleanupAsync"),sig415,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoExecuteClassCleanupAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestAssemblyInfo"),(WCHAR*)WStr("RunAssemblyInitialize"),sig347,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestAssemblyInfoRunAssemblyInitializeIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestAssemblyInfo"),(WCHAR*)WStr("RunAssemblyInitialize"),sig348,3,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestAssemblyInfoRunAssemblyInitializeIntegrationV3_9"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("ExecuteClassCleanup"),sig326,1,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoExecuteClassCleanupIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("ExecuteClassCleanup"),sig417,3,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoExecuteClassCleanupIntegrationV3_9"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("ExecuteClassCleanup"),sig416,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoRunClassCleanupIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("ExecuteClassCleanupAsync"),sig416,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoExecuteClassCleanupAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("RunClassCleanup"),sig184,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoRunClassCleanupIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("RunClassInitialize"),sig412,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoRunClassInitializeIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("RunClassInitialize"),sig413,3,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoRunClassInitializeIntegrationV3_9"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("RunClassInitializeAsync"),sig217,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoRunClassInitializeAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestMethodRunner"),(WCHAR*)WStr("ExecuteTestAsync"),sig283,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestMethodRunnerExecuteTestIntegrationV3_9"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("RunClassInitialize"),sig413,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoRunClassInitializeIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("RunClassInitialize"),sig414,3,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoRunClassInitializeIntegrationV3_9"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("RunClassInitializeAsync"),sig218,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoRunClassInitializeAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestMethodRunner"),(WCHAR*)WStr("ExecuteTestAsync"),sig284,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestMethodRunnerExecuteTestIntegrationV3_9"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TypeCache"),(WCHAR*)WStr("GetTestMethodInfo"),sig089,4,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TypeCacheGetTestMethodInfoIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TypeCache"),(WCHAR*)WStr("GetTestMethodInfo"),sig088,3,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TypeCacheGetTestMethodInfoIntegrationV3_9"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.UnitTestRunner"),(WCHAR*)WStr("RunCleanup"),sig086,1,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.UnitTestRunnerRunCleanupIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.UnitTestRunner"),(WCHAR*)WStr("RunSingleTest"),sig091,3,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.UnitTestRunnerRunSingleTestIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.UnitTestRunner"),(WCHAR*)WStr("RunSingleTest"),sig095,4,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.UnitTestRunnerRunSingleTestIntegration3_8"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.UnitTestRunner"),(WCHAR*)WStr("RunSingleTestAsync"),sig284,4,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.UnitTestRunnerRunSingleTestAsyncIntegration3_8"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.UnitTestDiscoverer"),(WCHAR*)WStr("SendTestCases"),sig399,6,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.UnitTestDiscovererSendTestCasesIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.UnitTestRunner"),(WCHAR*)WStr("RunSingleTestAsync"),sig285,4,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.UnitTestRunnerRunSingleTestAsyncIntegration3_8"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.UnitTestDiscoverer"),(WCHAR*)WStr("SendTestCases"),sig400,6,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.UnitTestDiscovererSendTestCasesIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.TestFramework"),(WCHAR*)WStr("Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute"),(WCHAR*)WStr("Execute"),sig092,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestMethodAttributeExecuteIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.TestFramework"),(WCHAR*)WStr("Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute"),(WCHAR*)WStr("Execute"),sig092,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestMethodAttributeExecuteIntegration"),CallTargetKind::Derived,1,15}, -{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.TestFramework"),(WCHAR*)WStr("Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute"),(WCHAR*)WStr("ExecuteAsync"),sig288,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestMethodAttributeExecuteAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.TestFramework"),(WCHAR*)WStr("Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute"),(WCHAR*)WStr("ExecuteAsync"),sig288,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestMethodAttributeExecuteAsyncIntegration"),CallTargetKind::Derived,1,15}, -{(WCHAR*)WStr("MSTest.TestFramework"),(WCHAR*)WStr("Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute"),(WCHAR*)WStr("ExecuteAsync"),sig288,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestMethodAttributeExecuteAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MSTest.TestFramework"),(WCHAR*)WStr("Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute"),(WCHAR*)WStr("ExecuteAsync"),sig288,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestMethodAttributeExecuteAsyncIntegration"),CallTargetKind::Derived,1,15}, -{(WCHAR*)WStr("MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestAssemblyInfo"),(WCHAR*)WStr("RunAssemblyInitialize"),sig346,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestAssemblyInfoRunAssemblyInitializeIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("ExecuteClassCleanupAsync"),sig415,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoExecuteClassCleanupAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("RunClassInitializeAsync"),sig217,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoRunClassInitializeAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestMethodRunner"),(WCHAR*)WStr("ExecuteTestAsync"),sig283,2,4,0,0,4,2,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestMethodRunnerExecuteTestIntegrationV3_9"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestMethodRunner"),(WCHAR*)WStr("ExecuteTestAsync"),sig287,3,4,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestMethodRunnerExecuteTestIntegrationV4_3"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.TestFramework"),(WCHAR*)WStr("Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute"),(WCHAR*)WStr("ExecuteAsync"),sig289,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestMethodAttributeExecuteAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.TestFramework"),(WCHAR*)WStr("Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute"),(WCHAR*)WStr("ExecuteAsync"),sig289,2,14,0,0,14,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestMethodAttributeExecuteAsyncIntegration"),CallTargetKind::Derived,1,15}, +{(WCHAR*)WStr("MSTest.TestFramework"),(WCHAR*)WStr("Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute"),(WCHAR*)WStr("ExecuteAsync"),sig289,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestMethodAttributeExecuteAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MSTest.TestFramework"),(WCHAR*)WStr("Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute"),(WCHAR*)WStr("ExecuteAsync"),sig289,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestMethodAttributeExecuteAsyncIntegration"),CallTargetKind::Derived,1,15}, +{(WCHAR*)WStr("MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestAssemblyInfo"),(WCHAR*)WStr("RunAssemblyInitialize"),sig347,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestAssemblyInfoRunAssemblyInitializeIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("ExecuteClassCleanupAsync"),sig416,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoExecuteClassCleanupAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestClassInfo"),(WCHAR*)WStr("RunClassInitializeAsync"),sig218,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestClassInfoRunClassInitializeAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestMethodRunner"),(WCHAR*)WStr("ExecuteTestAsync"),sig284,2,4,0,0,4,2,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestMethodRunnerExecuteTestIntegrationV3_9"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestMethodRunner"),(WCHAR*)WStr("ExecuteTestAsync"),sig288,3,4,3,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TestMethodRunnerExecuteTestIntegrationV4_3"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TypeCache"),(WCHAR*)WStr("GetTestMethodInfo"),sig088,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TypeCacheGetTestMethodInfoIntegrationV3_9"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TypeCache"),(WCHAR*)WStr("GetTestMethodInfo"),sig087,2,4,2,1,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.TypeCacheGetTestMethodInfoIntegrationV4"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.UnitTestRunner"),(WCHAR*)WStr("RunSingleTest"),sig095,4,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.UnitTestRunnerRunSingleTestIntegration3_8"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.UnitTestRunner"),(WCHAR*)WStr("RunSingleTest"),sig096,4,4,2,1,4,3,2,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.UnitTestRunnerRunSingleTestIntegration3_8"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.UnitTestRunner"),(WCHAR*)WStr("RunSingleTest"),sig097,5,4,3,3,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.UnitTestRunnerRunSingleTestIntegration3_8"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.UnitTestRunner"),(WCHAR*)WStr("RunSingleTestAsync"),sig284,4,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.UnitTestRunnerRunSingleTestAsyncIntegration3_8"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.UnitTestRunner"),(WCHAR*)WStr("RunSingleTestAsync"),sig285,4,4,2,1,4,3,2,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.UnitTestRunnerRunSingleTestAsyncIntegration3_8"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.UnitTestRunner"),(WCHAR*)WStr("RunSingleTestAsync"),sig286,5,4,3,3,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.UnitTestRunnerRunSingleTestAsyncIntegrationV4_3_3"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.UnitTestDiscoverer"),(WCHAR*)WStr("SendTestCases"),sig372,5,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.UnitTestDiscovererSendTestCasesIntegrationV4"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.UnitTestRunner"),(WCHAR*)WStr("RunSingleTestAsync"),sig285,4,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.UnitTestRunnerRunSingleTestAsyncIntegration3_8"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.UnitTestRunner"),(WCHAR*)WStr("RunSingleTestAsync"),sig286,4,4,2,1,4,3,2,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.UnitTestRunnerRunSingleTestAsyncIntegration3_8"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.UnitTestRunner"),(WCHAR*)WStr("RunSingleTestAsync"),sig287,5,4,3,3,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.UnitTestRunnerRunSingleTestAsyncIntegrationV4_3_3"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MSTestAdapter.PlatformServices"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.UnitTestDiscoverer"),(WCHAR*)WStr("SendTestCases"),sig373,5,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.MsTestV2.UnitTestDiscovererSendTestCasesIntegrationV4"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteDbDataReader"),sig143,2,6,7,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteDbDataReader"),sig143,2,8,0,0,26,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteDbDataReaderAsync"),sig307,3,8,0,0,26,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteDbDataReaderAsync"),sig308,3,8,0,0,26,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteNonQuery"),sig154,1,6,7,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteNonQuery"),sig154,1,8,0,0,26,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteNonQueryAsync"),sig310,2,8,0,0,26,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteNonQueryAsync"),sig311,2,8,0,0,26,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteReader"),sig098,1,6,7,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteReader"),sig099,2,6,7,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteReader"),sig098,1,8,0,0,26,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteReader"),sig099,2,8,0,0,26,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig289,2,8,0,0,26,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig290,3,8,0,0,26,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig290,2,8,0,0,26,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig291,3,8,0,0,26,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteScalar"),sig170,1,6,7,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteScalar"),sig170,1,8,0,0,26,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteScalarAsync"),sig315,2,8,0,0,26,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlDataReader"),(WCHAR*)WStr("Close"),sig325,1,6,7,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, -{(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlDataReader"),(WCHAR*)WStr("Close"),sig325,1,8,0,0,26,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteScalarAsync"),sig316,2,8,0,0,26,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlDataReader"),(WCHAR*)WStr("Close"),sig326,1,6,7,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlDataReader"),(WCHAR*)WStr("Close"),sig326,1,8,0,0,26,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlDataReader"),(WCHAR*)WStr("GetString"),sig179,2,6,7,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlDataReader"),(WCHAR*)WStr("GetString"),sig179,2,8,0,0,26,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlDataReader"),(WCHAR*)WStr("GetValue"),sig172,2,6,7,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlDataReader"),(WCHAR*)WStr("GetValue"),sig172,2,8,0,0,26,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlDataReader"),(WCHAR*)WStr("Read"),sig129,1,6,7,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlDataReader"),(WCHAR*)WStr("Read"),sig129,1,8,0,0,26,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadIntegration"),CallTargetKind::Default,4,15}, -{(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlDataReader"),(WCHAR*)WStr("ReadAsync"),sig315,2,6,7,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, -{(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlDataReader"),(WCHAR*)WStr("ReadAsync"),sig315,2,8,0,0,26,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlDataReader"),(WCHAR*)WStr("ReadAsync"),sig316,2,6,7,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("MySql.Data"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlDataReader"),(WCHAR*)WStr("ReadAsync"),sig316,2,8,0,0,26,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteDbDataReader"),sig143,2,0,61,0,0,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteDbDataReaderAsync"),sig307,3,0,61,0,0,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteDbDataReaderAsync"),sig308,3,0,61,0,0,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteNonQuery"),sig154,1,0,61,0,0,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteNonQueryAsync"),sig310,2,0,61,0,0,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteNonQueryAsync"),sig311,2,0,61,0,0,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteReader"),sig098,1,0,61,0,0,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteReader"),sig099,2,0,61,0,0,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteScalar"),sig170,1,0,61,0,0,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteScalarAsync"),sig315,2,0,61,0,0,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySql.Data.MySqlClient.MySqlCommand"),(WCHAR*)WStr("ExecuteScalarAsync"),sig316,2,0,61,0,0,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySqlConnector.MySqlCommand"),(WCHAR*)WStr("ExecuteDbDataReader"),sig143,2,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySqlConnector.MySqlCommand"),(WCHAR*)WStr("ExecuteDbDataReaderAsync"),sig307,3,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySqlConnector.MySqlCommand"),(WCHAR*)WStr("ExecuteDbDataReaderAsync"),sig308,3,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySqlConnector.MySqlCommand"),(WCHAR*)WStr("ExecuteNonQuery"),sig154,1,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySqlConnector.MySqlCommand"),(WCHAR*)WStr("ExecuteNonQueryAsync"),sig310,2,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySqlConnector.MySqlCommand"),(WCHAR*)WStr("ExecuteNonQueryAsync"),sig311,2,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySqlConnector.MySqlCommand"),(WCHAR*)WStr("ExecuteReader"),sig100,1,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySqlConnector.MySqlCommand"),(WCHAR*)WStr("ExecuteReader"),sig101,2,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySqlConnector.MySqlCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig292,2,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySqlConnector.MySqlCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig291,3,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySqlConnector.MySqlCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig293,2,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySqlConnector.MySqlCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig292,3,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySqlConnector.MySqlCommand"),(WCHAR*)WStr("ExecuteScalar"),sig170,1,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySqlConnector.MySqlCommand"),(WCHAR*)WStr("ExecuteScalarAsync"),sig315,2,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySqlConnector.MySqlDataReader"),(WCHAR*)WStr("Close"),sig325,1,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySqlConnector.MySqlCommand"),(WCHAR*)WStr("ExecuteScalarAsync"),sig316,2,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySqlConnector.MySqlDataReader"),(WCHAR*)WStr("Close"),sig326,1,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySqlConnector.MySqlDataReader"),(WCHAR*)WStr("GetString"),sig179,2,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySqlConnector.MySqlDataReader"),(WCHAR*)WStr("GetValue"),sig172,2,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySqlConnector.MySqlDataReader"),(WCHAR*)WStr("Read"),sig129,1,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadIntegration"),CallTargetKind::Default,4,15}, -{(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySqlConnector.MySqlDataReader"),(WCHAR*)WStr("ReadAsync"),sig315,2,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("MySqlConnector"),(WCHAR*)WStr("MySqlConnector.MySqlDataReader"),(WCHAR*)WStr("ReadAsync"),sig316,2,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("NLog"),(WCHAR*)WStr("NLog.Config.LoggingConfigurationFileLoader"),(WCHAR*)WStr("Load"),sig102,3,6,0,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.NLog.DirectSubmission.LoggingConfigurationFileLoaderLoadInstrumentation"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("NLog"),(WCHAR*)WStr("NLog.LogFactory"),(WCHAR*)WStr("ActivateLoggingConfiguration"),sig349,2,6,0,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.NLog.DirectSubmission.LogFactoryActivateLoggingConfigurationInstrumentation"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("NLog"),(WCHAR*)WStr("NLog.LogFactory"),(WCHAR*)WStr("ActivateLoggingConfiguration"),sig350,2,6,0,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.NLog.DirectSubmission.LogFactoryActivateLoggingConfigurationInstrumentation"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("NLog"),(WCHAR*)WStr("NLog.LogFactory"),(WCHAR*)WStr("BuildLoggerConfiguration"),sig103,3,5,0,0,5,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.NLog.DirectSubmission.LogFactoryBuildLoggerConfiguration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("NLog"),(WCHAR*)WStr("NLog.LogFactory"),(WCHAR*)WStr("BuildLoggerConfiguration"),sig392,3,5,0,0,5,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.NLog.DirectSubmission.LogFactoryGetConfigurationForLoggerInstrumentation"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("NLog"),(WCHAR*)WStr("NLog.LogFactory"),(WCHAR*)WStr("GetConfigurationForLogger"),sig392,3,2,1,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.NLog.DirectSubmission.LogFactoryGetConfigurationForLoggerInstrumentation"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("NLog"),(WCHAR*)WStr("NLog.LoggerImpl"),(WCHAR*)WStr("Write"),sig407,5,1,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.NLog.LogsInjection.LoggerImplWriteIntegrationV4"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("NLog"),(WCHAR*)WStr("NLog.LoggerImpl"),(WCHAR*)WStr("Write"),sig407,5,5,0,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.NLog.LogsInjection.LoggerImplWriteIntegrationV5"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("NLog"),(WCHAR*)WStr("NLog.LogFactory"),(WCHAR*)WStr("BuildLoggerConfiguration"),sig393,3,5,0,0,5,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.NLog.DirectSubmission.LogFactoryGetConfigurationForLoggerInstrumentation"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("NLog"),(WCHAR*)WStr("NLog.LogFactory"),(WCHAR*)WStr("GetConfigurationForLogger"),sig393,3,2,1,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.NLog.DirectSubmission.LogFactoryGetConfigurationForLoggerInstrumentation"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("NLog"),(WCHAR*)WStr("NLog.LoggerImpl"),(WCHAR*)WStr("Write"),sig408,5,1,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.NLog.LogsInjection.LoggerImplWriteIntegrationV4"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("NLog"),(WCHAR*)WStr("NLog.LoggerImpl"),(WCHAR*)WStr("Write"),sig408,5,5,0,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.NLog.LogsInjection.LoggerImplWriteIntegrationV5"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Npgsql"),(WCHAR*)WStr("Npgsql.NpgsqlCommand"),(WCHAR*)WStr("ExecuteDbDataReader"),sig143,2,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Npgsql"),(WCHAR*)WStr("Npgsql.NpgsqlCommand"),(WCHAR*)WStr("ExecuteDbDataReaderAsync"),sig307,3,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Npgsql"),(WCHAR*)WStr("Npgsql.NpgsqlCommand"),(WCHAR*)WStr("ExecuteDbDataReaderAsync"),sig308,3,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Npgsql"),(WCHAR*)WStr("Npgsql.NpgsqlCommand"),(WCHAR*)WStr("ExecuteNonQuery"),sig154,1,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Npgsql"),(WCHAR*)WStr("Npgsql.NpgsqlCommand"),(WCHAR*)WStr("ExecuteNonQueryAsync"),sig310,2,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Npgsql"),(WCHAR*)WStr("Npgsql.NpgsqlCommand"),(WCHAR*)WStr("ExecuteNonQueryAsync"),sig311,2,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Npgsql"),(WCHAR*)WStr("Npgsql.NpgsqlCommand"),(WCHAR*)WStr("ExecuteReader"),sig104,1,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Npgsql"),(WCHAR*)WStr("Npgsql.NpgsqlCommand"),(WCHAR*)WStr("ExecuteReader"),sig105,2,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Npgsql"),(WCHAR*)WStr("Npgsql.NpgsqlCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig293,3,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Npgsql"),(WCHAR*)WStr("Npgsql.NpgsqlCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig294,3,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Npgsql"),(WCHAR*)WStr("Npgsql.NpgsqlCommand"),(WCHAR*)WStr("ExecuteScalar"),sig170,1,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Npgsql"),(WCHAR*)WStr("Npgsql.NpgsqlCommand"),(WCHAR*)WStr("ExecuteScalarAsync"),sig315,2,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Npgsql"),(WCHAR*)WStr("Npgsql.NpgsqlCommand"),(WCHAR*)WStr("ExecuteScalarAsync"),sig316,2,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Npgsql"),(WCHAR*)WStr("Npgsql.NpgsqlDataReader"),(WCHAR*)WStr("Close"),sig207,4,4,0,0,8,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.Npgsql.ReaderCloseNpgsqlIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("Npgsql"),(WCHAR*)WStr("Npgsql.NpgsqlDataReader"),(WCHAR*)WStr("GetString"),sig179,2,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("Npgsql"),(WCHAR*)WStr("Npgsql.NpgsqlDataReader"),(WCHAR*)WStr("GetValue"),sig172,2,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("Npgsql"),(WCHAR*)WStr("Npgsql.NpgsqlDataReader"),(WCHAR*)WStr("Read"),sig129,1,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadIntegration"),CallTargetKind::Default,4,15}, -{(WCHAR*)WStr("Npgsql"),(WCHAR*)WStr("Npgsql.NpgsqlDataReader"),(WCHAR*)WStr("ReadAsync"),sig315,2,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("Npgsql"),(WCHAR*)WStr("Npgsql.NpgsqlDataReader"),(WCHAR*)WStr("ReadAsync"),sig316,2,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("nunit.framework"),(WCHAR*)WStr("NUnit.Framework.Internal.Execution.CommandBuilder"),(WCHAR*)WStr("MakeSkipCommand"),sig106,2,3,0,0,3,6,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.NUnit.NUnitCommandBuilderMakeTestCommandIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("nunit.framework"),(WCHAR*)WStr("NUnit.Framework.Internal.Execution.CommandBuilder"),(WCHAR*)WStr("MakeTestCommand"),sig108,2,3,0,0,3,6,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.NUnit.NUnitCommandBuilderMakeTestCommandIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("nunit.framework"),(WCHAR*)WStr("NUnit.Framework.Internal.Execution.SimpleWorkItem"),(WCHAR*)WStr(".ctor"),sig351,4,3,13,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.NUnit.SimpleWorkItemctor2Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("nunit.framework"),(WCHAR*)WStr("NUnit.Framework.Internal.Execution.SimpleWorkItem"),(WCHAR*)WStr(".ctor"),sig350,3,3,7,0,3,12,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.NUnit.SimpleWorkItemctorIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("nunit.framework"),(WCHAR*)WStr("NUnit.Framework.Internal.Execution.SimpleWorkItem"),(WCHAR*)WStr(".ctor"),sig352,4,3,13,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.NUnit.SimpleWorkItemctor2Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("nunit.framework"),(WCHAR*)WStr("NUnit.Framework.Internal.Execution.SimpleWorkItem"),(WCHAR*)WStr(".ctor"),sig351,3,3,7,0,3,12,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.NUnit.SimpleWorkItemctorIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("nunit.framework"),(WCHAR*)WStr("NUnit.Framework.Internal.Execution.SimpleWorkItem"),(WCHAR*)WStr("MakeTestCommand"),sig107,1,3,7,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.NUnit.NUnitSimpleWorkItemMakeTestCommandIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("nunit.framework"),(WCHAR*)WStr("NUnit.Framework.Internal.Execution.WorkItem"),(WCHAR*)WStr("PerformWork"),sig325,1,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.NUnit.NUnitWorkItemPerformWorkIntegration"),CallTargetKind::Derived,1,15}, -{(WCHAR*)WStr("nunit.framework"),(WCHAR*)WStr("NUnit.Framework.Internal.Execution.WorkItem"),(WCHAR*)WStr("WorkItemComplete"),sig325,1,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.NUnit.NUnitWorkItemWorkItemCompleteIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("nunit.framework"),(WCHAR*)WStr("NUnit.Framework.Internal.Execution.WorkItem"),(WCHAR*)WStr("PerformWork"),sig326,1,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.NUnit.NUnitWorkItemPerformWorkIntegration"),CallTargetKind::Derived,1,15}, +{(WCHAR*)WStr("nunit.framework"),(WCHAR*)WStr("NUnit.Framework.Internal.Execution.WorkItem"),(WCHAR*)WStr("WorkItemComplete"),sig326,1,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.NUnit.NUnitWorkItemWorkItemCompleteIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("nunit.framework"),(WCHAR*)WStr("NUnit.Framework.Internal.Reflect"),(WCHAR*)WStr("InvokeMethod"),sig175,4,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.NUnit.NUnitReflectInvokeMethodIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.FeatureFlags.OpenFeature"),(WCHAR*)WStr("Datadog.FeatureFlags.OpenFeature.FeatureFlagsSdk"),(WCHAR*)WStr("AccumulateSpanEnrichment"),sig381,7,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkAccumulateSpanEnrichmentIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.FeatureFlags.OpenFeature"),(WCHAR*)WStr("Datadog.FeatureFlags.OpenFeature.FeatureFlagsSdk"),(WCHAR*)WStr("AccumulateSpanEnrichment"),sig382,7,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkAccumulateSpanEnrichmentIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.FeatureFlags.OpenFeature"),(WCHAR*)WStr("Datadog.FeatureFlags.OpenFeature.FeatureFlagsSdk"),(WCHAR*)WStr("Evaluate"),sig061,6,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkEvaluateIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.FeatureFlags.OpenFeature"),(WCHAR*)WStr("Datadog.FeatureFlags.OpenFeature.FeatureFlagsSdk"),(WCHAR*)WStr("InitializeAsync"),sig217,2,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkInitializeAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.FeatureFlags.OpenFeature"),(WCHAR*)WStr("Datadog.FeatureFlags.OpenFeature.FeatureFlagsSdk"),(WCHAR*)WStr("IsAvailable"),sig129,1,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkIsAvailableIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.FeatureFlags.OpenFeature"),(WCHAR*)WStr("Datadog.FeatureFlags.OpenFeature.FeatureFlagsSdk"),(WCHAR*)WStr("IsSpanEnrichmentEnabled"),sig129,1,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkIsSpanEnrichmentEnabledIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Datadog.FeatureFlags.OpenFeature"),(WCHAR*)WStr("Datadog.FeatureFlags.OpenFeature.FeatureFlagsSdk"),(WCHAR*)WStr("RegisterOnNewConfigEventHandler"),sig355,2,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkRegisterOnNewConfigEventHandlerIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.FeatureFlags.OpenFeature"),(WCHAR*)WStr("Datadog.FeatureFlags.OpenFeature.FeatureFlagsSdk"),(WCHAR*)WStr("RegisterOnNewConfigEventHandler"),sig356,2,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkRegisterOnNewConfigEventHandlerIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("OpenTelemetry"),(WCHAR*)WStr("OpenTelemetry.Trace.TracerProviderBuilderExtensions"),(WCHAR*)WStr("Build"),sig118,2,1,0,0,1,0,0,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.OpenTelemetry.TracerProviderBuilderIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("OpenTelemetry.Api"),(WCHAR*)WStr("OpenTelemetry.Baggage"),(WCHAR*)WStr("ClearBaggage"),sig112,2,1,0,0,1,0,0,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.OpenTelemetry.OTelBaggage_ClearBaggageIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("OpenTelemetry.Api"),(WCHAR*)WStr("OpenTelemetry.Baggage"),(WCHAR*)WStr("get_Current"),sig111,1,1,0,0,1,0,0,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.OpenTelemetry.OTelBaggage_GetCurrentIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("OpenTelemetry.Api"),(WCHAR*)WStr("OpenTelemetry.Baggage"),(WCHAR*)WStr("RemoveBaggage"),sig114,3,1,0,0,1,0,0,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.OpenTelemetry.OTelBaggage_RemoveBaggageIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("OpenTelemetry.Api"),(WCHAR*)WStr("OpenTelemetry.Baggage"),(WCHAR*)WStr("set_Current"),sig353,2,1,0,0,1,0,0,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.OpenTelemetry.OTelBaggage_SetCurrentIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("OpenTelemetry.Api"),(WCHAR*)WStr("OpenTelemetry.Baggage"),(WCHAR*)WStr("set_Current"),sig354,2,1,0,0,1,0,0,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.OpenTelemetry.OTelBaggage_SetCurrentIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("OpenTelemetry.Api"),(WCHAR*)WStr("OpenTelemetry.Baggage"),(WCHAR*)WStr("SetBaggage"),sig115,4,1,0,0,1,0,0,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.OpenTelemetry.OTelBaggage_SetBaggageIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("OpenTelemetry.Api"),(WCHAR*)WStr("OpenTelemetry.Baggage"),(WCHAR*)WStr("SetBaggage"),sig113,3,1,0,0,1,0,0,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.OpenTelemetry.OTelBaggage_SetBaggageItemsIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("OpenTelemetry.Api"),(WCHAR*)WStr("OpenTelemetry.Trace.Tracer"),(WCHAR*)WStr("StartRootSpan"),sig116,6,1,0,0,1,0,0,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.OpenTelemetry.StartRootSpanIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("OpenTelemetry.Api"),(WCHAR*)WStr("OpenTelemetry.Trace.Tracer"),(WCHAR*)WStr("StartSpan"),sig117,7,1,0,0,1,0,0,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.OpenTelemetry.StartSpanIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Oracle.DataAccess"),(WCHAR*)WStr("Oracle.DataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteDbDataReader"),sig143,2,4,122,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Oracle.DataAccess"),(WCHAR*)WStr("Oracle.DataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteDbDataReaderAsync"),sig307,3,4,122,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Oracle.DataAccess"),(WCHAR*)WStr("Oracle.DataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteDbDataReaderAsync"),sig308,3,4,122,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Oracle.DataAccess"),(WCHAR*)WStr("Oracle.DataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteNonQuery"),sig154,1,4,122,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Oracle.DataAccess"),(WCHAR*)WStr("Oracle.DataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteNonQueryAsync"),sig310,2,4,122,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Oracle.DataAccess"),(WCHAR*)WStr("Oracle.DataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteNonQueryAsync"),sig311,2,4,122,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Oracle.DataAccess"),(WCHAR*)WStr("Oracle.DataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReader"),sig121,1,4,122,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Oracle.DataAccess"),(WCHAR*)WStr("Oracle.DataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReader"),sig122,2,4,122,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Oracle.DataAccess"),(WCHAR*)WStr("Oracle.DataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig294,1,4,122,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Oracle.DataAccess"),(WCHAR*)WStr("Oracle.DataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig295,2,4,122,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Oracle.DataAccess"),(WCHAR*)WStr("Oracle.DataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig297,2,4,122,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Oracle.DataAccess"),(WCHAR*)WStr("Oracle.DataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig296,3,4,122,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Oracle.DataAccess"),(WCHAR*)WStr("Oracle.DataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig295,1,4,122,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Oracle.DataAccess"),(WCHAR*)WStr("Oracle.DataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig296,2,4,122,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Oracle.DataAccess"),(WCHAR*)WStr("Oracle.DataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig298,2,4,122,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Oracle.DataAccess"),(WCHAR*)WStr("Oracle.DataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig297,3,4,122,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Oracle.DataAccess"),(WCHAR*)WStr("Oracle.DataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteScalar"),sig170,1,4,122,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Oracle.DataAccess"),(WCHAR*)WStr("Oracle.DataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteScalarAsync"),sig315,2,4,122,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Oracle.DataAccess"),(WCHAR*)WStr("Oracle.DataAccess.Client.OracleDataReader"),(WCHAR*)WStr("Close"),sig325,1,4,122,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("Oracle.DataAccess"),(WCHAR*)WStr("Oracle.DataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteScalarAsync"),sig316,2,4,122,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Oracle.DataAccess"),(WCHAR*)WStr("Oracle.DataAccess.Client.OracleDataReader"),(WCHAR*)WStr("Close"),sig326,1,4,122,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("Oracle.DataAccess"),(WCHAR*)WStr("Oracle.DataAccess.Client.OracleDataReader"),(WCHAR*)WStr("GetString"),sig179,2,4,122,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("Oracle.DataAccess"),(WCHAR*)WStr("Oracle.DataAccess.Client.OracleDataReader"),(WCHAR*)WStr("GetValue"),sig172,2,4,122,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("Oracle.DataAccess"),(WCHAR*)WStr("Oracle.DataAccess.Client.OracleDataReader"),(WCHAR*)WStr("Read"),sig129,1,4,122,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadIntegration"),CallTargetKind::Default,4,15}, -{(WCHAR*)WStr("Oracle.DataAccess"),(WCHAR*)WStr("Oracle.DataAccess.Client.OracleDataReader"),(WCHAR*)WStr("ReadAsync"),sig315,2,4,122,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("Oracle.DataAccess"),(WCHAR*)WStr("Oracle.DataAccess.Client.OracleDataReader"),(WCHAR*)WStr("ReadAsync"),sig316,2,4,122,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteDbDataReader"),sig143,2,2,0,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteDbDataReader"),sig143,2,23,0,0,23,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteDbDataReaderAsync"),sig307,3,2,0,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteDbDataReaderAsync"),sig307,3,23,0,0,23,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteDbDataReaderAsync"),sig308,3,2,0,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteDbDataReaderAsync"),sig308,3,23,0,0,23,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteNonQuery"),sig154,1,2,0,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteNonQuery"),sig154,1,23,0,0,23,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteNonQueryAsync"),sig310,2,2,0,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteNonQueryAsync"),sig310,2,23,0,0,23,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteNonQueryAsync"),sig311,2,2,0,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteNonQueryAsync"),sig311,2,23,0,0,23,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReader"),sig123,1,2,0,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReader"),sig124,2,2,0,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReader"),sig123,1,23,0,0,23,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReader"),sig124,2,23,0,0,23,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig298,1,2,0,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig299,2,2,0,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig301,2,2,0,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig300,3,2,0,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig298,1,23,0,0,23,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig299,2,23,0,0,23,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig301,2,23,0,0,23,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig300,3,23,0,0,23,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig299,1,2,0,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig300,2,2,0,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig302,2,2,0,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig301,3,2,0,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig299,1,23,0,0,23,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig300,2,23,0,0,23,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig302,2,23,0,0,23,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig301,3,23,0,0,23,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteScalar"),sig170,1,2,0,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteScalar"),sig170,1,23,0,0,23,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteScalarAsync"),sig315,2,2,0,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteScalarAsync"),sig315,2,23,0,0,23,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleDataReader"),(WCHAR*)WStr("Close"),sig325,1,2,0,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, -{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleDataReader"),(WCHAR*)WStr("Close"),sig325,1,23,0,0,23,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteScalarAsync"),sig316,2,2,0,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleCommand"),(WCHAR*)WStr("ExecuteScalarAsync"),sig316,2,23,0,0,23,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleDataReader"),(WCHAR*)WStr("Close"),sig326,1,2,0,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleDataReader"),(WCHAR*)WStr("Close"),sig326,1,23,0,0,23,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleDataReader"),(WCHAR*)WStr("GetString"),sig179,2,2,0,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleDataReader"),(WCHAR*)WStr("GetString"),sig179,2,23,0,0,23,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleDataReader"),(WCHAR*)WStr("GetValue"),sig172,2,2,0,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleDataReader"),(WCHAR*)WStr("GetValue"),sig172,2,23,0,0,23,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleDataReader"),(WCHAR*)WStr("Read"),sig129,1,2,0,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleDataReader"),(WCHAR*)WStr("Read"),sig129,1,23,0,0,23,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadIntegration"),CallTargetKind::Default,4,15}, -{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleDataReader"),(WCHAR*)WStr("ReadAsync"),sig315,2,2,0,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, -{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleDataReader"),(WCHAR*)WStr("ReadAsync"),sig315,2,23,0,0,23,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleDataReader"),(WCHAR*)WStr("ReadAsync"),sig316,2,2,0,0,4,122,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("Oracle.ManagedDataAccess"),(WCHAR*)WStr("Oracle.ManagedDataAccess.Client.OracleDataReader"),(WCHAR*)WStr("ReadAsync"),sig316,2,23,0,0,23,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("System"),(WCHAR*)WStr("System.Diagnostics.Process"),(WCHAR*)WStr("Start"),sig148,1,1,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Process.ProcessStartIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("System.Diagnostics.Process"),(WCHAR*)WStr("System.Diagnostics.Process"),(WCHAR*)WStr("Start"),sig148,1,1,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Process.ProcessStartIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Google.Protobuf"),(WCHAR*)WStr("Google.Protobuf.IBufferMessage"),(WCHAR*)WStr("InternalMergeFrom"),sig339,2,3,15,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Protobuf.BufferMessageInternalMergeFromIntegration"),CallTargetKind::Interface,1,15}, -{(WCHAR*)WStr("Google.Protobuf"),(WCHAR*)WStr("Google.Protobuf.IBufferMessage"),(WCHAR*)WStr("InternalWriteTo"),sig340,2,3,15,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Protobuf.BufferMessageInternalWriteToIntegration"),CallTargetKind::Interface,1,15}, -{(WCHAR*)WStr("Google.Protobuf"),(WCHAR*)WStr("Google.Protobuf.IMessage"),(WCHAR*)WStr("MergeFrom"),sig337,2,3,13,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Protobuf.MessageMergeFromIntegration"),CallTargetKind::Interface,1,15}, -{(WCHAR*)WStr("Google.Protobuf"),(WCHAR*)WStr("Google.Protobuf.IMessage"),(WCHAR*)WStr("MergeFrom"),sig337,2,3,0,0,3,12,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Protobuf.OldMessageMergeFromIntegration"),CallTargetKind::Interface,1,15}, -{(WCHAR*)WStr("Google.Protobuf"),(WCHAR*)WStr("Google.Protobuf.IMessage"),(WCHAR*)WStr("WriteTo"),sig338,2,3,13,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Protobuf.MessageWriteToIntegration"),CallTargetKind::Interface,1,15}, -{(WCHAR*)WStr("Google.Protobuf"),(WCHAR*)WStr("Google.Protobuf.IMessage"),(WCHAR*)WStr("WriteTo"),sig338,2,3,0,0,3,12,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Protobuf.OldMessageWriteToIntegration"),CallTargetKind::Interface,1,15}, +{(WCHAR*)WStr("Google.Protobuf"),(WCHAR*)WStr("Google.Protobuf.IBufferMessage"),(WCHAR*)WStr("InternalMergeFrom"),sig340,2,3,15,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Protobuf.BufferMessageInternalMergeFromIntegration"),CallTargetKind::Interface,1,15}, +{(WCHAR*)WStr("Google.Protobuf"),(WCHAR*)WStr("Google.Protobuf.IBufferMessage"),(WCHAR*)WStr("InternalWriteTo"),sig341,2,3,15,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Protobuf.BufferMessageInternalWriteToIntegration"),CallTargetKind::Interface,1,15}, +{(WCHAR*)WStr("Google.Protobuf"),(WCHAR*)WStr("Google.Protobuf.IMessage"),(WCHAR*)WStr("MergeFrom"),sig338,2,3,13,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Protobuf.MessageMergeFromIntegration"),CallTargetKind::Interface,1,15}, +{(WCHAR*)WStr("Google.Protobuf"),(WCHAR*)WStr("Google.Protobuf.IMessage"),(WCHAR*)WStr("MergeFrom"),sig338,2,3,0,0,3,12,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Protobuf.OldMessageMergeFromIntegration"),CallTargetKind::Interface,1,15}, +{(WCHAR*)WStr("Google.Protobuf"),(WCHAR*)WStr("Google.Protobuf.IMessage"),(WCHAR*)WStr("WriteTo"),sig339,2,3,13,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Protobuf.MessageWriteToIntegration"),CallTargetKind::Interface,1,15}, +{(WCHAR*)WStr("Google.Protobuf"),(WCHAR*)WStr("Google.Protobuf.IMessage"),(WCHAR*)WStr("WriteTo"),sig339,2,3,0,0,3,12,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Protobuf.OldMessageWriteToIntegration"),CallTargetKind::Interface,1,15}, {(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.AsyncDefaultBasicConsumer"),(WCHAR*)WStr("HandleBasicDeliver"),sig215,8,3,6,9,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.BasicDeliverAsyncIntegration"),CallTargetKind::Derived,1,15}, {(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.AsyncDefaultBasicConsumer"),(WCHAR*)WStr("HandleBasicDeliverAsync"),sig216,9,7,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.BasicDeliverAsyncAsyncIntegration"),CallTargetKind::Derived,1,15}, -{(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.DefaultBasicConsumer"),(WCHAR*)WStr("HandleBasicDeliver"),sig405,8,3,6,9,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.BasicDeliverIntegration"),CallTargetKind::Derived,1,15}, -{(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.Framing.Impl.Model"),(WCHAR*)WStr("_Private_BasicPublish"),sig401,6,3,6,9,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.BasicPublishIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.Framing.Impl.Model"),(WCHAR*)WStr("_Private_ExchangeDeclare"),sig402,9,3,6,9,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.ExchangeDeclareIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.Framing.Impl.Model"),(WCHAR*)WStr("_Private_QueueDeclare"),sig395,8,3,6,9,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.QueueDeclareIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.DefaultBasicConsumer"),(WCHAR*)WStr("HandleBasicDeliver"),sig406,8,3,6,9,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.BasicDeliverIntegration"),CallTargetKind::Derived,1,15}, +{(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.Framing.Impl.Model"),(WCHAR*)WStr("_Private_BasicPublish"),sig402,6,3,6,9,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.BasicPublishIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.Framing.Impl.Model"),(WCHAR*)WStr("_Private_ExchangeDeclare"),sig403,9,3,6,9,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.ExchangeDeclareIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.Framing.Impl.Model"),(WCHAR*)WStr("_Private_QueueDeclare"),sig396,8,3,6,9,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.QueueDeclareIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.IAsyncBasicConsumer"),(WCHAR*)WStr("HandleBasicDeliver"),sig215,8,3,6,9,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.BasicDeliverAsyncIntegration"),CallTargetKind::Interface,1,15}, {(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.IAsyncBasicConsumer"),(WCHAR*)WStr("HandleBasicDeliverAsync"),sig216,9,7,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.BasicDeliverAsyncAsyncIntegration"),CallTargetKind::Interface,1,15}, -{(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.IBasicConsumer"),(WCHAR*)WStr("HandleBasicDeliver"),sig405,8,3,6,9,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.BasicDeliverIntegration"),CallTargetKind::Interface,1,15}, -{(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.Impl.Channel"),(WCHAR*)WStr("BasicConsumeAsync"),sig316,9,7,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.BasicConsumeAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.Impl.Channel"),(WCHAR*)WStr("BasicGetAsync"),sig302,4,7,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.BasicGetAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.Impl.Channel"),(WCHAR*)WStr("BasicPublishAsync"),sig319,7,7,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.BasicPublishAsyncCachedStringsIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.Impl.Channel"),(WCHAR*)WStr("BasicPublishAsync"),sig320,7,7,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.BasicPublishAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.IBasicConsumer"),(WCHAR*)WStr("HandleBasicDeliver"),sig406,8,3,6,9,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.BasicDeliverIntegration"),CallTargetKind::Interface,1,15}, +{(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.Impl.Channel"),(WCHAR*)WStr("BasicConsumeAsync"),sig317,9,7,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.BasicConsumeAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.Impl.Channel"),(WCHAR*)WStr("BasicGetAsync"),sig303,4,7,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.BasicGetAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.Impl.Channel"),(WCHAR*)WStr("BasicPublishAsync"),sig320,7,7,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.BasicPublishAsyncCachedStringsIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.Impl.Channel"),(WCHAR*)WStr("BasicPublishAsync"),sig321,7,7,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.BasicPublishAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.Impl.Channel"),(WCHAR*)WStr("ExchangeDeclareAsync"),sig213,9,7,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.ExchangeDeclareAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.Impl.Channel"),(WCHAR*)WStr("PopulateBasicPropertiesHeaders"),sig126,4,7,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.PopulateBasicPropertiesHeadersIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.Impl.Channel"),(WCHAR*)WStr("QueueBindAsync"),sig214,7,7,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.QueueBindAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.Impl.Channel"),(WCHAR*)WStr("QueueDeclareAsync"),sig303,9,7,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.QueueDeclareAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.Impl.Channel"),(WCHAR*)WStr("QueueDeclareAsync"),sig304,9,7,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.QueueDeclareAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.Impl.ModelBase"),(WCHAR*)WStr("BasicConsume"),sig182,8,3,6,9,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.BasicConsumeIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.Impl.ModelBase"),(WCHAR*)WStr("BasicGet"),sig125,3,3,6,9,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.BasicGetIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.Impl.ModelBase"),(WCHAR*)WStr("QueueBind"),sig404,5,3,6,9,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.QueueBindIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("RabbitMQ.Client"),(WCHAR*)WStr("RabbitMQ.Client.Impl.ModelBase"),(WCHAR*)WStr("QueueBind"),sig405,5,3,6,9,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.QueueBindIntegration"),CallTargetKind::Default,1,15}, #if _WIN32 {(WCHAR*)WStr("System.Runtime.Remoting"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.BinaryClientFormatterSink"),(WCHAR*)WStr("SyncProcessMessage"),sig177,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Remoting.Client.SyncProcessMessageIntegration"),CallTargetKind::Default,1,1}, {(WCHAR*)WStr("System.Runtime.Remoting"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.BinaryServerFormatterSink"),(WCHAR*)WStr("ProcessMessage"),sig176,8,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Remoting.Server.ProcessMessageIntegration"),CallTargetKind::Default,1,1}, -{(WCHAR*)WStr("System.Runtime.Remoting"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.BinaryServerFormatterSink"),(WCHAR*)WStr("SerializeResponse"),sig385,5,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Remoting.Server.BinarySerializeResponseIntegration"),CallTargetKind::Default,1,1}, +{(WCHAR*)WStr("System.Runtime.Remoting"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.BinaryServerFormatterSink"),(WCHAR*)WStr("SerializeResponse"),sig386,5,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Remoting.Server.BinarySerializeResponseIntegration"),CallTargetKind::Default,1,1}, {(WCHAR*)WStr("System.Runtime.Remoting"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.Http.HttpClientTransportSink"),(WCHAR*)WStr("ProcessAndSend"),sig165,4,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Remoting.Client.HttpProcessAndSendIntegration"),CallTargetKind::Default,1,1}, -{(WCHAR*)WStr("System.Runtime.Remoting"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.Http.HttpClientTransportSink"),(WCHAR*)WStr("ProcessMessage"),sig386,6,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Remoting.Client.HttpProcessMessageIntegration"),CallTargetKind::Default,1,1}, -{(WCHAR*)WStr("System.Runtime.Remoting"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.Http.HttpClientTransportSink"),(WCHAR*)WStr("ProcessResponseException"),sig380,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Remoting.Client.HttpProcessResponseExceptionIntegration"),CallTargetKind::Default,1,1}, -{(WCHAR*)WStr("System.Runtime.Remoting"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.Http.HttpClientTransportSink"),(WCHAR*)WStr("ReceiveAndProcess"),sig379,4,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Remoting.Client.HttpReceiveAndProcessIntegration"),CallTargetKind::Default,1,1}, -{(WCHAR*)WStr("System.Runtime.Remoting"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.Ipc.IpcClientTransportSink"),(WCHAR*)WStr("ProcessMessage"),sig386,6,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Remoting.Client.IpcTcpProcessMessageIntegration"),CallTargetKind::Default,1,1}, +{(WCHAR*)WStr("System.Runtime.Remoting"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.Http.HttpClientTransportSink"),(WCHAR*)WStr("ProcessMessage"),sig387,6,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Remoting.Client.HttpProcessMessageIntegration"),CallTargetKind::Default,1,1}, +{(WCHAR*)WStr("System.Runtime.Remoting"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.Http.HttpClientTransportSink"),(WCHAR*)WStr("ProcessResponseException"),sig381,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Remoting.Client.HttpProcessResponseExceptionIntegration"),CallTargetKind::Default,1,1}, +{(WCHAR*)WStr("System.Runtime.Remoting"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.Http.HttpClientTransportSink"),(WCHAR*)WStr("ReceiveAndProcess"),sig380,4,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Remoting.Client.HttpReceiveAndProcessIntegration"),CallTargetKind::Default,1,1}, +{(WCHAR*)WStr("System.Runtime.Remoting"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.Ipc.IpcClientTransportSink"),(WCHAR*)WStr("ProcessMessage"),sig387,6,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Remoting.Client.IpcTcpProcessMessageIntegration"),CallTargetKind::Default,1,1}, {(WCHAR*)WStr("System.Runtime.Remoting"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.SoapClientFormatterSink"),(WCHAR*)WStr("SyncProcessMessage"),sig177,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Remoting.Client.SyncProcessMessageIntegration"),CallTargetKind::Default,1,1}, {(WCHAR*)WStr("System.Runtime.Remoting"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.SoapServerFormatterSink"),(WCHAR*)WStr("ProcessMessage"),sig176,8,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Remoting.Server.ProcessMessageIntegration"),CallTargetKind::Default,1,1}, -{(WCHAR*)WStr("System.Runtime.Remoting"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.SoapServerFormatterSink"),(WCHAR*)WStr("SerializeResponse"),sig384,6,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Remoting.Server.SoapSerializeResponseIntegration"),CallTargetKind::Default,1,1}, -{(WCHAR*)WStr("System.Runtime.Remoting"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink"),(WCHAR*)WStr("ProcessMessage"),sig386,6,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Remoting.Client.IpcTcpProcessMessageIntegration"),CallTargetKind::Default,1,1}, +{(WCHAR*)WStr("System.Runtime.Remoting"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.SoapServerFormatterSink"),(WCHAR*)WStr("SerializeResponse"),sig385,6,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Remoting.Server.SoapSerializeResponseIntegration"),CallTargetKind::Default,1,1}, +{(WCHAR*)WStr("System.Runtime.Remoting"),(WCHAR*)WStr("System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink"),(WCHAR*)WStr("ProcessMessage"),sig387,6,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Remoting.Client.IpcTcpProcessMessageIntegration"),CallTargetKind::Default,1,1}, #endif -{(WCHAR*)WStr("WebDriver"),(WCHAR*)WStr("OpenQA.Selenium.Remote.HttpCommandExecutor"),(WCHAR*)WStr("OnSendingRemoteHttpRequest"),sig352,2,3,12,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.Selenium.HttpCommandExecutorOnSendingRemoteHttpRequestIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("WebDriver"),(WCHAR*)WStr("OpenQA.Selenium.Remote.HttpCommandExecutor"),(WCHAR*)WStr("OnSendingRemoteHttpRequest"),sig353,2,3,12,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.Selenium.HttpCommandExecutorOnSendingRemoteHttpRequestIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("WebDriver"),(WCHAR*)WStr("OpenQA.Selenium.Remote.RemoteWebDriver"),(WCHAR*)WStr("Execute"),sig109,3,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.Selenium.WebDriverExecuteIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("WebDriver"),(WCHAR*)WStr("OpenQA.Selenium.Remote.RemoteWebDriver"),(WCHAR*)WStr("Execute"),sig109,3,3,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.Selenium.WebDriverExecuteIntegration"),CallTargetKind::Derived,1,15}, {(WCHAR*)WStr("WebDriver"),(WCHAR*)WStr("OpenQA.Selenium.WebDriver"),(WCHAR*)WStr("Execute"),sig110,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.Selenium.WebDriverExecuteIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("WebDriver"),(WCHAR*)WStr("OpenQA.Selenium.WebDriver"),(WCHAR*)WStr("Execute"),sig110,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.Selenium.WebDriverExecuteIntegration"),CallTargetKind::Derived,1,15}, -{(WCHAR*)WStr("Serilog"),(WCHAR*)WStr("Serilog.Core.Logger"),(WCHAR*)WStr("Dispatch"),sig354,2,2,0,0,4,3,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.Serilog.LogsInjection.LoggerDispatchInstrumentation"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Serilog"),(WCHAR*)WStr("Serilog.Core.Logger"),(WCHAR*)WStr("PostLevelCheckEmit"),sig354,2,4,4,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.Serilog.LogsInjection.LoggerDispatchInstrumentation"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Serilog"),(WCHAR*)WStr("Serilog.Core.Pipeline.Logger"),(WCHAR*)WStr("Dispatch"),sig354,2,1,4,0,1,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.Serilog.LogsInjection.LoggerDispatchInstrumentation"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Serilog"),(WCHAR*)WStr("Serilog.Core.Logger"),(WCHAR*)WStr("Dispatch"),sig355,2,2,0,0,4,3,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.Serilog.LogsInjection.LoggerDispatchInstrumentation"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Serilog"),(WCHAR*)WStr("Serilog.Core.Logger"),(WCHAR*)WStr("PostLevelCheckEmit"),sig355,2,4,4,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.Serilog.LogsInjection.LoggerDispatchInstrumentation"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Serilog"),(WCHAR*)WStr("Serilog.Core.Pipeline.Logger"),(WCHAR*)WStr("Dispatch"),sig355,2,1,4,0,1,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.Serilog.LogsInjection.LoggerDispatchInstrumentation"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Serilog"),(WCHAR*)WStr("Serilog.LoggerConfiguration"),(WCHAR*)WStr("CreateLogger"),sig127,1,1,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Logging.Serilog.DirectSubmission.LoggerConfigurationInstrumentation"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.Serverless.Compat"),(WCHAR*)WStr("Datadog.Serverless.CompatibilityLayer"),(WCHAR*)WStr("CalculateDogStatsDPipeName"),sig178,1,0,0,0,1,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Serverless.CompatibilityLayer_CalculateDogStatsDPipeName_Integration"),CallTargetKind::Default,1,14}, {(WCHAR*)WStr("Datadog.Serverless.Compat"),(WCHAR*)WStr("Datadog.Serverless.CompatibilityLayer"),(WCHAR*)WStr("CalculateTracePipeName"),sig178,1,0,0,0,1,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Serverless.CompatibilityLayer_CalculateTracePipeName_Integration"),CallTargetKind::Default,1,14}, {(WCHAR*)WStr("ServiceStack.Redis"),(WCHAR*)WStr("ServiceStack.Redis.RedisNativeClient"),(WCHAR*)WStr("SendReceive"),sig002,5,4,0,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.ServiceStack.RedisNativeClientSendReceiveIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("ServiceStack.Redis"),(WCHAR*)WStr("ServiceStack.Redis.RedisNativeClient"),(WCHAR*)WStr("SendReceive"),sig003,6,6,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.ServiceStack.RedisNativeClientSendReceiveIntegration_6_2_0"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.Data.SqlClient"),(WCHAR*)WStr("Microsoft.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteDbDataReader"),sig143,2,1,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.Data.SqlClient"),(WCHAR*)WStr("Microsoft.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteDbDataReaderAsync"),sig307,3,1,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.Data.SqlClient"),(WCHAR*)WStr("Microsoft.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteDbDataReaderAsync"),sig308,3,1,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.Data.SqlClient"),(WCHAR*)WStr("Microsoft.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteNonQuery"),sig154,1,1,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.Data.SqlClient"),(WCHAR*)WStr("Microsoft.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteNonQueryAsync"),sig310,2,1,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.Data.SqlClient"),(WCHAR*)WStr("Microsoft.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteNonQueryAsync"),sig311,2,1,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.Data.SqlClient"),(WCHAR*)WStr("Microsoft.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteReader"),sig082,1,1,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.Data.SqlClient"),(WCHAR*)WStr("Microsoft.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteReader"),sig083,2,1,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.Data.SqlClient"),(WCHAR*)WStr("Microsoft.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig278,1,1,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.Data.SqlClient"),(WCHAR*)WStr("Microsoft.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig281,2,1,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.Data.SqlClient"),(WCHAR*)WStr("Microsoft.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig279,2,1,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.Data.SqlClient"),(WCHAR*)WStr("Microsoft.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig280,3,1,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.Data.SqlClient"),(WCHAR*)WStr("Microsoft.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig279,1,1,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.Data.SqlClient"),(WCHAR*)WStr("Microsoft.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig282,2,1,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.Data.SqlClient"),(WCHAR*)WStr("Microsoft.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig280,2,1,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.Data.SqlClient"),(WCHAR*)WStr("Microsoft.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig281,3,1,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.Data.SqlClient"),(WCHAR*)WStr("Microsoft.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteScalar"),sig170,1,1,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.Data.SqlClient"),(WCHAR*)WStr("Microsoft.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteScalarAsync"),sig315,2,1,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.Data.SqlClient"),(WCHAR*)WStr("Microsoft.Data.SqlClient.SqlDataReader"),(WCHAR*)WStr("Close"),sig325,1,1,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("Microsoft.Data.SqlClient"),(WCHAR*)WStr("Microsoft.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteScalarAsync"),sig316,2,1,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.Data.SqlClient"),(WCHAR*)WStr("Microsoft.Data.SqlClient.SqlDataReader"),(WCHAR*)WStr("Close"),sig326,1,1,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("Microsoft.Data.SqlClient"),(WCHAR*)WStr("Microsoft.Data.SqlClient.SqlDataReader"),(WCHAR*)WStr("GetString"),sig179,2,1,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("Microsoft.Data.SqlClient"),(WCHAR*)WStr("Microsoft.Data.SqlClient.SqlDataReader"),(WCHAR*)WStr("GetValue"),sig172,2,1,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("Microsoft.Data.SqlClient"),(WCHAR*)WStr("Microsoft.Data.SqlClient.SqlDataReader"),(WCHAR*)WStr("Read"),sig129,1,1,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadIntegration"),CallTargetKind::Default,4,15}, -{(WCHAR*)WStr("Microsoft.Data.SqlClient"),(WCHAR*)WStr("Microsoft.Data.SqlClient.SqlDataReader"),(WCHAR*)WStr("ReadAsync"),sig315,2,1,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("Microsoft.Data.SqlClient"),(WCHAR*)WStr("Microsoft.Data.SqlClient.SqlDataReader"),(WCHAR*)WStr("ReadAsync"),sig316,2,1,0,0,7,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteDbDataReader"),sig143,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteDbDataReaderAsync"),sig307,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteDbDataReaderAsync"),sig308,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteNonQuery"),sig154,1,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteNonQueryAsync"),sig310,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteNonQueryAsync"),sig311,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteReader"),sig144,1,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteReader"),sig145,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig308,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig309,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteScalar"),sig170,1,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteScalarAsync"),sig315,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.SqlClient.SqlDataReader"),(WCHAR*)WStr("Close"),sig325,1,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteScalarAsync"),sig316,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.SqlClient.SqlDataReader"),(WCHAR*)WStr("Close"),sig326,1,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.SqlClient.SqlDataReader"),(WCHAR*)WStr("GetString"),sig179,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.SqlClient.SqlDataReader"),(WCHAR*)WStr("GetValue"),sig172,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.SqlClient.SqlDataReader"),(WCHAR*)WStr("Read"),sig129,1,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadIntegration"),CallTargetKind::Default,4,15}, -{(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.SqlClient.SqlDataReader"),(WCHAR*)WStr("ReadAsync"),sig315,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("System.Data"),(WCHAR*)WStr("System.Data.SqlClient.SqlDataReader"),(WCHAR*)WStr("ReadAsync"),sig316,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("System.Data.SqlClient"),(WCHAR*)WStr("System.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteDbDataReader"),sig143,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("System.Data.SqlClient"),(WCHAR*)WStr("System.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteDbDataReaderAsync"),sig307,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("System.Data.SqlClient"),(WCHAR*)WStr("System.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteDbDataReaderAsync"),sig308,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("System.Data.SqlClient"),(WCHAR*)WStr("System.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteNonQuery"),sig154,1,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("System.Data.SqlClient"),(WCHAR*)WStr("System.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteNonQueryAsync"),sig310,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("System.Data.SqlClient"),(WCHAR*)WStr("System.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteNonQueryAsync"),sig311,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("System.Data.SqlClient"),(WCHAR*)WStr("System.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteReader"),sig144,1,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("System.Data.SqlClient"),(WCHAR*)WStr("System.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteReader"),sig145,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("System.Data.SqlClient"),(WCHAR*)WStr("System.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig308,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("System.Data.SqlClient"),(WCHAR*)WStr("System.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig309,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("System.Data.SqlClient"),(WCHAR*)WStr("System.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteScalar"),sig170,1,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("System.Data.SqlClient"),(WCHAR*)WStr("System.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteScalarAsync"),sig315,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("System.Data.SqlClient"),(WCHAR*)WStr("System.Data.SqlClient.SqlDataReader"),(WCHAR*)WStr("Close"),sig325,1,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("System.Data.SqlClient"),(WCHAR*)WStr("System.Data.SqlClient.SqlCommand"),(WCHAR*)WStr("ExecuteScalarAsync"),sig316,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("System.Data.SqlClient"),(WCHAR*)WStr("System.Data.SqlClient.SqlDataReader"),(WCHAR*)WStr("Close"),sig326,1,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("System.Data.SqlClient"),(WCHAR*)WStr("System.Data.SqlClient.SqlDataReader"),(WCHAR*)WStr("GetString"),sig179,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("System.Data.SqlClient"),(WCHAR*)WStr("System.Data.SqlClient.SqlDataReader"),(WCHAR*)WStr("GetValue"),sig172,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("System.Data.SqlClient"),(WCHAR*)WStr("System.Data.SqlClient.SqlDataReader"),(WCHAR*)WStr("Read"),sig129,1,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadIntegration"),CallTargetKind::Default,4,15}, -{(WCHAR*)WStr("System.Data.SqlClient"),(WCHAR*)WStr("System.Data.SqlClient.SqlDataReader"),(WCHAR*)WStr("ReadAsync"),sig315,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("System.Data.SqlClient"),(WCHAR*)WStr("System.Data.SqlClient.SqlDataReader"),(WCHAR*)WStr("ReadAsync"),sig316,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("Microsoft.Data.Sqlite"),(WCHAR*)WStr("Microsoft.Data.Sqlite.SqliteCommand"),(WCHAR*)WStr("ExecuteDbDataReader"),sig143,2,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.Data.Sqlite"),(WCHAR*)WStr("Microsoft.Data.Sqlite.SqliteCommand"),(WCHAR*)WStr("ExecuteDbDataReaderAsync"),sig307,3,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.Data.Sqlite"),(WCHAR*)WStr("Microsoft.Data.Sqlite.SqliteCommand"),(WCHAR*)WStr("ExecuteDbDataReaderAsync"),sig308,3,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.Data.Sqlite"),(WCHAR*)WStr("Microsoft.Data.Sqlite.SqliteCommand"),(WCHAR*)WStr("ExecuteNonQuery"),sig154,1,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.Data.Sqlite"),(WCHAR*)WStr("Microsoft.Data.Sqlite.SqliteCommand"),(WCHAR*)WStr("ExecuteReader"),sig084,1,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.Data.Sqlite"),(WCHAR*)WStr("Microsoft.Data.Sqlite.SqliteCommand"),(WCHAR*)WStr("ExecuteReader"),sig085,2,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.Data.Sqlite"),(WCHAR*)WStr("Microsoft.Data.Sqlite.SqliteCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig282,3,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.Data.Sqlite"),(WCHAR*)WStr("Microsoft.Data.Sqlite.SqliteCommand"),(WCHAR*)WStr("ExecuteReaderAsync"),sig283,3,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorAndCancellationAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.Data.Sqlite"),(WCHAR*)WStr("Microsoft.Data.Sqlite.SqliteCommand"),(WCHAR*)WStr("ExecuteScalar"),sig170,1,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.Data.Sqlite"),(WCHAR*)WStr("Microsoft.Data.Sqlite.SqliteDataReader"),(WCHAR*)WStr("Close"),sig325,1,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("Microsoft.Data.Sqlite"),(WCHAR*)WStr("Microsoft.Data.Sqlite.SqliteDataReader"),(WCHAR*)WStr("Close"),sig326,1,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("Microsoft.Data.Sqlite"),(WCHAR*)WStr("Microsoft.Data.Sqlite.SqliteDataReader"),(WCHAR*)WStr("GetString"),sig179,2,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("Microsoft.Data.Sqlite"),(WCHAR*)WStr("Microsoft.Data.Sqlite.SqliteDataReader"),(WCHAR*)WStr("GetValue"),sig172,2,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("Microsoft.Data.Sqlite"),(WCHAR*)WStr("Microsoft.Data.Sqlite.SqliteDataReader"),(WCHAR*)WStr("Read"),sig129,1,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadIntegration"),CallTargetKind::Default,4,15}, -{(WCHAR*)WStr("Microsoft.Data.Sqlite"),(WCHAR*)WStr("Microsoft.Data.Sqlite.SqliteDataReader"),(WCHAR*)WStr("ReadAsync"),sig315,2,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("Microsoft.Data.Sqlite"),(WCHAR*)WStr("Microsoft.Data.Sqlite.SqliteDataReader"),(WCHAR*)WStr("ReadAsync"),sig316,2,2,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("System.Data.SQLite"),(WCHAR*)WStr("System.Data.SQLite.SQLiteCommand"),(WCHAR*)WStr("ExecuteDbDataReader"),sig143,2,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("System.Data.SQLite"),(WCHAR*)WStr("System.Data.SQLite.SQLiteCommand"),(WCHAR*)WStr("ExecuteNonQuery"),sig154,1,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("System.Data.SQLite"),(WCHAR*)WStr("System.Data.SQLite.SQLiteCommand"),(WCHAR*)WStr("ExecuteNonQuery"),sig156,2,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteNonQueryWithBehaviorIntegration"),CallTargetKind::Default,1,15}, @@ -1199,94 +1201,94 @@ std::vector callTargets = {(WCHAR*)WStr("System.Data.SQLite"),(WCHAR*)WStr("System.Data.SQLite.SQLiteCommand"),(WCHAR*)WStr("ExecuteReader"),sig147,2,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteReaderWithBehaviorIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("System.Data.SQLite"),(WCHAR*)WStr("System.Data.SQLite.SQLiteCommand"),(WCHAR*)WStr("ExecuteScalar"),sig170,1,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("System.Data.SQLite"),(WCHAR*)WStr("System.Data.SQLite.SQLiteCommand"),(WCHAR*)WStr("ExecuteScalar"),sig171,2,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.CommandExecuteScalarWithBehaviorIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("System.Data.SQLite"),(WCHAR*)WStr("System.Data.SQLite.SQLiteDataReader"),(WCHAR*)WStr("Close"),sig325,1,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("System.Data.SQLite"),(WCHAR*)WStr("System.Data.SQLite.SQLiteDataReader"),(WCHAR*)WStr("Close"),sig326,1,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderCloseIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("System.Data.SQLite"),(WCHAR*)WStr("System.Data.SQLite.SQLiteDataReader"),(WCHAR*)WStr("GetString"),sig179,2,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("System.Data.SQLite"),(WCHAR*)WStr("System.Data.SQLite.SQLiteDataReader"),(WCHAR*)WStr("GetValue"),sig172,2,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderGetStringIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("System.Data.SQLite"),(WCHAR*)WStr("System.Data.SQLite.SQLiteDataReader"),(WCHAR*)WStr("Read"),sig129,1,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadIntegration"),CallTargetKind::Default,4,15}, -{(WCHAR*)WStr("System.Data.SQLite"),(WCHAR*)WStr("System.Data.SQLite.SQLiteDataReader"),(WCHAR*)WStr("ReadAsync"),sig315,2,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, +{(WCHAR*)WStr("System.Data.SQLite"),(WCHAR*)WStr("System.Data.SQLite.SQLiteDataReader"),(WCHAR*)WStr("ReadAsync"),sig316,2,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AdoNet.ReaderReadAsyncIntegration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("RestSharp"),(WCHAR*)WStr("RestSharp.Extensions.StringExtensions"),(WCHAR*)WStr("UrlEncode"),sig183,3,104,0,0,112,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RestSharp.UrlEncode2Integration"),CallTargetKind::Default,4,15}, {(WCHAR*)WStr("RestSharp"),(WCHAR*)WStr("RestSharp.Extensions.StringExtensions"),(WCHAR*)WStr("UrlEncode"),sig181,2,104,0,0,112,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.RestSharp.UrlEncodeIntegration"),CallTargetKind::Default,4,15}, -{(WCHAR*)WStr("StackExchange.Redis"),(WCHAR*)WStr("StackExchange.Redis.ConnectionMultiplexer"),(WCHAR*)WStr("ExecuteAsyncImpl"),sig222,5,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.ConnectionMultiplexerExecuteAsyncImplIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("StackExchange.Redis"),(WCHAR*)WStr("StackExchange.Redis.ConnectionMultiplexer"),(WCHAR*)WStr("ExecuteAsyncImpl"),sig223,6,2,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.ConnectionMultiplexerExecuteAsyncImplIntegration_2_6_45"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("StackExchange.Redis"),(WCHAR*)WStr("StackExchange.Redis.ConnectionMultiplexer"),(WCHAR*)WStr("ExecuteAsyncImpl"),sig223,5,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.ConnectionMultiplexerExecuteAsyncImplIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("StackExchange.Redis"),(WCHAR*)WStr("StackExchange.Redis.ConnectionMultiplexer"),(WCHAR*)WStr("ExecuteAsyncImpl"),sig224,6,2,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.ConnectionMultiplexerExecuteAsyncImplIntegration_2_6_45"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("StackExchange.Redis"),(WCHAR*)WStr("StackExchange.Redis.ConnectionMultiplexer"),(WCHAR*)WStr("ExecuteSyncImpl"),sig000,4,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.ConnectionMultiplexerExecuteSyncImplIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("StackExchange.Redis"),(WCHAR*)WStr("StackExchange.Redis.ConnectionMultiplexer"),(WCHAR*)WStr("ExecuteSyncImpl"),sig001,5,2,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.ConnectionMultiplexerExecuteSyncImplIntegration_2_6_45"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("StackExchange.Redis"),(WCHAR*)WStr("StackExchange.Redis.ConnectionMultiplexer"),(WCHAR*)WStr("SelectServer"),sig128,2,1,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.ConnectionMultiplexerSelectServerIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("StackExchange.Redis"),(WCHAR*)WStr("StackExchange.Redis.RedisBase"),(WCHAR*)WStr("ExecuteAsync"),sig219,4,1,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.RedisExecuteAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("StackExchange.Redis"),(WCHAR*)WStr("StackExchange.Redis.RedisBase"),(WCHAR*)WStr("ExecuteAsync"),sig218,5,2,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.RedisExecuteAsyncIntegration_2_6_48"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("StackExchange.Redis"),(WCHAR*)WStr("StackExchange.Redis.RedisBase"),(WCHAR*)WStr("ExecuteAsync"),sig220,4,1,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.RedisExecuteAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("StackExchange.Redis"),(WCHAR*)WStr("StackExchange.Redis.RedisBase"),(WCHAR*)WStr("ExecuteAsync"),sig219,5,2,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.RedisExecuteAsyncIntegration_2_6_48"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("StackExchange.Redis"),(WCHAR*)WStr("StackExchange.Redis.RedisBase"),(WCHAR*)WStr("ExecuteSync"),sig001,5,1,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.RedisExecuteSyncDefaultIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("StackExchange.Redis"),(WCHAR*)WStr("StackExchange.Redis.RedisBase"),(WCHAR*)WStr("ExecuteSync"),sig000,4,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.RedisExecuteSyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("StackExchange.Redis"),(WCHAR*)WStr("StackExchange.Redis.RedisBatch"),(WCHAR*)WStr("ExecuteAsync"),sig219,4,1,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.RedisExecuteAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("StackExchange.Redis"),(WCHAR*)WStr("StackExchange.Redis.RedisBatch"),(WCHAR*)WStr("ExecuteAsync"),sig218,5,2,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.RedisExecuteAsyncIntegration_2_6_48"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("StackExchange.Redis"),(WCHAR*)WStr("StackExchange.Redis.RedisTransaction"),(WCHAR*)WStr("ExecuteAsync"),sig219,4,1,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.RedisExecuteAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("StackExchange.Redis"),(WCHAR*)WStr("StackExchange.Redis.RedisTransaction"),(WCHAR*)WStr("ExecuteAsync"),sig218,5,2,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.RedisExecuteAsyncIntegration_2_6_48"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("StackExchange.Redis.StrongName"),(WCHAR*)WStr("StackExchange.Redis.ConnectionMultiplexer"),(WCHAR*)WStr("ExecuteAsyncImpl"),sig222,5,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.ConnectionMultiplexerExecuteAsyncImplIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("StackExchange.Redis.StrongName"),(WCHAR*)WStr("StackExchange.Redis.ConnectionMultiplexer"),(WCHAR*)WStr("ExecuteAsyncImpl"),sig223,6,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.ConnectionMultiplexerExecuteAsyncImplIntegration_2_6_45"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("StackExchange.Redis"),(WCHAR*)WStr("StackExchange.Redis.RedisBatch"),(WCHAR*)WStr("ExecuteAsync"),sig220,4,1,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.RedisExecuteAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("StackExchange.Redis"),(WCHAR*)WStr("StackExchange.Redis.RedisBatch"),(WCHAR*)WStr("ExecuteAsync"),sig219,5,2,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.RedisExecuteAsyncIntegration_2_6_48"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("StackExchange.Redis"),(WCHAR*)WStr("StackExchange.Redis.RedisTransaction"),(WCHAR*)WStr("ExecuteAsync"),sig220,4,1,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.RedisExecuteAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("StackExchange.Redis"),(WCHAR*)WStr("StackExchange.Redis.RedisTransaction"),(WCHAR*)WStr("ExecuteAsync"),sig219,5,2,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.RedisExecuteAsyncIntegration_2_6_48"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("StackExchange.Redis.StrongName"),(WCHAR*)WStr("StackExchange.Redis.ConnectionMultiplexer"),(WCHAR*)WStr("ExecuteAsyncImpl"),sig223,5,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.ConnectionMultiplexerExecuteAsyncImplIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("StackExchange.Redis.StrongName"),(WCHAR*)WStr("StackExchange.Redis.ConnectionMultiplexer"),(WCHAR*)WStr("ExecuteAsyncImpl"),sig224,6,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.ConnectionMultiplexerExecuteAsyncImplIntegration_2_6_45"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("StackExchange.Redis.StrongName"),(WCHAR*)WStr("StackExchange.Redis.ConnectionMultiplexer"),(WCHAR*)WStr("ExecuteSyncImpl"),sig000,4,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.ConnectionMultiplexerExecuteSyncImplIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("StackExchange.Redis.StrongName"),(WCHAR*)WStr("StackExchange.Redis.ConnectionMultiplexer"),(WCHAR*)WStr("ExecuteSyncImpl"),sig001,5,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.ConnectionMultiplexerExecuteSyncImplIntegration_2_6_45"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("StackExchange.Redis.StrongName"),(WCHAR*)WStr("StackExchange.Redis.RedisBase"),(WCHAR*)WStr("ExecuteAsync"),sig219,4,1,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.RedisExecuteAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("StackExchange.Redis.StrongName"),(WCHAR*)WStr("StackExchange.Redis.RedisBase"),(WCHAR*)WStr("ExecuteAsync"),sig218,5,2,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.RedisExecuteAsyncIntegration_2_6_48"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("StackExchange.Redis.StrongName"),(WCHAR*)WStr("StackExchange.Redis.RedisBase"),(WCHAR*)WStr("ExecuteAsync"),sig220,4,1,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.RedisExecuteAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("StackExchange.Redis.StrongName"),(WCHAR*)WStr("StackExchange.Redis.RedisBase"),(WCHAR*)WStr("ExecuteAsync"),sig219,5,2,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.RedisExecuteAsyncIntegration_2_6_48"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("StackExchange.Redis.StrongName"),(WCHAR*)WStr("StackExchange.Redis.RedisBase"),(WCHAR*)WStr("ExecuteSync"),sig001,5,1,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.RedisExecuteSyncDefaultIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("StackExchange.Redis.StrongName"),(WCHAR*)WStr("StackExchange.Redis.RedisBase"),(WCHAR*)WStr("ExecuteSync"),sig000,4,1,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.RedisExecuteSyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("StackExchange.Redis.StrongName"),(WCHAR*)WStr("StackExchange.Redis.RedisBatch"),(WCHAR*)WStr("ExecuteAsync"),sig219,4,1,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.RedisExecuteAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("StackExchange.Redis.StrongName"),(WCHAR*)WStr("StackExchange.Redis.RedisBatch"),(WCHAR*)WStr("ExecuteAsync"),sig218,5,2,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.RedisExecuteAsyncIntegration_2_6_48"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("StackExchange.Redis.StrongName"),(WCHAR*)WStr("StackExchange.Redis.RedisTransaction"),(WCHAR*)WStr("ExecuteAsync"),sig219,4,1,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.RedisExecuteAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("StackExchange.Redis.StrongName"),(WCHAR*)WStr("StackExchange.Redis.RedisTransaction"),(WCHAR*)WStr("ExecuteAsync"),sig218,5,2,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.RedisExecuteAsyncIntegration_2_6_48"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("StackExchange.Redis.StrongName"),(WCHAR*)WStr("StackExchange.Redis.RedisBatch"),(WCHAR*)WStr("ExecuteAsync"),sig220,4,1,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.RedisExecuteAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("StackExchange.Redis.StrongName"),(WCHAR*)WStr("StackExchange.Redis.RedisBatch"),(WCHAR*)WStr("ExecuteAsync"),sig219,5,2,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.RedisExecuteAsyncIntegration_2_6_48"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("StackExchange.Redis.StrongName"),(WCHAR*)WStr("StackExchange.Redis.RedisTransaction"),(WCHAR*)WStr("ExecuteAsync"),sig220,4,1,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.RedisExecuteAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("StackExchange.Redis.StrongName"),(WCHAR*)WStr("StackExchange.Redis.RedisTransaction"),(WCHAR*)WStr("ExecuteAsync"),sig219,5,2,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Redis.StackExchange.RedisExecuteAsyncIntegration_2_6_48"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Microsoft.AspNetCore.Diagnostics"),(WCHAR*)WStr("Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware"),(WCHAR*)WStr("DisplayException"),sig203,3,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.StackTraceLeak.DeveloperExceptionPageMiddlewareIntegration"),CallTargetKind::Default,4,14}, {(WCHAR*)WStr("Microsoft.AspNetCore.Diagnostics"),(WCHAR*)WStr("Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware"),(WCHAR*)WStr("DisplayException"),sig200,2,3,0,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.StackTraceLeak.DeveloperExceptionPageMiddlewareIntegration_Pre_3_0_0"),CallTargetKind::Default,4,14}, {(WCHAR*)WStr("Microsoft.AspNetCore.Diagnostics"),(WCHAR*)WStr("Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl"),(WCHAR*)WStr("DisplayException"),sig200,2,7,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.StackTraceLeak.DeveloperExceptionPageMiddlewareIntegration_Pre_3_0_0"),CallTargetKind::Default,4,14}, #if _WIN32 -{(WCHAR*)WStr("System.Web"),(WCHAR*)WStr("System.Web.HttpResponse"),(WCHAR*)WStr("WriteErrorMessage"),sig375,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.StackTraceLeak.HttpResponseIntegration"),CallTargetKind::Default,4,1}, +{(WCHAR*)WStr("System.Web"),(WCHAR*)WStr("System.Web.HttpResponse"),(WCHAR*)WStr("WriteErrorMessage"),sig376,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.StackTraceLeak.HttpResponseIntegration"),CallTargetKind::Default,4,1}, #endif -{(WCHAR*)WStr("System.Security.Cryptography"),(WCHAR*)WStr("System.Security.Cryptography.SymmetricAlgorithm"),(WCHAR*)WStr(".ctor"),sig325,1,7,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.CryptographyAlgorithm.SymmetricAlgorithmIntegration"),CallTargetKind::Default,4,14}, -{(WCHAR*)WStr("System.Security.Cryptography.Primitives"),(WCHAR*)WStr("System.Security.Cryptography.SymmetricAlgorithm"),(WCHAR*)WStr(".ctor"),sig325,1,1,0,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.CryptographyAlgorithm.SymmetricAlgorithmIntegration"),CallTargetKind::Default,4,14}, -{(WCHAR*)WStr("Microsoft.TestPlatform.PlatformAbstractions"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformAssemblyResolver"),(WCHAR*)WStr(".ctor"),sig325,1,15,0,0,15,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.PlatformAssemblyResolverAssemblyResolverEventIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("System.Security.Cryptography"),(WCHAR*)WStr("System.Security.Cryptography.SymmetricAlgorithm"),(WCHAR*)WStr(".ctor"),sig326,1,7,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.CryptographyAlgorithm.SymmetricAlgorithmIntegration"),CallTargetKind::Default,4,14}, +{(WCHAR*)WStr("System.Security.Cryptography.Primitives"),(WCHAR*)WStr("System.Security.Cryptography.SymmetricAlgorithm"),(WCHAR*)WStr(".ctor"),sig326,1,1,0,0,6,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.CryptographyAlgorithm.SymmetricAlgorithmIntegration"),CallTargetKind::Default,4,14}, +{(WCHAR*)WStr("Microsoft.TestPlatform.PlatformAbstractions"),(WCHAR*)WStr("Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformAssemblyResolver"),(WCHAR*)WStr(".ctor"),sig326,1,15,0,0,15,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.PlatformAssemblyResolverAssemblyResolverEventIntegration"),CallTargetKind::Default,1,15}, #if _WIN32 {(WCHAR*)WStr("System.ServiceModel"),(WCHAR*)WStr("System.ServiceModel.Dispatcher.AsyncMethodInvoker"),(WCHAR*)WStr("InvokeBegin"),sig152,5,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Wcf.AsyncMethodInvoker_InvokeBegin_Integration"),CallTargetKind::Default,1,1}, {(WCHAR*)WStr("System.ServiceModel"),(WCHAR*)WStr("System.ServiceModel.Dispatcher.AsyncMethodInvoker"),(WCHAR*)WStr("InvokeEnd"),sig174,4,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Wcf.AsyncMethodInvoker_InvokeEnd_Integration"),CallTargetKind::Default,1,1}, {(WCHAR*)WStr("System.ServiceModel"),(WCHAR*)WStr("System.ServiceModel.Dispatcher.ChannelHandler"),(WCHAR*)WStr("HandleRequest"),sig133,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Wcf.ChannelHandlerIntegration"),CallTargetKind::Default,1,1}, -{(WCHAR*)WStr("System.ServiceModel"),(WCHAR*)WStr("System.ServiceModel.Dispatcher.ImmutableDispatchRuntime"),(WCHAR*)WStr("AfterReceiveRequest"),sig387,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Wcf.AfterReceiveRequestIntegration"),CallTargetKind::Default,1,1}, -{(WCHAR*)WStr("System.ServiceModel"),(WCHAR*)WStr("System.ServiceModel.Dispatcher.ImmutableDispatchRuntime"),(WCHAR*)WStr("BeforeSendReply"),sig388,4,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Wcf.BeforeSendReplyIntegration"),CallTargetKind::Default,1,1}, +{(WCHAR*)WStr("System.ServiceModel"),(WCHAR*)WStr("System.ServiceModel.Dispatcher.ImmutableDispatchRuntime"),(WCHAR*)WStr("AfterReceiveRequest"),sig388,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Wcf.AfterReceiveRequestIntegration"),CallTargetKind::Default,1,1}, +{(WCHAR*)WStr("System.ServiceModel"),(WCHAR*)WStr("System.ServiceModel.Dispatcher.ImmutableDispatchRuntime"),(WCHAR*)WStr("BeforeSendReply"),sig389,4,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Wcf.BeforeSendReplyIntegration"),CallTargetKind::Default,1,1}, {(WCHAR*)WStr("System.ServiceModel"),(WCHAR*)WStr("System.ServiceModel.Dispatcher.SyncMethodInvoker"),(WCHAR*)WStr("Invoke"),sig173,4,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Wcf.SyncMethodInvokerIntegration"),CallTargetKind::Default,1,1}, -{(WCHAR*)WStr("System.ServiceModel"),(WCHAR*)WStr("System.ServiceModel.Dispatcher.TaskMethodInvoker"),(WCHAR*)WStr("InvokeAsync"),sig317,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Wcf.TaskMethodInvokerIntegration"),CallTargetKind::Default,1,1}, +{(WCHAR*)WStr("System.ServiceModel"),(WCHAR*)WStr("System.ServiceModel.Dispatcher.TaskMethodInvoker"),(WCHAR*)WStr("InvokeAsync"),sig318,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Wcf.TaskMethodInvokerIntegration"),CallTargetKind::Default,1,1}, #endif {(WCHAR*)WStr("System"),(WCHAR*)WStr("System.Net.HttpWebRequest"),(WCHAR*)WStr("BeginGetRequestStream"),sig151,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.WebRequest.HttpWebRequest_BeginGetRequestStream_Integration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("System"),(WCHAR*)WStr("System.Net.HttpWebRequest"),(WCHAR*)WStr("BeginGetResponse"),sig151,3,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.WebRequest.HttpWebRequest_BeginGetResponse_Integration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("System"),(WCHAR*)WStr("System.Net.HttpWebRequest"),(WCHAR*)WStr("EndGetResponse"),sig167,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.WebRequest.HttpWebRequest_EndGetResponse_Integration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("System"),(WCHAR*)WStr("System.Net.HttpWebRequest"),(WCHAR*)WStr("GetRequestStream"),sig160,1,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.WebRequest.HttpWebRequest_GetRequestStream_Integration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("System"),(WCHAR*)WStr("System.Net.HttpWebRequest"),(WCHAR*)WStr("GetResponse"),sig166,1,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.WebRequest.HttpWebRequest_GetResponse_Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("System"),(WCHAR*)WStr("System.Net.WebRequest"),(WCHAR*)WStr("GetResponseAsync"),sig221,1,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.WebRequest.WebRequest_GetResponseAsync_Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("System"),(WCHAR*)WStr("System.Net.WebRequest"),(WCHAR*)WStr("GetResponseAsync"),sig222,1,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.WebRequest.WebRequest_GetResponseAsync_Integration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("System.Net.Requests"),(WCHAR*)WStr("System.Net.HttpWebRequest"),(WCHAR*)WStr("BeginGetRequestStream"),sig151,3,4,0,0,8,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.WebRequest.HttpWebRequest_BeginGetRequestStream_Integration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("System.Net.Requests"),(WCHAR*)WStr("System.Net.HttpWebRequest"),(WCHAR*)WStr("BeginGetRequestStream"),sig151,3,9,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.WebRequest.HttpWebRequest_BeginGetRequestStreamV9_Integration"),CallTargetKind::Default,1,8}, {(WCHAR*)WStr("System.Net.Requests"),(WCHAR*)WStr("System.Net.HttpWebRequest"),(WCHAR*)WStr("EndGetResponse"),sig167,2,9,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.WebRequest.HttpWebRequest_EndGetResponseV9_Integration"),CallTargetKind::Default,1,8}, {(WCHAR*)WStr("System.Net.Requests"),(WCHAR*)WStr("System.Net.HttpWebRequest"),(WCHAR*)WStr("GetRequestStream"),sig160,1,4,0,0,8,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.WebRequest.HttpWebRequest_GetRequestStream_Integration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("System.Net.Requests"),(WCHAR*)WStr("System.Net.HttpWebRequest"),(WCHAR*)WStr("GetRequestStream"),sig160,1,9,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.WebRequest.HttpWebRequest_GetRequestStreamV9_Integration"),CallTargetKind::Default,1,8}, {(WCHAR*)WStr("System.Net.Requests"),(WCHAR*)WStr("System.Net.HttpWebRequest"),(WCHAR*)WStr("GetResponse"),sig166,1,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.WebRequest.HttpWebRequest_GetResponse_Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("System.Net.Requests"),(WCHAR*)WStr("System.Net.WebRequest"),(WCHAR*)WStr("GetResponseAsync"),sig221,1,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.WebRequest.WebRequest_GetResponseAsync_Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("Microsoft.AspNetCore.Html.Abstractions"),(WCHAR*)WStr("Microsoft.AspNetCore.Html.HtmlString"),(WCHAR*)WStr(".ctor"),sig389,2,1,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.Html.HtmlStringIntegration"),CallTargetKind::Default,4,14}, +{(WCHAR*)WStr("System.Net.Requests"),(WCHAR*)WStr("System.Net.WebRequest"),(WCHAR*)WStr("GetResponseAsync"),sig222,1,4,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Http.WebRequest.WebRequest_GetResponseAsync_Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Microsoft.AspNetCore.Html.Abstractions"),(WCHAR*)WStr("Microsoft.AspNetCore.Html.HtmlString"),(WCHAR*)WStr(".ctor"),sig390,2,1,0,0,10,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.Html.HtmlStringIntegration"),CallTargetKind::Default,4,14}, #if _WIN32 -{(WCHAR*)WStr("System.Web"),(WCHAR*)WStr("System.Web.HtmlString"),(WCHAR*)WStr(".ctor"),sig389,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.Html.HtmlStringIntegration"),CallTargetKind::Default,4,1}, +{(WCHAR*)WStr("System.Web"),(WCHAR*)WStr("System.Web.HtmlString"),(WCHAR*)WStr(".ctor"),sig390,2,4,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.AspNetCore.Html.HtmlStringIntegration"),CallTargetKind::Default,4,1}, #endif {(WCHAR*)WStr("xunit.execution.desktop"),(WCHAR*)WStr("Xunit.Sdk.TestAssemblyRunner`1"),(WCHAR*)WStr("BeforeTestAssemblyFinishedAsync"),sig185,1,2,2,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.XUnitTestAssemblyRunnerBeforeTestAssemblyFinishedAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("xunit.execution.desktop"),(WCHAR*)WStr("Xunit.Sdk.TestAssemblyRunner`1"),(WCHAR*)WStr("BeforeTestAssemblyFinishedAsync"),sig185,1,2,2,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.XUnitTestAssemblyRunnerBeforeTestAssemblyFinishedAsyncIntegration"),CallTargetKind::Derived,1,15}, -{(WCHAR*)WStr("xunit.execution.desktop"),(WCHAR*)WStr("Xunit.Sdk.TestAssemblyRunner`1"),(WCHAR*)WStr("RunAsync"),sig318,1,2,2,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.XUnitTestAssemblyRunnerRunAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("xunit.execution.desktop"),(WCHAR*)WStr("Xunit.Sdk.TestClassRunner`1"),(WCHAR*)WStr("RunAsync"),sig318,1,2,2,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.XUnitTestClassRunnerRunAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("xunit.execution.desktop"),(WCHAR*)WStr("Xunit.Sdk.TestInvoker`1"),(WCHAR*)WStr("RunAsync"),sig309,1,2,2,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.XUnitTestInvokerRunAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("xunit.execution.desktop"),(WCHAR*)WStr("Xunit.Sdk.TestOutputHelper"),(WCHAR*)WStr("QueueTestOutput"),sig389,2,2,2,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.XUnitTestOutputHelperQueueTestOutputIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("xunit.execution.desktop"),(WCHAR*)WStr("Xunit.Sdk.TestRunner`1"),(WCHAR*)WStr("RunAsync"),sig318,1,2,2,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.XUnitTestRunnerRunAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("xunit.execution.desktop"),(WCHAR*)WStr("Xunit.Sdk.TestAssemblyRunner`1"),(WCHAR*)WStr("RunAsync"),sig319,1,2,2,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.XUnitTestAssemblyRunnerRunAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("xunit.execution.desktop"),(WCHAR*)WStr("Xunit.Sdk.TestClassRunner`1"),(WCHAR*)WStr("RunAsync"),sig319,1,2,2,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.XUnitTestClassRunnerRunAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("xunit.execution.desktop"),(WCHAR*)WStr("Xunit.Sdk.TestInvoker`1"),(WCHAR*)WStr("RunAsync"),sig310,1,2,2,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.XUnitTestInvokerRunAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("xunit.execution.desktop"),(WCHAR*)WStr("Xunit.Sdk.TestOutputHelper"),(WCHAR*)WStr("QueueTestOutput"),sig390,2,2,2,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.XUnitTestOutputHelperQueueTestOutputIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("xunit.execution.desktop"),(WCHAR*)WStr("Xunit.Sdk.TestRunner`1"),(WCHAR*)WStr("RunAsync"),sig319,1,2,2,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.XUnitTestRunnerRunAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("xunit.execution.dotnet"),(WCHAR*)WStr("Xunit.Sdk.TestAssemblyRunner`1"),(WCHAR*)WStr("BeforeTestAssemblyFinishedAsync"),sig185,1,2,2,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.XUnitTestAssemblyRunnerBeforeTestAssemblyFinishedAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("xunit.execution.dotnet"),(WCHAR*)WStr("Xunit.Sdk.TestAssemblyRunner`1"),(WCHAR*)WStr("BeforeTestAssemblyFinishedAsync"),sig185,1,2,2,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.XUnitTestAssemblyRunnerBeforeTestAssemblyFinishedAsyncIntegration"),CallTargetKind::Derived,1,15}, -{(WCHAR*)WStr("xunit.execution.dotnet"),(WCHAR*)WStr("Xunit.Sdk.TestAssemblyRunner`1"),(WCHAR*)WStr("RunAsync"),sig318,1,2,2,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.XUnitTestAssemblyRunnerRunAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("xunit.execution.dotnet"),(WCHAR*)WStr("Xunit.Sdk.TestClassRunner`1"),(WCHAR*)WStr("RunAsync"),sig318,1,2,2,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.XUnitTestClassRunnerRunAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("xunit.execution.dotnet"),(WCHAR*)WStr("Xunit.Sdk.TestAssemblyRunner`1"),(WCHAR*)WStr("RunAsync"),sig319,1,2,2,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.XUnitTestAssemblyRunnerRunAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("xunit.execution.dotnet"),(WCHAR*)WStr("Xunit.Sdk.TestClassRunner`1"),(WCHAR*)WStr("RunAsync"),sig319,1,2,2,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.XUnitTestClassRunnerRunAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("xunit.execution.dotnet"),(WCHAR*)WStr("Xunit.Sdk.TestFrameworkDiscoverer"),(WCHAR*)WStr("ReportDiscoveredTestCase"),sig134,4,2,2,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.TestFrameworkDiscovererReportDiscoveredTestCaseIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("xunit.execution.dotnet"),(WCHAR*)WStr("Xunit.Sdk.TestInvoker`1"),(WCHAR*)WStr("RunAsync"),sig309,1,2,2,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.XUnitTestInvokerRunAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("xunit.execution.dotnet"),(WCHAR*)WStr("Xunit.Sdk.TestOutputHelper"),(WCHAR*)WStr("QueueTestOutput"),sig389,2,2,2,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.XUnitTestOutputHelperQueueTestOutputIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("xunit.execution.dotnet"),(WCHAR*)WStr("Xunit.Sdk.TestRunner`1"),(WCHAR*)WStr("RunAsync"),sig318,1,2,2,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.XUnitTestRunnerRunAsyncIntegration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("xunit.v3.core"),(WCHAR*)WStr("Xunit.v3.TestAssemblyRunner`4"),(WCHAR*)WStr("Run"),sig322,2,1,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.V3.XUnitTestAssemblyRunnerRunV3Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("xunit.v3.core"),(WCHAR*)WStr("Xunit.v3.TestClassRunner`4"),(WCHAR*)WStr("Run"),sig322,2,1,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.V3.XUnitTestClassRunnerRunV3Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("xunit.v3.core"),(WCHAR*)WStr("Xunit.v3.TestOutputHelper"),(WCHAR*)WStr("QueueTestOutput"),sig389,2,1,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.V3.XUnitTestOutputHelperQueueTestOutputV3Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("xunit.v3.core"),(WCHAR*)WStr("Xunit.v3.TestRunner`2"),(WCHAR*)WStr("RunTest"),sig321,2,1,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.V3.XUnitTestRunnerV3Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("xunit.v3.core"),(WCHAR*)WStr("Xunit.v3.XunitTestMethodRunnerBase`3"),(WCHAR*)WStr("RunTestCase"),sig323,3,1,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.V3.XUnitTestMethodRunnerBaseRunTestCaseV3Integration"),CallTargetKind::Default,1,15}, -{(WCHAR*)WStr("xunit.v3.core"),(WCHAR*)WStr("Xunit.v3.XunitTestMethodRunnerContext"),(WCHAR*)WStr(".ctor"),sig410,8,1,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.V3.XunitTestMethodRunnerContextCtorV3Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("xunit.execution.dotnet"),(WCHAR*)WStr("Xunit.Sdk.TestInvoker`1"),(WCHAR*)WStr("RunAsync"),sig310,1,2,2,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.XUnitTestInvokerRunAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("xunit.execution.dotnet"),(WCHAR*)WStr("Xunit.Sdk.TestOutputHelper"),(WCHAR*)WStr("QueueTestOutput"),sig390,2,2,2,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.XUnitTestOutputHelperQueueTestOutputIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("xunit.execution.dotnet"),(WCHAR*)WStr("Xunit.Sdk.TestRunner`1"),(WCHAR*)WStr("RunAsync"),sig319,1,2,2,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.XUnitTestRunnerRunAsyncIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("xunit.v3.core"),(WCHAR*)WStr("Xunit.v3.TestAssemblyRunner`4"),(WCHAR*)WStr("Run"),sig323,2,1,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.V3.XUnitTestAssemblyRunnerRunV3Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("xunit.v3.core"),(WCHAR*)WStr("Xunit.v3.TestClassRunner`4"),(WCHAR*)WStr("Run"),sig323,2,1,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.V3.XUnitTestClassRunnerRunV3Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("xunit.v3.core"),(WCHAR*)WStr("Xunit.v3.TestOutputHelper"),(WCHAR*)WStr("QueueTestOutput"),sig390,2,1,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.V3.XUnitTestOutputHelperQueueTestOutputV3Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("xunit.v3.core"),(WCHAR*)WStr("Xunit.v3.TestRunner`2"),(WCHAR*)WStr("RunTest"),sig322,2,1,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.V3.XUnitTestRunnerV3Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("xunit.v3.core"),(WCHAR*)WStr("Xunit.v3.XunitTestMethodRunnerBase`3"),(WCHAR*)WStr("RunTestCase"),sig324,3,1,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.V3.XUnitTestMethodRunnerBaseRunTestCaseV3Integration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("xunit.v3.core"),(WCHAR*)WStr("Xunit.v3.XunitTestMethodRunnerContext"),(WCHAR*)WStr(".ctor"),sig411,8,1,0,0,3,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.XUnit.V3.XunitTestMethodRunnerContextCtorV3Integration"),CallTargetKind::Default,1,15}, }; return profiler->RegisterCallTargetDefinitions((WCHAR*) WStr("Tracing"), callTargets.data(), callTargets.size(), enabledCategories, platform); } From 0a0e68fa517b15d6409b071ae1fbc15662c2b6b7 Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 14 Aug 2026 16:12:58 +0300 Subject: [PATCH 25/86] fix(feature-flags): make ExposureApi construction lazy to avoid eager allocation --- .../Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs | 11 +++++++---- .../FeatureFlags/FeatureFlagsModuleTests.cs | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs index 10862a3a84a8..8e941544277f 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs @@ -25,7 +25,7 @@ internal sealed class FeatureFlagsModule : IDisposable internal static readonly IDatadogLogger Log = DatadogLogging.GetLoggerFor(typeof(FeatureFlagsModule)); private readonly FeatureFlagsSettings _settings; - private readonly ExposureApi _exposureApi; + private readonly Lazy _exposureApi; private readonly bool _spanEnrichmentEnabled; private readonly IRcmSubscriptionManager? _rcmSubscriptionManager; private readonly ISubscription? _rcmSubscription; @@ -42,7 +42,7 @@ internal FeatureFlagsModule(TracerSettings settings, IRcmSubscriptionManager rcm { _settings = settings.FeatureFlags; _spanEnrichmentEnabled = settings.IsSpanEnrichmentEnabled; - _exposureApi = new ExposureApi(settings); + _exposureApi = new Lazy(() => new ExposureApi(settings)); Log.Debug("FeatureFlagsModule ENABLED with source {Source}", _settings.Source); @@ -98,7 +98,10 @@ public void Dispose() } Interlocked.Exchange(ref _agentlessSource, null)?.Dispose(); - _exposureApi.Dispose(); + if (_exposureApi.IsValueCreated) + { + _exposureApi.Value.Dispose(); + } } /// @@ -258,7 +261,7 @@ static ServerConfiguration MergeConfigs(List + Flags = new FlagCollection { ["test-flag"] = new Flag { Key = "test-flag", Enabled = true, VariationType = FeatureFlagsValueType.Boolean } } From 58ae7f42df1697eb481703dd49572ccf1e4c5185 Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 14 Aug 2026 18:12:59 +0300 Subject: [PATCH 26/86] fix(feature-flags): remove unused locals, defer RC subscription, and add fallback activation --- .../FeatureFlagsSdkEvaluateIntegration.cs | 4 ++ .../OpenFeatureSdkEvaluateIntegration.cs | 8 +++- .../Configuration/TracerSettings.cs | 6 --- .../FeatureFlags/FeatureFlagsModule.cs | 42 ++++++++----------- .../FeatureFlags/FeatureFlagsModuleTests.cs | 10 ++++- 5 files changed, 37 insertions(+), 33 deletions(-) diff --git a/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/ManualInstrumentation/FeatureFlags/FeatureFlagsSdkEvaluateIntegration.cs b/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/ManualInstrumentation/FeatureFlags/FeatureFlagsSdkEvaluateIntegration.cs index f6f7cfbb9d69..ef658f6d5278 100644 --- a/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/ManualInstrumentation/FeatureFlags/FeatureFlagsSdkEvaluateIntegration.cs +++ b/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/ManualInstrumentation/FeatureFlags/FeatureFlagsSdkEvaluateIntegration.cs @@ -50,6 +50,10 @@ internal static CallTargetState OnMethodBegin(ref string flagKey, Featu return new CallTargetReturn(returnValue); } + // Manual API users may not call InitializeAsync before Evaluate. Activate delivery as a + // fallback so the agentless poller starts on first evaluation, not never. + flags.Activate(); + var parameters = (State)state.State!; var res = flags.Evaluate(parameters.FlagKey, parameters.TargetType, parameters.DefaultValue, parameters.TargetingKey ?? string.Empty, parameters.Attributes); var traceContext = tracer.InternalActiveScope?.Span?.Context.TraceContext; diff --git a/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/ManualInstrumentation/OpenFeature/OpenFeatureSdkEvaluateIntegration.cs b/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/ManualInstrumentation/OpenFeature/OpenFeatureSdkEvaluateIntegration.cs index 9bfe9de24f1e..f9d57d3d99c6 100644 --- a/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/ManualInstrumentation/OpenFeature/OpenFeatureSdkEvaluateIntegration.cs +++ b/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/ManualInstrumentation/OpenFeature/OpenFeatureSdkEvaluateIntegration.cs @@ -43,7 +43,13 @@ internal static CallTargetState OnMethodBegin(ref string flagKey, Featu } var parameters = (State)state.State!; - var res = TracerManager.Instance.FeatureFlags?.Evaluate(parameters.FlagKey, parameters.TargetType, parameters.DefaultValue, parameters.TargetingKey ?? string.Empty, parameters.Attributes); + var flags = TracerManager.Instance.FeatureFlags; + + // Fallback activation: if the user calls Evaluate without InitializeAsync (for example, + // via the manual API or an older OpenFeature package), start delivery on first evaluation. + flags?.Activate(); + + var res = flags?.Evaluate(parameters.FlagKey, parameters.TargetType, parameters.DefaultValue, parameters.TargetingKey ?? string.Empty, parameters.Attributes); return new CallTargetReturn(res.DuckCast()); } diff --git a/tracer/src/Datadog.Trace/Configuration/TracerSettings.cs b/tracer/src/Datadog.Trace/Configuration/TracerSettings.cs index cf7bbe9b14d3..7803e2be4261 100644 --- a/tracer/src/Datadog.Trace/Configuration/TracerSettings.cs +++ b/tracer/src/Datadog.Trace/Configuration/TracerSettings.cs @@ -763,12 +763,6 @@ not null when string.Equals(value, "otlp", StringComparison.OrdinalIgnoreCase) = DisabledAdoNetCommandTypes.UnionWith(userSplit); } -#pragma warning disable 618 // superseded, but still honoured so existing adopters keep their source - var flaggingProviderEnabled = config.WithKeys(ConfigurationKeys.FeatureFlags.FlaggingProviderEnabled).AsBool(); -#pragma warning restore 618 - var featureFlagsEnabled = config.WithKeys(ConfigurationKeys.FeatureFlags.FeatureFlagsEnabled).AsBool(); - var configuredSource = config.WithKeys(ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSource).AsString(); - FeatureFlags = new FeatureFlagsSettings(source, telemetry); IsSpanEnrichmentEnabled = config.WithKeys(ConfigurationKeys.FeatureFlags.SpanEnrichmentEnabled) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs index 8e941544277f..c8d2f73c1620 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs @@ -25,11 +25,12 @@ internal sealed class FeatureFlagsModule : IDisposable internal static readonly IDatadogLogger Log = DatadogLogging.GetLoggerFor(typeof(FeatureFlagsModule)); private readonly FeatureFlagsSettings _settings; + private readonly bool _isRemoteConfigurationAvailable; private readonly Lazy _exposureApi; private readonly bool _spanEnrichmentEnabled; private readonly IRcmSubscriptionManager? _rcmSubscriptionManager; - private readonly ISubscription? _rcmSubscription; private readonly TaskCompletionSource _firstConfigReceived = new(TaskCreationOptions.RunContinuationsAsynchronously); + private ISubscription? _rcmSubscription; private Action? _onNewConfigEventHander; private FeatureFlagsEvaluator? _evaluator; @@ -41,31 +42,12 @@ internal sealed class FeatureFlagsModule : IDisposable internal FeatureFlagsModule(TracerSettings settings, IRcmSubscriptionManager rcmSubscriptionManager) { _settings = settings.FeatureFlags; + _isRemoteConfigurationAvailable = settings.IsRemoteConfigurationAvailable; _spanEnrichmentEnabled = settings.IsSpanEnrichmentEnabled; _exposureApi = new Lazy(() => new ExposureApi(settings)); + _rcmSubscriptionManager = rcmSubscriptionManager; Log.Debug("FeatureFlagsModule ENABLED with source {Source}", _settings.Source); - - if (_settings.Source == FeatureFlagsSource.RemoteConfig) - { - if (!settings.IsRemoteConfigurationAvailable) - { - // Selecting Remote Configuration explicitly and then falling back to the agentless - // endpoint would start billed requests the customer did not ask for, so the source - // stays selected and simply never delivers. - Log.Warning( - "Feature Flags are configured to use the Remote Configuration source, but Remote Configuration is not available. No flag configuration will be received."); - } - - // Subscribing advertises the FFE capability and starts a billed Remote Configuration - // subscription, so it only happens when Remote Configuration is the selected source. - // The subscription keeps the product alive, so it needs no field of its own. - var ffeProduct = new FfeProduct(configs => ApplyConfigurations(configs)); - _rcmSubscriptionManager = rcmSubscriptionManager; - _rcmSubscription = new Subscription(ffeProduct.UpdateFromRcm, RcmProducts.FfeFlags); - _rcmSubscriptionManager.SubscribeToChanges(_rcmSubscription!); - _rcmSubscriptionManager.SetCapability(RcmCapabilitiesIndices.FfeFlagConfigurationRules, true); - } } /// @@ -118,10 +100,20 @@ internal void Activate() switch (_settings.Source) { case FeatureFlagsSource.RemoteConfig: - // Remote Configuration delivery is driven by the Agent, so the subscription set up - // in the constructor is all that is needed; activation only marks intent. + // Remote Configuration subscription is deferred to activation so that merely + // enabling Feature Flags does not start a billed RC subscription. + if (!_isRemoteConfigurationAvailable) + { + Log.Warning("Feature Flags are configured to use the Remote Configuration source, but Remote Configuration is not available. No flag configuration will be received."); + break; + } + + var ffeProduct = new FfeProduct(configs => ApplyConfigurations(configs)); + _rcmSubscription = new Subscription(ffeProduct.UpdateFromRcm, RcmProducts.FfeFlags); + _rcmSubscriptionManager!.SubscribeToChanges(_rcmSubscription!); + _rcmSubscriptionManager.SetCapability(RcmCapabilitiesIndices.FfeFlagConfigurationRules, true); _deliveryStarted = true; - Log.Debug("FeatureFlagsModule::Activate -> Remote Configuration source is already subscribed"); + Log.Debug("FeatureFlagsModule::Activate -> Remote Configuration source subscribed"); break; case FeatureFlagsSource.Agentless: // Polling is billable, so it starts here rather than at construction. diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs index c2b2b7aef281..1011dd6c5df7 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs @@ -33,6 +33,7 @@ public void UpdateRemoteConfig_WithEmptyList_InvokesCallbackAndReturnsProviderNo var rcmManager = new MockRcmSubscriptionManager(); var settings = CreateSettings(); var module = new FeatureFlagsModule(settings, rcmManager); + module.Activate(); var callbackInvoked = false; module.RegisterOnNewConfigEventHandler(() => callbackInvoked = true); @@ -96,7 +97,7 @@ public void Create_WithAgentlessSource_DoesNotSubscribeToRc() } [Fact] - public void Create_WithRemoteConfigSource_SubscribesAndAdvertisesCapability() + public void Create_WithRemoteConfigSource_DoesNotSubscribeUntilActivated() { var rcmManager = new MockRcmSubscriptionManager(); var settings = CreateSettings((ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSource, "remote_config")); @@ -104,6 +105,13 @@ public void Create_WithRemoteConfigSource_SubscribesAndAdvertisesCapability() using var module = FeatureFlagsModule.Create(settings, rcmManager); module.Should().NotBeNull(); + + // Subscription is deferred to Activate() so merely enabling Feature Flags does not start + // a billed RC subscription. + rcmManager.HasAnySubscription.Should().BeFalse(); + + module!.Activate(); + rcmManager.HasAnySubscription.Should().BeTrue(); rcmManager.ProductKeys.Should().Contain(RcmProducts.FfeFlags); } From 4b925d73f2b29334c670e17d455354a77594e20e Mon Sep 17 00:00:00 2001 From: Pavel Date: Tue, 18 Aug 2026 17:40:03 +0300 Subject: [PATCH 27/86] [FeatureFlags] Drop the duplicate FeatureFlags settings left by the rebase --- tracer/src/Datadog.Trace/Configuration/TracerSettings.cs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tracer/src/Datadog.Trace/Configuration/TracerSettings.cs b/tracer/src/Datadog.Trace/Configuration/TracerSettings.cs index 7803e2be4261..a310d90bbb58 100644 --- a/tracer/src/Datadog.Trace/Configuration/TracerSettings.cs +++ b/tracer/src/Datadog.Trace/Configuration/TracerSettings.cs @@ -763,8 +763,6 @@ not null when string.Equals(value, "otlp", StringComparison.OrdinalIgnoreCase) = DisabledAdoNetCommandTypes.UnionWith(userSplit); } - FeatureFlags = new FeatureFlagsSettings(source, telemetry); - IsSpanEnrichmentEnabled = config.WithKeys(ConfigurationKeys.FeatureFlags.SpanEnrichmentEnabled) .AsBool(false); @@ -1495,11 +1493,6 @@ not null when string.Equals(value, "otlp", StringComparison.OrdinalIgnoreCase) = /// internal HashSet DisabledAdoNetCommandTypes { get; } - /// - /// Gets the Feature Flags configuration, including which delivery source is selected. - /// - internal FeatureFlagsSettings FeatureFlags { get; } - /// /// Gets a value indicating whether APM span enrichment is enabled; see . /// From 261d4029e447fe492d559464db99285591f15d4f Mon Sep 17 00:00:00 2001 From: Pavel Date: Tue, 18 Aug 2026 18:31:17 +0300 Subject: [PATCH 28/86] [FeatureFlags] Guard activation and disposal with a single lock --- .../FeatureFlags/FeatureFlagsModule.cs | 179 ++++++++++++------ .../FeatureFlags/FeatureFlagsModuleTests.cs | 65 +++++++ 2 files changed, 189 insertions(+), 55 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs index c8d2f73c1620..a5a33bec646d 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs @@ -24,19 +24,26 @@ internal sealed class FeatureFlagsModule : IDisposable { internal static readonly IDatadogLogger Log = DatadogLogging.GetLoggerFor(typeof(FeatureFlagsModule)); + // Activation, disposal and exposure-API creation all mutate the same state from different + // threads, so they share one lock rather than individual interlocked flags: a flag set + // before its accompanying setup completes lets a concurrent caller observe a half-activated + // module, and a disposal interleaved with activation leaks the delivery path it started. + private readonly object _stateLock = new(); + private readonly FeatureFlagsSettings _settings; private readonly bool _isRemoteConfigurationAvailable; - private readonly Lazy _exposureApi; + private readonly Func _exposureApiFactory; private readonly bool _spanEnrichmentEnabled; - private readonly IRcmSubscriptionManager? _rcmSubscriptionManager; + private readonly IRcmSubscriptionManager _rcmSubscriptionManager; private readonly TaskCompletionSource _firstConfigReceived = new(TaskCreationOptions.RunContinuationsAsynchronously); private ISubscription? _rcmSubscription; private Action? _onNewConfigEventHander; private FeatureFlagsEvaluator? _evaluator; private AgentlessConfigurationSource? _agentlessSource; - private int _activated; - private int _disposed; + private ExposureApi? _exposureApi; + private bool _activated; + private bool _disposed; private bool _deliveryStarted; internal FeatureFlagsModule(TracerSettings settings, IRcmSubscriptionManager rcmSubscriptionManager) @@ -44,7 +51,7 @@ internal FeatureFlagsModule(TracerSettings settings, IRcmSubscriptionManager rcm _settings = settings.FeatureFlags; _isRemoteConfigurationAvailable = settings.IsRemoteConfigurationAvailable; _spanEnrichmentEnabled = settings.IsSpanEnrichmentEnabled; - _exposureApi = new Lazy(() => new ExposureApi(settings)); + _exposureApiFactory = () => new ExposureApi(settings); _rcmSubscriptionManager = rcmSubscriptionManager; Log.Debug("FeatureFlagsModule ENABLED with source {Source}", _settings.Source); @@ -69,21 +76,37 @@ internal FeatureFlagsModule(TracerSettings settings, IRcmSubscriptionManager rcm public void Dispose() { - if (Interlocked.CompareExchange(ref _disposed, 1, 0) != 0) - { - return; - } + ISubscription? subscription; + AgentlessConfigurationSource? agentlessSource; + ExposureApi? exposureApi; - if (_rcmSubscriptionManager is not null && _rcmSubscription is not null) + lock (_stateLock) { - _rcmSubscriptionManager.Unsubscribe(_rcmSubscription); + if (_disposed) + { + return; + } + + _disposed = true; + + subscription = _rcmSubscription; + agentlessSource = _agentlessSource; + exposureApi = _exposureApi; + + _rcmSubscription = null; + _agentlessSource = null; + Volatile.Write(ref _exposureApi, null); } - Interlocked.Exchange(ref _agentlessSource, null)?.Dispose(); - if (_exposureApi.IsValueCreated) + // Released the lock first: disposal is not state mutation, and holding it here would + // block an activation or an exposure for the duration. + if (subscription is not null) { - _exposureApi.Value.Dispose(); + _rcmSubscriptionManager.Unsubscribe(subscription); } + + agentlessSource?.Dispose(); + exposureApi?.Dispose(); } /// @@ -92,49 +115,55 @@ public void Dispose() /// internal void Activate() { - if (Interlocked.CompareExchange(ref _activated, 1, 0) != 0) - { - return; - } + AgentlessConfigurationSource? sourceToStart = null; - switch (_settings.Source) + lock (_stateLock) { - case FeatureFlagsSource.RemoteConfig: - // Remote Configuration subscription is deferred to activation so that merely - // enabling Feature Flags does not start a billed RC subscription. - if (!_isRemoteConfigurationAvailable) - { - Log.Warning("Feature Flags are configured to use the Remote Configuration source, but Remote Configuration is not available. No flag configuration will be received."); - break; - } - - var ffeProduct = new FfeProduct(configs => ApplyConfigurations(configs)); - _rcmSubscription = new Subscription(ffeProduct.UpdateFromRcm, RcmProducts.FfeFlags); - _rcmSubscriptionManager!.SubscribeToChanges(_rcmSubscription!); - _rcmSubscriptionManager.SetCapability(RcmCapabilitiesIndices.FfeFlagConfigurationRules, true); - _deliveryStarted = true; - Log.Debug("FeatureFlagsModule::Activate -> Remote Configuration source subscribed"); - break; - case FeatureFlagsSource.Agentless: - // Polling is billable, so it starts here rather than at construction. - var source = AgentlessConfigurationSource.Create(_settings, ApplyConfiguration); - if (source is null) - { - break; - } + if (_activated || _disposed) + { + return; + } - Interlocked.Exchange(ref _agentlessSource, source); - if (Volatile.Read(ref _disposed) == 1) - { - // Disposed while we were creating it. - Interlocked.Exchange(ref _agentlessSource, null)?.Dispose(); - break; - } + _activated = true; - source.Start(); - _deliveryStarted = true; - break; + switch (_settings.Source) + { + case FeatureFlagsSource.RemoteConfig: + // Remote Configuration subscription is deferred to activation so that merely + // enabling Feature Flags does not start a billed RC subscription. + if (!_isRemoteConfigurationAvailable) + { + Log.Warning("Feature Flags are configured to use the Remote Configuration source, but Remote Configuration is not available. No flag configuration will be received."); + break; + } + + var ffeProduct = new FfeProduct(configs => ApplyConfigurations(configs)); + _rcmSubscription = new Subscription(ffeProduct.UpdateFromRcm, RcmProducts.FfeFlags); + _rcmSubscriptionManager.SubscribeToChanges(_rcmSubscription); + _rcmSubscriptionManager.SetCapability(RcmCapabilitiesIndices.FfeFlagConfigurationRules, true); + _deliveryStarted = true; + Log.Debug("FeatureFlagsModule::Activate -> Remote Configuration source subscribed"); + break; + case FeatureFlagsSource.Agentless: + // Polling is billable, so it starts here rather than at construction. + var source = AgentlessConfigurationSource.Create(_settings, ApplyConfiguration); + if (source is null) + { + break; + } + + _agentlessSource = source; + sourceToStart = source; + _deliveryStarted = true; + break; + } } + + // Start() issues the first request on the calling thread up to its first await, so it runs + // outside the lock: holding it across a network request would block Dispose(). A Dispose() + // that interleaves here has already cancelled the source's shutdown token, which makes the + // poll loop exit before its first request. + sourceToStart?.Start(); } /// @@ -153,8 +182,16 @@ internal async Task InitializeAsync(CancellationToken cancellationToken) // When activation could not start any delivery source (for example, agentless without // an API key), waiting would only delay startup for a configuration that will never - // arrive. The provider stays not-ready, which is the correct state. - if (!_deliveryStarted) + // arrive. The provider stays not-ready, which is the correct state. Read under the lock + // so a concurrent activation is seen through, rather than skipping the wait because its + // source had not finished starting. + bool deliveryStarted; + lock (_stateLock) + { + deliveryStarted = _deliveryStarted; + } + + if (!deliveryStarted) { return; } @@ -253,7 +290,39 @@ static ServerConfiguration MergeConfigs(List + { + start.SignalAndWait(); + module!.Activate(); + }); + + rcmManager.ProductKeys.Should().ContainSingle().Which.Should().Be(RcmProducts.FfeFlags); + } + + [Fact] + public void Activate_AfterDispose_DoesNotSubscribe() + { + var rcmManager = new MockRcmSubscriptionManager(); + var module = FeatureFlagsModule.Create(CreateSettings(), rcmManager); + + module!.Dispose(); + module.Activate(); + + // Disposal has already run its unsubscribe, so a subscription registered afterwards would + // never be removed, leaving a billed delivery path active for the rest of the process. + rcmManager.HasAnySubscription.Should().BeFalse(); + rcmManager.ProductKeys.Should().BeEmpty(); + } + + [Fact] + public void Dispose_AfterSubscribing_Unsubscribes() + { + var rcmManager = new MockRcmSubscriptionManager(); + var module = FeatureFlagsModule.Create(CreateSettings(), rcmManager); + + module!.Activate(); + rcmManager.HasAnySubscription.Should().BeTrue(); + + module.Dispose(); + + rcmManager.HasAnySubscription.Should().BeFalse(); + } + + [Fact] + public void GetExposureApi_AfterDispose_DoesNotCreateOne() + { + var module = FeatureFlagsModule.Create(CreateSettings(), new MockRcmSubscriptionManager()); + + module!.GetExposureApi().Should().NotBeNull(); + + module.Dispose(); + + // An exposure API created after disposal would keep its send loop running for the rest of + // the process, because nothing disposes it. + module.GetExposureApi().Should().BeNull(); + } + private static TracerSettings CreateSettings(params (string Key, string Value)[] settings) { var collection = new NameValueCollection From 2f725b096fcab3727027cf37acebb9dfa6f681df Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 19 Aug 2026 09:23:50 +0300 Subject: [PATCH 29/86] [FeatureFlags] Report an error status when no delivery source could start --- .../DatadogProvider.cs | 12 ++- .../Sdk/FeatureFlagsSdk.cs | 2 +- ...eatureFlagsDeliveryUnavailableException.cs | 23 +++++ .../FeatureFlags/FeatureFlagsModule.cs | 30 ++++-- .../FeatureFlags/FeatureFlagsModuleTests.cs | 96 ++++++++++++------- 5 files changed, 117 insertions(+), 46 deletions(-) create mode 100644 tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsDeliveryUnavailableException.cs diff --git a/tracer/src/Datadog.FeatureFlags.OpenFeature/DatadogProvider.cs b/tracer/src/Datadog.FeatureFlags.OpenFeature/DatadogProvider.cs index cec9ace37388..3a27ee10a736 100644 --- a/tracer/src/Datadog.FeatureFlags.OpenFeature/DatadogProvider.cs +++ b/tracer/src/Datadog.FeatureFlags.OpenFeature/DatadogProvider.cs @@ -75,9 +75,15 @@ private void SignalGeneralUpdate() /// /// Starts flag configuration delivery and waits for the first configuration, so that a ready - /// provider can actually resolve flags. It returns normally when the wait times out instead of - /// throwing: slow delivery is transient, and initialization commonly runs at startup, where an - /// exception would take the application down. + /// provider can actually resolve flags. + /// + /// It returns normally when the wait times out, because slow delivery is transient and the + /// configuration still arrives afterwards. It faults when no source could start delivery at all, + /// which leaves the provider unable to resolve anything for the rest of the process: OpenFeature + /// then marks this provider as errored instead of ready, and evaluations keep returning their + /// default values. The exception does not reach the application, because OpenFeature handles it + /// while setting the provider. + /// /// /// Evaluation context /// Async cancellation token diff --git a/tracer/src/Datadog.FeatureFlags.OpenFeature/Sdk/FeatureFlagsSdk.cs b/tracer/src/Datadog.FeatureFlags.OpenFeature/Sdk/FeatureFlagsSdk.cs index 7ae5ac8438f4..1fa4c8300f2e 100644 --- a/tracer/src/Datadog.FeatureFlags.OpenFeature/Sdk/FeatureFlagsSdk.cs +++ b/tracer/src/Datadog.FeatureFlags.OpenFeature/Sdk/FeatureFlagsSdk.cs @@ -40,7 +40,7 @@ internal static class FeatureFlagsSdk /// tracer alone must not do it. /// /// Cancellation token supplied by OpenFeature - /// A task that completes once configuration has arrived, or the initialization timeout has elapsed + /// A task that completes once configuration has arrived or the initialization timeout has elapsed, and that faults when no source could start delivery at all [MethodImpl(MethodImplOptions.NoInlining)] public static Task InitializeAsync(CancellationToken cancellationToken) => Task.CompletedTask; diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsDeliveryUnavailableException.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsDeliveryUnavailableException.cs new file mode 100644 index 000000000000..65569afeee99 --- /dev/null +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsDeliveryUnavailableException.cs @@ -0,0 +1,23 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +#nullable enable + +using System; + +namespace Datadog.Trace.FeatureFlags; + +/// +/// Thrown from initialization when no source could start requesting flag configuration, so none will +/// ever arrive. Initialization reports this rather than returning, because a normal return tells the +/// SDK that the provider is ready while every evaluation would keep returning its default value. +/// +internal sealed class FeatureFlagsDeliveryUnavailableException : Exception +{ + public FeatureFlagsDeliveryUnavailableException(string? reason) + : base($"Feature Flags cannot request configuration: {reason ?? "no delivery source could be started"}. Evaluations return their default values.") + { + } +} diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs index a5a33bec646d..4ad653c4e654 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs @@ -42,6 +42,7 @@ internal sealed class FeatureFlagsModule : IDisposable private FeatureFlagsEvaluator? _evaluator; private AgentlessConfigurationSource? _agentlessSource; private ExposureApi? _exposureApi; + private string? _deliveryUnavailableReason; private bool _activated; private bool _disposed; private bool _deliveryStarted; @@ -134,6 +135,7 @@ internal void Activate() if (!_isRemoteConfigurationAvailable) { Log.Warning("Feature Flags are configured to use the Remote Configuration source, but Remote Configuration is not available. No flag configuration will be received."); + _deliveryUnavailableReason = "the Remote Configuration source is selected, but Remote Configuration is not available in this environment"; break; } @@ -149,6 +151,9 @@ internal void Activate() var source = AgentlessConfigurationSource.Create(_settings, ApplyConfiguration); if (source is null) { + // Create logs the specific reason, which may name configuration the + // message must not repeat back to the application. + _deliveryUnavailableReason = "the agentless source could not be started, see the Datadog logs for the reason"; break; } @@ -168,8 +173,13 @@ internal void Activate() /// /// Activates delivery and waits for the first configuration, so that a provider reported as - /// ready can resolve flags. Never throws on timeout: delivery being slow is transient, while - /// initialization typically runs at application startup where an exception is fatal. + /// ready can resolve flags. + /// + /// Returns without throwing when the wait times out, because delivery being slow is transient: + /// the configuration still arrives later and promotes the provider. Throws + /// when no source could start at all, + /// which is permanent for the life of the process and must not be reported as a ready provider. + /// /// internal async Task InitializeAsync(CancellationToken cancellationToken) { @@ -180,20 +190,24 @@ internal async Task InitializeAsync(CancellationToken cancellationToken) return; } - // When activation could not start any delivery source (for example, agentless without - // an API key), waiting would only delay startup for a configuration that will never - // arrive. The provider stays not-ready, which is the correct state. Read under the lock - // so a concurrent activation is seen through, rather than skipping the wait because its - // source had not finished starting. + // Read under the lock so a concurrent activation is seen through, rather than reporting no + // delivery because its source had not finished starting. bool deliveryStarted; + string? deliveryUnavailableReason; lock (_stateLock) { deliveryStarted = _deliveryStarted; + deliveryUnavailableReason = _deliveryUnavailableReason; } + // When activation could not start any delivery source (for example, agentless without an + // API key), no configuration can ever arrive, so waiting would only delay startup. + // Returning instead would report the provider as usable while every evaluation keeps + // returning its default, so the failure is raised: the SDK turns it into an error status + // and an error event without taking the application down. if (!deliveryStarted) { - return; + throw new FeatureFlagsDeliveryUnavailableException(deliveryUnavailableReason); } using var timeoutCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs index d526cd4d6270..c91834803234 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs @@ -5,6 +5,7 @@ #nullable enable +using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; @@ -47,8 +48,10 @@ public void UpdateRemoteConfig_WithEmptyList_InvokesCallbackAndReturnsProviderNo } }); var configPath = RemoteConfigurationPath.FromPath($"datadog/2/{RcmProducts.FfeFlags}/test-config/config"); + var subscription = rcmManager.LastSubscription + ?? throw new InvalidOperationException("Activation did not register a Remote Configuration subscription."); - rcmManager.LastSubscription!.Invoke( + subscription.Invoke( new Dictionary> { [RcmProducts.FfeFlags] = [new RemoteConfiguration(configPath, System.Text.Encoding.UTF8.GetBytes(configJson), configJson.Length, new Dictionary { { "sha256", "dummy" } }, 1)] @@ -64,7 +67,7 @@ public void UpdateRemoteConfig_WithEmptyList_InvokesCallbackAndReturnsProviderNo callbackInvoked = false; // Act: Remove the config (RC reset) - rcmManager.LastSubscription!.Invoke( + subscription.Invoke( new Dictionary>(), new Dictionary> { @@ -85,10 +88,10 @@ public void Create_WithAgentlessSource_DoesNotSubscribeToRc() var rcmManager = new MockRcmSubscriptionManager(); var settings = CreateSettings((ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSource, "agentless")); - using var module = FeatureFlagsModule.Create(settings, rcmManager); + // CreateModule throws when no module is created, which is the assertion that it was. + using var module = CreateModule(settings, rcmManager); - module.Should().NotBeNull(); - module!.Settings.Source.Should().Be(FeatureFlagsSource.Agentless); + module.Settings.Source.Should().Be(FeatureFlagsSource.Agentless); // Subscribing would advertise the FFE capability and start a billed Remote Configuration // subscription, which must not happen for a source that never uses it. @@ -102,15 +105,13 @@ public void Create_WithRemoteConfigSource_DoesNotSubscribeUntilActivated() var rcmManager = new MockRcmSubscriptionManager(); var settings = CreateSettings((ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSource, "remote_config")); - using var module = FeatureFlagsModule.Create(settings, rcmManager); - - module.Should().NotBeNull(); + using var module = CreateModule(settings, rcmManager); // Subscription is deferred to Activate() so merely enabling Feature Flags does not start // a billed RC subscription. rcmManager.HasAnySubscription.Should().BeFalse(); - module!.Activate(); + module.Activate(); rcmManager.HasAnySubscription.Should().BeTrue(); rcmManager.ProductKeys.Should().Contain(RcmProducts.FfeFlags); @@ -131,9 +132,9 @@ public void Create_WhenDisabled_ReturnsNull() public async Task InitializeAsync_WhenConfigurationAlreadyApplied_ReturnsImmediately() { var settings = CreateInitializationSettings("60000"); - using var module = FeatureFlagsModule.Create(settings, new MockRcmSubscriptionManager()); + using var module = CreateModule(settings, new MockRcmSubscriptionManager()); - module!.ApplyConfiguration(new ServerConfiguration + module.ApplyConfiguration(new ServerConfiguration { Flags = new FlagCollection { @@ -150,9 +151,9 @@ public async Task InitializeAsync_WhenConfigurationAlreadyApplied_ReturnsImmedia public async Task InitializeAsync_WhenConfigurationArrivesWhileWaiting_Returns() { var settings = CreateInitializationSettings("60000"); - using var module = FeatureFlagsModule.Create(settings, new MockRcmSubscriptionManager()); + using var module = CreateModule(settings, new MockRcmSubscriptionManager()); - var initialization = module!.InitializeAsync(CancellationToken.None); + var initialization = module.InitializeAsync(CancellationToken.None); initialization.IsCompleted.Should().BeFalse(); module.ApplyConfiguration(new ServerConfiguration()).Should().BeTrue(); @@ -164,11 +165,11 @@ public async Task InitializeAsync_WhenConfigurationArrivesWhileWaiting_Returns() public async Task InitializeAsync_OnTimeout_ReturnsWithoutThrowing() { var settings = CreateInitializationSettings("1"); - using var module = FeatureFlagsModule.Create(settings, new MockRcmSubscriptionManager()); + using var module = CreateModule(settings, new MockRcmSubscriptionManager()); - // Initialization commonly runs at application startup, where throwing would take the - // application down, so a missing configuration is only reported through evaluations. - await module!.InitializeAsync(CancellationToken.None); + // Delivery has started, so the configuration still arrives after this point and promotes the + // provider. Only the wait is abandoned, which is why the timeout does not fail initialization. + await module.InitializeAsync(CancellationToken.None); module.FirstConfigReceived.IsCompleted.Should().BeFalse(); module.Evaluate("test-flag", FeatureFlagsValueType.Boolean, false, "user-1", null) @@ -179,39 +180,59 @@ public async Task InitializeAsync_OnTimeout_ReturnsWithoutThrowing() public async Task InitializeAsync_OnCancellation_ReturnsWithoutThrowing() { var settings = CreateInitializationSettings("60000"); - using var module = FeatureFlagsModule.Create(settings, new MockRcmSubscriptionManager()); + using var module = CreateModule(settings, new MockRcmSubscriptionManager()); using var cancellation = new CancellationTokenSource(); - var initialization = module!.InitializeAsync(cancellation.Token); + var initialization = module.InitializeAsync(cancellation.Token); cancellation.Cancel(); await initialization; } [Fact] - public async Task InitializeAsync_WhenAgentlessSourceCannotStart_ReturnsImmediately() + public async Task InitializeAsync_WhenAgentlessSourceCannotStart_FailsImmediately() { - // Agentless without an API key cannot start the poller. Initialization should return - // immediately instead of waiting the full timeout for a configuration that will never arrive. + // Agentless without an API key cannot start the poller, so no configuration will ever arrive. var settings = CreateSettings( (ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSource, "agentless"), (ConfigurationKeys.FeatureFlags.FlaggingProviderInitializationTimeoutMs, "60000")); - using var module = FeatureFlagsModule.Create(settings, new MockRcmSubscriptionManager()); + using var module = CreateModule(settings, new MockRcmSubscriptionManager()); var stopwatch = Stopwatch.StartNew(); - await module!.InitializeAsync(CancellationToken.None); + + // Completing normally would report the provider as ready, while every evaluation would keep + // returning its default value. Failing is what makes the SDK record an error status instead. + await module.Invoking(m => m.InitializeAsync(CancellationToken.None)) + .Should().ThrowAsync(); + stopwatch.Stop(); - // Should return near-instantly, not after the 60s timeout. - stopwatch.Elapsed.Should().BeLessThan(System.TimeSpan.FromSeconds(5)); + // Immediately, rather than after the 60s timeout: the configuration cannot arrive by waiting. + stopwatch.Elapsed.Should().BeLessThan(TimeSpan.FromSeconds(5)); module.FirstConfigReceived.IsCompleted.Should().BeFalse(); } + [Fact] + public async Task InitializeAsync_WhenRemoteConfigurationIsUnavailable_FailsWithTheReason() + { + var settings = CreateSettings( + (ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSource, "remote_config"), + (ConfigurationKeys.Rcm.RemoteConfigurationEnabled, "false")); + using var module = CreateModule(settings, new MockRcmSubscriptionManager()); + + var failure = await module.Invoking(m => m.InitializeAsync(CancellationToken.None)) + .Should().ThrowAsync(); + + // The message reaches the application through the SDK's error event, so it names the cause + // without echoing configuration back. + failure.Which.Message.Should().Contain("Remote Configuration is not available"); + } + [Fact] public void Activate_WhenCalledConcurrently_SubscribesOnce() { var rcmManager = new MockRcmSubscriptionManager(); - using var module = FeatureFlagsModule.Create(CreateSettings(), rcmManager); + using var module = CreateModule(CreateSettings(), rcmManager); // Activation claims its flag and completes its setup atomically, so a second caller cannot // subscribe a second time, nor observe the module as activated while setup is still running. @@ -223,7 +244,7 @@ public void Activate_WhenCalledConcurrently_SubscribesOnce() _ => { start.SignalAndWait(); - module!.Activate(); + module.Activate(); }); rcmManager.ProductKeys.Should().ContainSingle().Which.Should().Be(RcmProducts.FfeFlags); @@ -233,9 +254,9 @@ public void Activate_WhenCalledConcurrently_SubscribesOnce() public void Activate_AfterDispose_DoesNotSubscribe() { var rcmManager = new MockRcmSubscriptionManager(); - var module = FeatureFlagsModule.Create(CreateSettings(), rcmManager); + var module = CreateModule(CreateSettings(), rcmManager); - module!.Dispose(); + module.Dispose(); module.Activate(); // Disposal has already run its unsubscribe, so a subscription registered afterwards would @@ -248,9 +269,9 @@ public void Activate_AfterDispose_DoesNotSubscribe() public void Dispose_AfterSubscribing_Unsubscribes() { var rcmManager = new MockRcmSubscriptionManager(); - var module = FeatureFlagsModule.Create(CreateSettings(), rcmManager); + var module = CreateModule(CreateSettings(), rcmManager); - module!.Activate(); + module.Activate(); rcmManager.HasAnySubscription.Should().BeTrue(); module.Dispose(); @@ -261,9 +282,9 @@ public void Dispose_AfterSubscribing_Unsubscribes() [Fact] public void GetExposureApi_AfterDispose_DoesNotCreateOne() { - var module = FeatureFlagsModule.Create(CreateSettings(), new MockRcmSubscriptionManager()); + var module = CreateModule(CreateSettings(), new MockRcmSubscriptionManager()); - module!.GetExposureApi().Should().NotBeNull(); + module.GetExposureApi().Should().NotBeNull(); module.Dispose(); @@ -272,6 +293,13 @@ public void GetExposureApi_AfterDispose_DoesNotCreateOne() module.GetExposureApi().Should().BeNull(); } + // Creates the module for settings that enable Feature Flags, and returns it as non-nullable so + // tests can use it directly. Throwing rather than asserting keeps the compiler's nullable analysis + // satisfied without a null-forgiving operator. + private static FeatureFlagsModule CreateModule(TracerSettings settings, IRcmSubscriptionManager rcmSubscriptionManager) + => FeatureFlagsModule.Create(settings, rcmSubscriptionManager) + ?? throw new InvalidOperationException("Feature Flags are enabled, but no module was created."); + private static TracerSettings CreateSettings(params (string Key, string Value)[] settings) { var collection = new NameValueCollection From 126d201de8013504442dcae776060808d16b801e Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 19 Aug 2026 10:02:22 +0300 Subject: [PATCH 30/86] [FeatureFlags] Emit typed provider events instead of an implicit ProviderReady --- .../DatadogProvider.cs | 58 +++++++++++++++++-- 1 file changed, 52 insertions(+), 6 deletions(-) diff --git a/tracer/src/Datadog.FeatureFlags.OpenFeature/DatadogProvider.cs b/tracer/src/Datadog.FeatureFlags.OpenFeature/DatadogProvider.cs index 3a27ee10a736..3e5ffd3f6ebd 100644 --- a/tracer/src/Datadog.FeatureFlags.OpenFeature/DatadogProvider.cs +++ b/tracer/src/Datadog.FeatureFlags.OpenFeature/DatadogProvider.cs @@ -33,6 +33,8 @@ public sealed class DatadogProvider : global::OpenFeature.FeatureProvider, IDisp // nothing is allocated/registered when the feature is disabled. private readonly SpanEnrichmentHook? _spanEnrichmentHook; + private int _readySignalled; + /// Initializes a new instance of the class. public DatadogProvider() { @@ -62,17 +64,61 @@ private void SignalGeneralUpdate() { _onNewConfig?.Invoke(); - // You don't have to provide specific flag keys - var payload = new ProviderEventPayload + // The first configuration is what makes this provider usable, and only a ready event + // promotes it: initialization reports an error when no delivery source could start, and + // OpenFeature keeps that status until told otherwise. Later configurations are changes, + // which deliberately leave the status alone. + if (Interlocked.CompareExchange(ref _readySignalled, 1, 0) == 0) { - Message = "A backend update occurred, but specific changes are unknown." - }; - - EventChannel.Writer.TryWrite((object)payload); + SignalReady(); + return; + } + + // Specific flag keys are unknown, so this payload only reports that something changed. + // An event already queued says exactly the same thing, which is why a full channel is + // left alone: the notification is on its way regardless. + EventChannel.Writer.TryWrite(CreatePayload(ProviderEventTypes.ProviderConfigurationChanged, "A backend update occurred, but specific changes are unknown.")); } catch { } } + private void SignalReady() + { + var payload = CreatePayload(ProviderEventTypes.ProviderReady, "Feature flag configuration was received."); + + if (EventChannel.Writer.TryWrite(payload)) + { + return; + } + + // Unlike a change notification, this one cannot be dropped: losing it would leave the provider + // reported as errored for the rest of the process even though it can now resolve flags. The + // channel holds a single item, so waiting for room happens in the background rather than on the + // thread applying the configuration. Only ever one such write exists, because it is signalled once. + _ = WriteWhenRoomAvailableAsync(payload); + } + + private async Task WriteWhenRoomAvailableAsync(ProviderEventPayload payload) + { + try + { + await EventChannel.Writer.WriteAsync(payload).ConfigureAwait(false); + } + catch + { + // The channel is completed when the provider is replaced or the SDK shuts down, at which + // point this provider's status no longer matters. + } + } + + private ProviderEventPayload CreatePayload(ProviderEventTypes type, string message) + => new ProviderEventPayload + { + Type = type, + Message = message, + ProviderName = _metadata.Name, + }; + /// /// Starts flag configuration delivery and waits for the first configuration, so that a ready /// provider can actually resolve flags. From 154ef588eb8840e5a832ffed0ea8ec6e95a9bfad Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 20 Aug 2026 17:34:26 +0300 Subject: [PATCH 31/86] [FeatureFlags] Apply dd_env per request instead of baking it into the endpoint --- .../Configuration/TracerSettings.cs | 8 +- .../Agentless/AgentlessEndpoint.cs | 89 ++++++++++++++++--- .../FeatureFlags/FeatureFlagsSettings.cs | 14 +-- .../FeatureFlags/AgentlessEndpointTests.cs | 60 ++++++++++--- .../FeatureFlags/FeatureFlagsSettingsTests.cs | 2 +- 5 files changed, 132 insertions(+), 41 deletions(-) diff --git a/tracer/src/Datadog.Trace/Configuration/TracerSettings.cs b/tracer/src/Datadog.Trace/Configuration/TracerSettings.cs index 1ce04feb0861..6051c80536d2 100644 --- a/tracer/src/Datadog.Trace/Configuration/TracerSettings.cs +++ b/tracer/src/Datadog.Trace/Configuration/TracerSettings.cs @@ -889,10 +889,10 @@ not null when string.Equals(value, "otlp", StringComparison.OrdinalIgnoreCase) = Manager = new(source, this, telemetry, errorLog); - // Created after the manager so the environment can be taken from the initial mutable - // settings, which also honour the "env" entry of DD_TAGS. It is captured once, so a - // later dynamic-configuration change to "env" does not move the agentless endpoint. - FeatureFlags = new FeatureFlagsSettings(source, telemetry, Manager.InitialMutableSettings.Environment); + // The environment is deliberately not passed in: it can be changed in code after + // startup, so the delivery source subscribes to the manager and applies the current + // value per request instead of capturing one here. + FeatureFlags = new FeatureFlagsSettings(source, telemetry); // OTLP span metrics require OTLP trace export (see TracerManagerFactory.GetAgentWriter). // Force to false otherwise, even if explicitly requested. diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs index 2ebc7b03b3b3..a779d909a731 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs @@ -29,14 +29,25 @@ internal sealed class AgentlessEndpoint /// internal const string ManagedHostPrefix = "ufc-server.ff-cdn."; - private AgentlessEndpoint(Uri uri, bool isManaged) + /// + /// The query parameter carrying the environment to request configuration for. + /// + internal const string EnvParameterName = "dd_env"; + + // Set when the configured base URL already carries dd_env. The operator chose that value + // deliberately, so it is left alone rather than duplicated or overwritten. + private readonly bool _pinsEnv; + + private AgentlessEndpoint(Uri uri, bool isManaged, bool pinsEnv) { Uri = uri; IsManaged = isManaged; + _pinsEnv = pinsEnv; } /// - /// Gets the endpoint URI. + /// Gets the endpoint URI, without the environment. Use to get the + /// URI to request. /// public Uri Uri { get; } @@ -50,17 +61,19 @@ private AgentlessEndpoint(Uri uri, bool isManaged) /// /// Builds the endpoint. Without a custom the managed Datadog CDN /// endpoint is derived from the (lowercased) site, so staging and government sites resolve - /// with no allowlist, and dd_env is added only when an environment is configured. - /// A custom base URL that is an origin receives the canonical path; one that carries a path - /// is used verbatim. + /// with no allowlist. A custom base URL that is an origin receives the canonical path; one that + /// carries a path is used verbatim. + /// + /// The environment is not part of the endpoint: it can be changed in code while the application + /// runs, so it is applied per request by instead. + /// /// /// The Datadog site, for example datadoghq.com. - /// The configured environment, or null. /// The configured endpoint override, or null. /// The resulting endpoint, or null when none could be built. /// Why the configured base URL was rejected. Never contains the URL, which may carry credentials. /// true when an endpoint could be built. - public static bool TryCreate(string? site, string? env, string? baseUrl, [NotNullWhen(true)] out AgentlessEndpoint? endpoint, out string? error) + public static bool TryCreate(string? site, string? baseUrl, [NotNullWhen(true)] out AgentlessEndpoint? endpoint, out string? error) { endpoint = null; error = null; @@ -92,12 +105,7 @@ public static bool TryCreate(string? site, string? env, string? baseUrl, [NotNul return false; } - if (!StringUtil.IsNullOrEmpty(env)) - { - managedUri = new UriBuilder(managedUri) { Query = "dd_env=" + Uri.EscapeDataString(env) }.Uri; - } - - endpoint = new AgentlessEndpoint(managedUri, isManaged: true); + endpoint = new AgentlessEndpoint(managedUri, isManaged: true, pinsEnv: false); return true; } @@ -129,7 +137,60 @@ public static bool TryCreate(string? site, string? env, string? baseUrl, [NotNul custom = new UriBuilder(custom) { Path = DefaultPath }.Uri; } - endpoint = new AgentlessEndpoint(custom, isManaged: false); + endpoint = new AgentlessEndpoint(custom, isManaged: false, pinsEnv: HasEnvParameter(custom.Query)); return true; } + + /// + /// Returns the URI to request configuration for . The environment is + /// added as a query parameter rather than baked into the endpoint, because it can change while + /// the application runs. + /// + /// Any query the configured base URL already carries is kept: it may hold credentials or routing + /// the operator needs. An endpoint that already pins dd_env is returned unchanged. + /// + /// + /// The current environment, or null when none is configured. + /// The URI to request. + public Uri BuildRequestUri(string? env) + { + if (_pinsEnv || StringUtil.IsNullOrEmpty(env)) + { + return Uri; + } + + var parameter = EnvParameterName + "=" + Uri.EscapeDataString(env); + var builder = new UriBuilder(Uri); + + // The getter returns the query with its leading "?", and the setter keeps one that is + // already there, so an existing query can be extended without trimming it first. A URL + // ending in a bare "?" reports an empty query, which the length check treats as no query. + builder.Query = builder.Query.Length > 1 ? builder.Query + "&" + parameter : parameter; + return builder.Uri; + } + + /// + /// Reports whether a query string already carries a dd_env parameter. Matching the name + /// alone would also hit a value such as ?next=dd_env, so the surrounding delimiters are + /// checked too. + /// + private static bool HasEnvParameter(string query) + { + var index = query.IndexOf(EnvParameterName, StringComparison.OrdinalIgnoreCase); + while (index >= 0) + { + var preceding = index == 0 ? '?' : query[index - 1]; + var followingIndex = index + EnvParameterName.Length; + var following = followingIndex < query.Length ? query[followingIndex] : '\0'; + + if (preceding is '?' or '&' && following is '=' or '&' or '\0') + { + return true; + } + + index = query.IndexOf(EnvParameterName, index + 1, StringComparison.OrdinalIgnoreCase); + } + + return false; + } } diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs index f9c804f30364..3ebd6419e7e6 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs @@ -36,7 +36,7 @@ internal sealed class FeatureFlagsSettings private static readonly IDatadogLogger Log = DatadogLogging.GetLoggerFor(typeof(FeatureFlagsSettings)); - public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetry telemetry, string? env) + public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetry telemetry) { source ??= NullConfigurationSource.Instance; var config = new ConfigurationBuilder(source, telemetry); @@ -96,13 +96,12 @@ public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetr .Value); // DD_SITE and DD_API_KEY are not extracted on TracerSettings, so they are read here as the - // other product settings do (TelemetrySettings, DirectLogSubmissionSettings). DD_ENV is - // passed in, because TracerSettings also honours the "env" entry of DD_TAGS and re-reading - // the key alone would disagree with the rest of the tracer. + // other product settings do (TelemetrySettings, DirectLogSubmissionSettings). DD_ENV is not + // read at all: it can be changed in code while the application runs, so the delivery source + // takes the current value per request rather than capturing one here. Site = config .WithKeys(ConfigurationKeys.Site) .AsString(DefaultSite, static site => !StringUtil.IsNullOrWhiteSpace(site)); - Env = env; ApiKey = config.WithKeys(ConfigurationKeys.ApiKey).AsRedactedString(); var initializationTimeoutMs = config @@ -132,11 +131,6 @@ public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetr /// public string Site { get; } - /// - /// Gets the configured environment, sent to the agentless endpoint as dd_env. - /// - public string? Env { get; } - /// /// Gets the API key, required by the managed agentless endpoint. /// diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs index 2fbda55d3836..0edc9f96bdcb 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs @@ -30,16 +30,52 @@ public void DerivesManagedEndpointFromSite(string site, string expected) } [Fact] - public void AddsDdEnvWhenEnvIsConfigured() - => Create("datadoghq.com", env: "production").Uri.Query.Should().Be("?dd_env=production"); + public void EndpointItselfCarriesNoEnvironment() + => Create("datadoghq.com").Uri.Query.Should().BeEmpty(); [Fact] - public void DoesNotAddDdEnvWhenEnvIsNull() - => Create("datadoghq.com").Uri.Query.Should().BeEmpty(); + public void AddsDdEnvWhenEnvIsConfigured() + => Create("datadoghq.com").BuildRequestUri("production").Query.Should().Be("?dd_env=production"); + + [Theory] + [InlineData(null)] + [InlineData("")] + public void DoesNotAddDdEnvWhenEnvIsNotConfigured(string? env) + => Create("datadoghq.com").BuildRequestUri(env).Query.Should().BeEmpty(); [Fact] public void EscapesDdEnvValue() - => Create("datadoghq.com", env: "my env&test").Uri.Query.Should().Be("?dd_env=my%20env%26test"); + => Create("datadoghq.com").BuildRequestUri("my env&test").Query.Should().Be("?dd_env=my%20env%26test"); + + [Fact] + public void KeepsTheQueryConfiguredOnACustomEndpoint() + { + // The query may carry credentials or routing the operator needs, so dd_env is appended to it + // rather than replacing it. + var endpoint = Create("datadoghq.com", baseUrl: "https://flags.example.com/ufc?token=abc"); + + endpoint.BuildRequestUri("production").Query.Should().Be("?token=abc&dd_env=production"); + } + + [Theory] + [InlineData("https://flags.example.com/ufc?dd_env=staging")] + [InlineData("https://flags.example.com/ufc?token=abc&dd_env=staging")] + public void LeavesACustomEndpointThatAlreadyPinsDdEnvAlone(string baseUrl) + { + var endpoint = Create("datadoghq.com", baseUrl: baseUrl); + + endpoint.BuildRequestUri("production").Should().Be(endpoint.Uri); + } + + [Fact] + public void AddsDdEnvToACustomEndpointWithoutAQuery() + => Create("datadoghq.com", baseUrl: "https://flags.example.com/ufc") + .BuildRequestUri("production").Query.Should().Be("?dd_env=production"); + + [Fact] + public void DoesNotMistakeAQueryValueForAPinnedDdEnv() + => Create("datadoghq.com", baseUrl: "https://flags.example.com/ufc?next=dd_env") + .BuildRequestUri("production").Query.Should().Be("?next=dd_env&dd_env=production"); [Theory] [InlineData("https://flags.example.com", "https://flags.example.com" + DefaultPath)] @@ -65,7 +101,7 @@ public void CustomEndpointAcceptsHttp(string baseUrl) [InlineData("https://flags.example.com bad", "The configured Feature Flags agentless URL is not a valid URL")] // internal whitespace public void RejectsInvalidBaseUrl(string baseUrl, string expectedError) { - AgentlessEndpoint.TryCreate("datadoghq.com", env: null, baseUrl: baseUrl, out var endpoint, out var error) + AgentlessEndpoint.TryCreate("datadoghq.com", baseUrl: baseUrl, out var endpoint, out var error) .Should().BeFalse(); error.Should().Be(expectedError); endpoint.Should().BeNull(); @@ -74,7 +110,7 @@ public void RejectsInvalidBaseUrl(string baseUrl, string expectedError) [Fact] public void RejectsEmptySiteWithoutBaseUrl() { - AgentlessEndpoint.TryCreate(site: null, env: null, baseUrl: null, out var endpoint, out var error) + AgentlessEndpoint.TryCreate(site: null, baseUrl: null, out var endpoint, out var error) .Should().BeFalse(); error.Should().Be("No Datadog site is configured"); endpoint.Should().BeNull(); @@ -83,7 +119,7 @@ public void RejectsEmptySiteWithoutBaseUrl() [Fact] public void RejectsWhitespaceOnlySiteWithoutBaseUrl() { - AgentlessEndpoint.TryCreate(" ", env: null, baseUrl: null, out var endpoint, out var error) + AgentlessEndpoint.TryCreate(" ", baseUrl: null, out var endpoint, out var error) .Should().BeFalse(); error.Should().Be("No Datadog site is configured"); endpoint.Should().BeNull(); @@ -95,7 +131,7 @@ public void RejectsWhitespaceOnlySiteWithoutBaseUrl() [InlineData("datadoghq.com:99999")] // invalid port public void RejectsMalformedSiteWithoutThrowing(string site) { - AgentlessEndpoint.TryCreate(site, env: null, baseUrl: null, out var endpoint, out var error) + AgentlessEndpoint.TryCreate(site, baseUrl: null, out var endpoint, out var error) .Should().BeFalse(); error.Should().Be("The configured Datadog site is not valid"); endpoint.Should().BeNull(); @@ -105,7 +141,7 @@ public void RejectsMalformedSiteWithoutThrowing(string site) public void ErrorNeverContainsUrl() { // A URL may carry credentials, so the error must never echo it. - AgentlessEndpoint.TryCreate("datadoghq.com", env: null, baseUrl: "https://user:pass@flags.example.com bad", out _, out var error) + AgentlessEndpoint.TryCreate("datadoghq.com", baseUrl: "https://user:pass@flags.example.com bad", out _, out var error) .Should().BeFalse(); error.Should().NotContain("user"); error.Should().NotContain("pass"); @@ -115,9 +151,9 @@ public void ErrorNeverContainsUrl() // assertions can read it directly. Throwing rather than asserting keeps the compiler's nullable // analysis satisfied without a null-forgiving operator, which would let an assertion be // silently skipped if the endpoint were ever null. - private static AgentlessEndpoint Create(string? site, string? env = null, string? baseUrl = null) + private static AgentlessEndpoint Create(string? site, string? baseUrl = null) { - AgentlessEndpoint.TryCreate(site, env, baseUrl, out var endpoint, out var error) + AgentlessEndpoint.TryCreate(site, baseUrl, out var endpoint, out var error) .Should().BeTrue(); error.Should().BeNull(); diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs index efd24e3d9419..a55e21c5e765 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs @@ -201,6 +201,6 @@ private static FeatureFlagsSettings CreateSettings( collection[key] = value; } - return new FeatureFlagsSettings(new NameValueConfigurationSource(collection), NullConfigurationTelemetry.Instance, env: null); + return new FeatureFlagsSettings(new NameValueConfigurationSource(collection), NullConfigurationTelemetry.Instance); } } From dbae9dc71ce81c5abd011dfa15b23a70c704f84f Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 20 Aug 2026 17:41:41 +0300 Subject: [PATCH 32/86] [FeatureFlags] Normalize dd_env the same way span tags are normalized --- .../Agentless/AgentlessEndpoint.cs | 15 +++++++++++-- .../FeatureFlags/AgentlessEndpointTests.cs | 22 ++++++++++++++++++- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs index a779d909a731..5fa9e07a7892 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs @@ -7,6 +7,7 @@ using System; using System.Diagnostics.CodeAnalysis; +using Datadog.Trace.Processors; using Datadog.Trace.Util; namespace Datadog.Trace.FeatureFlags.Agentless; @@ -154,12 +155,22 @@ public static bool TryCreate(string? site, string? baseUrl, [NotNullWhen(true)] /// The URI to request. public Uri BuildRequestUri(string? env) { - if (_pinsEnv || StringUtil.IsNullOrEmpty(env)) + if (_pinsEnv) { return Uri; } - var parameter = EnvParameterName + "=" + Uri.EscapeDataString(env); + // Normalized the same way the tracer normalizes it before tagging spans, so that flag + // targeting and span tags agree on what the environment is. It also bounds the value at 200 + // characters, which keeps a misconfigured environment from producing an unusable URL. + // A value that normalizes to nothing is treated as no environment at all. + var normalized = TraceUtil.NormalizeTag(env); + if (StringUtil.IsNullOrEmpty(normalized)) + { + return Uri; + } + + var parameter = EnvParameterName + "=" + Uri.EscapeDataString(normalized); var builder = new UriBuilder(Uri); // The getter returns the query with its leading "?", and the setter keeps one that is diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs index 0edc9f96bdcb..2f53914f4b7c 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs @@ -40,12 +40,32 @@ public void AddsDdEnvWhenEnvIsConfigured() [Theory] [InlineData(null)] [InlineData("")] + [InlineData(" ")] + // The tracer's tag normalization requires a leading letter, so a value that is entirely digits + // normalizes away. Spans are tagged the same way, so no environment is reported either. + [InlineData("2024")] public void DoesNotAddDdEnvWhenEnvIsNotConfigured(string? env) => Create("datadoghq.com").BuildRequestUri(env).Query.Should().BeEmpty(); + [Theory] + // Normalized exactly as the tracer normalizes the environment before tagging spans: lowercased, + // with runs of unsupported characters collapsed to a single underscore. + [InlineData("Production", "production")] + [InlineData("Prod EU", "prod_eu")] + [InlineData(" staging ", "staging")] + [InlineData("my env&test", "my_env_test")] + public void NormalizesDdEnvValue(string env, string expected) + => Create("datadoghq.com").BuildRequestUri(env).Query.Should().Be("?dd_env=" + expected); + [Fact] public void EscapesDdEnvValue() - => Create("datadoghq.com").BuildRequestUri("my env&test").Query.Should().Be("?dd_env=my%20env%26test"); + // "/" survives normalization but cannot be carried unescaped in a query value. + => Create("datadoghq.com").BuildRequestUri("team/a").Query.Should().Be("?dd_env=team%2Fa"); + + [Fact] + public void TruncatesAnOverlongDdEnvValue() + => Create("datadoghq.com").BuildRequestUri(new string('a', 500)) + .Query.Should().Be("?dd_env=" + new string('a', 200)); [Fact] public void KeepsTheQueryConfiguredOnACustomEndpoint() From 7c7d7e6f6214d17fa9c7e9cdea20fe222299aeb6 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 20 Aug 2026 17:48:16 +0300 Subject: [PATCH 33/86] [FeatureFlags] Report an unrecognised configuration source as a parsing failure --- .../Configuration/supported-configurations.yaml | 7 ++++--- .../Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs | 8 ++++---- .../ConfigurationKeys.FeatureFlags.g.cs | 7 ++++--- .../ConfigurationKeys.FeatureFlags.g.cs | 7 ++++--- .../ConfigurationKeys.FeatureFlags.g.cs | 7 ++++--- .../ConfigurationKeys.FeatureFlags.g.cs | 7 ++++--- .../FeatureFlags/FeatureFlagsSettingsTests.cs | 7 ++++--- 7 files changed, 28 insertions(+), 22 deletions(-) diff --git a/tracer/src/Datadog.Trace/Configuration/supported-configurations.yaml b/tracer/src/Datadog.Trace/Configuration/supported-configurations.yaml index 33a8c0f6a63b..3523c5a3c676 100644 --- a/tracer/src/Datadog.Trace/Configuration/supported-configurations.yaml +++ b/tracer/src/Datadog.Trace/Configuration/supported-configurations.yaml @@ -3192,9 +3192,10 @@ supportedConfigurations: const_name: FeatureFlagsConfigurationSource documentation: |- Configuration key for selecting where flag configuration is loaded from. - Supported values are agentless (direct HTTP delivery, the default) and - remote_config (delivery through the Datadog Agent's Remote Configuration). - Any other value disables Feature Flags, which fails closed and contacts nothing. + Supported values are agentless (direct HTTP delivery, the default), + remote_config (delivery through the Datadog Agent's Remote Configuration) + and offline, which disables Feature Flags and contacts nothing. + Any other value is rejected and the default applies. DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_BASE_URL: - implementation: A scope: managed diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs index 3ebd6419e7e6..426bd6780484 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs @@ -153,9 +153,9 @@ public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetr /// /// Converts a configured source name to a . A blank value is - /// treated as unset so the default applies, and an unrecognised one fails closed: it resolves - /// to rather than falling back to a billed delivery - /// path, which is why it is reported as a successful conversion. + /// treated as unset, and an unrecognised one is reported as a parsing failure so that it shows + /// up as rejected in configuration telemetry rather than as a value nobody configured. Both + /// fall back to the default, which is what an unset key would have selected anyway. /// private static ParsingResult ConvertSource(string? value) { @@ -171,7 +171,7 @@ private static ParsingResult ConvertSource(string? value) return ParsingResult.Success(source); } - return ParsingResult.Success(FeatureFlagsSource.Disabled); + return ParsingResult.Failure(); } private static bool TryMatch(string value, out FeatureFlagsSource source) diff --git a/tracer/src/Datadog.Trace/Generated/net461/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs b/tracer/src/Datadog.Trace/Generated/net461/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs index c0bc6ef9a199..6d3efb137e4e 100644 --- a/tracer/src/Datadog.Trace/Generated/net461/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs +++ b/tracer/src/Datadog.Trace/Generated/net461/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs @@ -40,9 +40,10 @@ internal static class FeatureFlags /// /// Configuration key for selecting where flag configuration is loaded from. - /// Supported values are agentless (direct HTTP delivery, the default) and - /// remote_config (delivery through the Datadog Agent's Remote Configuration). - /// Any other value disables Feature Flags, which fails closed and contacts nothing. + /// Supported values are agentless (direct HTTP delivery, the default), + /// remote_config (delivery through the Datadog Agent's Remote Configuration) + /// and offline, which disables Feature Flags and contacts nothing. + /// Any other value is rejected and the default applies. /// public const string FeatureFlagsConfigurationSource = "DD_FEATURE_FLAGS_CONFIGURATION_SOURCE"; diff --git a/tracer/src/Datadog.Trace/Generated/net6.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs b/tracer/src/Datadog.Trace/Generated/net6.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs index c0bc6ef9a199..6d3efb137e4e 100644 --- a/tracer/src/Datadog.Trace/Generated/net6.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs +++ b/tracer/src/Datadog.Trace/Generated/net6.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs @@ -40,9 +40,10 @@ internal static class FeatureFlags /// /// Configuration key for selecting where flag configuration is loaded from. - /// Supported values are agentless (direct HTTP delivery, the default) and - /// remote_config (delivery through the Datadog Agent's Remote Configuration). - /// Any other value disables Feature Flags, which fails closed and contacts nothing. + /// Supported values are agentless (direct HTTP delivery, the default), + /// remote_config (delivery through the Datadog Agent's Remote Configuration) + /// and offline, which disables Feature Flags and contacts nothing. + /// Any other value is rejected and the default applies. /// public const string FeatureFlagsConfigurationSource = "DD_FEATURE_FLAGS_CONFIGURATION_SOURCE"; diff --git a/tracer/src/Datadog.Trace/Generated/netcoreapp3.1/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs b/tracer/src/Datadog.Trace/Generated/netcoreapp3.1/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs index c0bc6ef9a199..6d3efb137e4e 100644 --- a/tracer/src/Datadog.Trace/Generated/netcoreapp3.1/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs +++ b/tracer/src/Datadog.Trace/Generated/netcoreapp3.1/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs @@ -40,9 +40,10 @@ internal static class FeatureFlags /// /// Configuration key for selecting where flag configuration is loaded from. - /// Supported values are agentless (direct HTTP delivery, the default) and - /// remote_config (delivery through the Datadog Agent's Remote Configuration). - /// Any other value disables Feature Flags, which fails closed and contacts nothing. + /// Supported values are agentless (direct HTTP delivery, the default), + /// remote_config (delivery through the Datadog Agent's Remote Configuration) + /// and offline, which disables Feature Flags and contacts nothing. + /// Any other value is rejected and the default applies. /// public const string FeatureFlagsConfigurationSource = "DD_FEATURE_FLAGS_CONFIGURATION_SOURCE"; diff --git a/tracer/src/Datadog.Trace/Generated/netstandard2.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs b/tracer/src/Datadog.Trace/Generated/netstandard2.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs index c0bc6ef9a199..6d3efb137e4e 100644 --- a/tracer/src/Datadog.Trace/Generated/netstandard2.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs +++ b/tracer/src/Datadog.Trace/Generated/netstandard2.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs @@ -40,9 +40,10 @@ internal static class FeatureFlags /// /// Configuration key for selecting where flag configuration is loaded from. - /// Supported values are agentless (direct HTTP delivery, the default) and - /// remote_config (delivery through the Datadog Agent's Remote Configuration). - /// Any other value disables Feature Flags, which fails closed and contacts nothing. + /// Supported values are agentless (direct HTTP delivery, the default), + /// remote_config (delivery through the Datadog Agent's Remote Configuration) + /// and offline, which disables Feature Flags and contacts nothing. + /// Any other value is rejected and the default applies. /// public const string FeatureFlagsConfigurationSource = "DD_FEATURE_FLAGS_CONFIGURATION_SOURCE"; diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs index a55e21c5e765..3dafd5457de1 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs @@ -39,9 +39,10 @@ public class FeatureFlagsSettingsTests // does not silently keep Feature Flags off during migration. [InlineData("true", null, "false", FeatureFlagsSource.Agentless)] [InlineData("true", null, "true", FeatureFlagsSource.Agentless)] - // An unrecognised source fails closed rather than guessing a billed delivery path. - [InlineData(null, "invalid", null, FeatureFlagsSource.Disabled)] - [InlineData(null, "invalid", "true", FeatureFlagsSource.Disabled)] + // An unrecognised source is a parsing failure, reported as such in configuration telemetry, so + // the key behaves as if it were unset rather than resolving to a value nobody configured. + [InlineData(null, "invalid", null, FeatureFlagsSource.Agentless)] + [InlineData(null, "invalid", "true", FeatureFlagsSource.RemoteConfig)] // "offline" is a reserved, recognised fail-closed sentinel (not an unrecognised value). [InlineData(null, "offline", null, FeatureFlagsSource.Disabled)] [InlineData(null, "offline", "true", FeatureFlagsSource.Disabled)] From 89357807915bc73adeb855092cac899780954d12 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 20 Aug 2026 18:18:37 +0300 Subject: [PATCH 34/86] [FeatureFlags] Poll for the current environment instead of the one captured at startup --- .../Agentless/AgentlessConfigurationSource.cs | 66 ++++++++++++++++--- .../AgentlessConfigurationSourceTests.cs | 47 ++++++++++++- 2 files changed, 102 insertions(+), 11 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs index 4f2658fda111..a0bdd1279537 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs @@ -13,6 +13,7 @@ using System.Threading.Tasks; using Datadog.Trace.Agent; using Datadog.Trace.Agent.Transports; +using Datadog.Trace.Configuration; using Datadog.Trace.FeatureFlags.Rcm.Model; using Datadog.Trace.Headers; using Datadog.Trace.Logging; @@ -42,7 +43,7 @@ internal sealed class AgentlessConfigurationSource : IDisposable private static readonly IDatadogLogger Log = DatadogLogging.GetLoggerFor(typeof(AgentlessConfigurationSource)); private readonly IApiRequestFactory _requestFactory; - private readonly Uri _endpoint; + private readonly AgentlessEndpoint _endpoint; private readonly TimeSpan _pollInterval; private readonly TimeSpan _requestTimeout; private readonly Func _applyConfiguration; @@ -52,18 +53,26 @@ internal sealed class AgentlessConfigurationSource : IDisposable // Only ever touched from the poll loop. private readonly HashSet _loggedFailureCategories = new(); + + // Written by the settings-change callback, read by the poll loop. + private string? _environment; + private IDisposable? _environmentSubscription; + + // Only ever touched from the poll loop. private bool _malformedPayloadLogged; private bool _applyFailureLogged; private string? _etag; + private Uri? _etagUri; private int _started; internal AgentlessConfigurationSource( - Uri endpoint, + AgentlessEndpoint endpoint, IApiRequestFactory requestFactory, TimeSpan pollInterval, TimeSpan requestTimeout, Func applyConfiguration, + string? environment = null, Func? waitAsync = null) { _endpoint = endpoint; @@ -71,6 +80,7 @@ internal AgentlessConfigurationSource( _pollInterval = pollInterval; _requestTimeout = requestTimeout; _applyConfiguration = applyConfiguration; + _environment = environment; _waitAsync = waitAsync ?? Task.Delay; } @@ -79,9 +89,12 @@ internal AgentlessConfigurationSource( /// not a URL, or the managed endpoint without an API key. Polling anyway would only produce /// failures every interval. /// - public static AgentlessConfigurationSource? Create(FeatureFlagsSettings settings, Func applyConfiguration) + public static AgentlessConfigurationSource? Create( + FeatureFlagsSettings settings, + TracerSettings.SettingsManager manager, + Func applyConfiguration) { - if (!AgentlessEndpoint.TryCreate(settings.Site, settings.Env, settings.AgentlessBaseUrl, out var endpoint, out var error)) + if (!AgentlessEndpoint.TryCreate(settings.Site, settings.AgentlessBaseUrl, out var endpoint, out var error)) { Log.Error("Feature Flags agentless source is unavailable: {Error}", error); return null; @@ -93,14 +106,34 @@ internal AgentlessConfigurationSource( return null; } - return new AgentlessConfigurationSource( - endpoint.Uri, + var source = new AgentlessConfigurationSource( + endpoint, CreateRequestFactory(endpoint, settings), settings.PollInterval, settings.RequestTimeout, - applyConfiguration); + applyConfiguration, + manager.InitialMutableSettings.Environment); + + // The environment is tracked rather than captured: customers can change it in code while + // the application runs, and flags are targeted per environment. Only the value is stored + // here, so that the poll loop stays the only thing that touches the request state. + source._environmentSubscription = manager.SubscribeToChanges(changes => + { + if (changes.UpdatedMutable is { } mutable) + { + source.UpdateEnvironment(mutable.Environment); + } + }); + + return source; } + /// + /// Records the environment to request configuration for. Applied by the poll loop on its next + /// request, so a change never disturbs a request already in flight. + /// + internal void UpdateEnvironment(string? environment) => Volatile.Write(ref _environment, environment); + /// /// Starts polling. Idempotent. /// @@ -172,6 +205,7 @@ public void Dispose() // from applying its result by the shutdown check in PollAsync. try { + _environmentSubscription?.Dispose(); _shutdown.Cancel(); } catch (Exception ex) @@ -207,6 +241,8 @@ private static ApiWebRequestFactory CreateRequestFactory(AgentlessEndpoint endpo headers.Add(new(TelemetryConstants.ApiKeyHeader, settings.ApiKey!)); } + // The endpoint is only the factory's default: both transports honour the URI passed to + // Create, which is what carries the current environment. #if NETCOREAPP return new HttpClientRequestFactory(endpoint.Uri, headers.ToArray(), timeout: settings.RequestTimeout); #else @@ -273,7 +309,21 @@ private async Task RequestAsync() { try { - var request = _requestFactory.Create(_endpoint); + // The environment is applied per request rather than baked into the endpoint, because + // it can be changed in code after startup. + var uri = _endpoint.BuildRequestUri(Volatile.Read(ref _environment)); + + // An ETag only identifies the configuration served for the URI it came from. Sending it + // against a different environment would earn a 304 and pin the process to the previous + // environment's flags, with no way back. + if (_etagUri is not null && uri != _etagUri) + { + _etag = null; + } + + _etagUri = uri; + + var request = _requestFactory.Create(uri); if (_etag is { } etag) { request.AddHeader("If-None-Match", etag); diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs index e2e39a15acde..a807554c0cc7 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs @@ -30,7 +30,7 @@ public class AgentlessConfigurationSourceTests "environment": { "name": "production" }, "flags": {} } } } """; - private static readonly Uri Endpoint = new("https://ufc-server.ff-cdn.datadoghq.com/api/v2/feature-flagging/config/rules-based/server"); + private const string EndpointUrl = "https://ufc-server.ff-cdn.datadoghq.com/api/v2/feature-flagging/config/rules-based/server"; [Fact] public async Task AppliesConfigurationFromA200() @@ -64,6 +64,37 @@ public async Task SendsTheEtagOfTheLastAppliedConfiguration() factory.RequestsSent[1].ExtraHeaders["If-None-Match"].Should().Be("\"ufc-v1\""); } + [Fact] + public async Task RequestsTheConfiguredEnvironment() + { + var applied = new List(); + var factory = new TestRequestFactory(uri => new TestApiRequest(uri, responseContent: Body)); + using var source = CreateSource(factory, applied, environment: "production"); + + await source.PollAsync(); + + factory.RequestsSent[0].Endpoint.Should().Be(new Uri(EndpointUrl + "?dd_env=production")); + } + + [Fact] + public async Task DropsTheEtagWhenTheEnvironmentChanges() + { + var applied = new List(); + var factory = new TestRequestFactory( + uri => new TestApiRequest(uri, responseContent: Body, responseHeaders: new() { { "ETag", "\"ufc-v1\"" } })); + using var source = CreateSource(factory, applied, environment: "production"); + + await source.PollAsync(); + + // The ETag identifies production's configuration, so it must not be sent against staging: + // a 304 would pin the process to production's flags with no way back. + source.UpdateEnvironment("staging"); + await source.PollAsync(); + + factory.RequestsSent[1].Endpoint.Should().Be(new Uri(EndpointUrl + "?dd_env=staging")); + factory.RequestsSent[1].ExtraHeaders.Should().NotContainKey("If-None-Match"); + } + [Fact] public async Task DoesNotApplyOn304() { @@ -211,9 +242,12 @@ public async Task HandlesNetworkError() factory.RequestsSent.Should().HaveCount(3); } - private static AgentlessConfigurationSource CreateSource(TestRequestFactory factory, List applied) + private static AgentlessConfigurationSource CreateSource( + TestRequestFactory factory, + List applied, + string? environment = null) => new( - Endpoint, + CreateEndpoint(), factory, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(5), @@ -222,8 +256,15 @@ private static AgentlessConfigurationSource CreateSource(TestRequestFactory fact applied.Add(configuration); return true; }, + environment, NoWait); + private static AgentlessEndpoint CreateEndpoint() + { + AgentlessEndpoint.TryCreate("datadoghq.com", baseUrl: null, out var endpoint, out _).Should().BeTrue(); + return endpoint ?? throw new InvalidOperationException("TryCreate reported success without producing an endpoint."); + } + private static Task NoWait(TimeSpan delay, CancellationToken cancellationToken) => Task.CompletedTask; private class ThrowingApiRequest(Uri endpoint) : TestApiRequest(endpoint) From 2317ea8fff30107dbe1fda02dca5c36828c99ee2 Mon Sep 17 00:00:00 2001 From: Pavel Date: Tue, 25 Aug 2026 15:39:15 +0300 Subject: [PATCH 35/86] [FeatureFlags] Fix double question mark in agentless request URI on .NET Framework --- .../FeatureFlags/Agentless/AgentlessEndpoint.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs index 5fa9e07a7892..11e258035245 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs @@ -173,10 +173,11 @@ public Uri BuildRequestUri(string? env) var parameter = EnvParameterName + "=" + Uri.EscapeDataString(normalized); var builder = new UriBuilder(Uri); - // The getter returns the query with its leading "?", and the setter keeps one that is - // already there, so an existing query can be extended without trimming it first. A URL - // ending in a bare "?" reports an empty query, which the length check treats as no query. - builder.Query = builder.Query.Length > 1 ? builder.Query + "&" + parameter : parameter; + // The getter returns the query with its leading "?", while the setter prepends one of its + // own on .NET Framework, so the existing query is trimmed before it is extended. A URL + // ending in a bare "?" reports a query of "?", which the length check treats as no query. + var existing = builder.Query; + builder.Query = existing.Length > 1 ? existing.TrimStart('?') + "&" + parameter : parameter; return builder.Uri; } From 574fa0dd2f5c4fcf212f90ca87f0ec92d20ddb2d Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 26 Aug 2026 11:44:41 +0300 Subject: [PATCH 36/86] [FeatureFlags] Subscribe to FFE_FLAGS at startup for the remote_config source --- ...penFeatureSdkInitializeAsyncIntegration.cs | 6 +- .../FeatureFlags/FeatureFlagsModule.cs | 74 +++++++++++++------ .../FeatureFlags/FeatureFlagsModuleTests.cs | 34 ++++----- 3 files changed, 73 insertions(+), 41 deletions(-) diff --git a/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/ManualInstrumentation/OpenFeature/OpenFeatureSdkInitializeAsyncIntegration.cs b/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/ManualInstrumentation/OpenFeature/OpenFeatureSdkInitializeAsyncIntegration.cs index ae703643300c..e26809b3cd47 100644 --- a/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/ManualInstrumentation/OpenFeature/OpenFeatureSdkInitializeAsyncIntegration.cs +++ b/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/ManualInstrumentation/OpenFeature/OpenFeatureSdkInitializeAsyncIntegration.cs @@ -39,8 +39,10 @@ internal static CallTargetReturn OnMethodEnd(Task returnValue, Ex return new CallTargetReturn(returnValue); } - // Delivery only starts here, because requesting configuration is billable, and the tracer - // must not start until application code adopts the provider. + // Agentless polling only starts here, because those requests go straight to Datadog and are + // billable, so the tracer must not start them until application code adopts the provider. The + // Remote Configuration source is already subscribed by then; this call waits for its first + // configuration. if (TracerManager.Instance.FeatureFlags is { } featureFlags) { var cancellationToken = state.State is CancellationToken token ? token : default; diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs index 0119167dfcb3..12f4b7ce0eee 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs @@ -77,7 +77,16 @@ internal FeatureFlagsModule(TracerSettings settings, IRcmSubscriptionManager rcm return null; } - return new FeatureFlagsModule(settings, rcmSubscriptionManager); + var module = new FeatureFlagsModule(settings, rcmSubscriptionManager); + + // Subscribing here rather than in the constructor: SubscribeToChanges can invoke the + // callback, which must not reach a module that is still being constructed. + if (settings.FeatureFlags.Source == FeatureFlagsSource.RemoteConfig) + { + module.SubscribeToRemoteConfiguration(); + } + + return module; } public void Dispose() @@ -116,8 +125,13 @@ public void Dispose() } /// - /// Signals that application code initialized the provider. Configuration is only requested - /// from this point on, because those requests are billable. Idempotent. + /// Signals that application code initialized the provider. Idempotent. + /// + /// This is where the agentless source starts, because its requests go straight to Datadog and + /// are billable, so nothing is sent until the application adopts the provider. The Remote + /// Configuration source does not wait here: it rides the poll the agent already performs, and + /// every other tracer subscribes to it at startup. + /// /// internal void Activate() { @@ -134,23 +148,6 @@ internal void Activate() switch (_settings.Source) { - case FeatureFlagsSource.RemoteConfig: - // Remote Configuration subscription is deferred to activation so that merely - // enabling Feature Flags does not start a billed RC subscription. - if (!_isRemoteConfigurationAvailable) - { - Log.Warning("Feature Flags are configured to use the Remote Configuration source, but Remote Configuration is not available. No flag configuration will be received."); - _deliveryUnavailableReason = "the Remote Configuration source is selected, but Remote Configuration is not available in this environment"; - break; - } - - var ffeProduct = new FfeProduct(configs => ApplyConfigurations(configs)); - _rcmSubscription = new Subscription(ffeProduct.UpdateFromRcm, RcmProducts.FfeFlags); - _rcmSubscriptionManager.SubscribeToChanges(_rcmSubscription); - _rcmSubscriptionManager.SetCapability(RcmCapabilitiesIndices.FfeFlagConfigurationRules, true); - _deliveryStarted = true; - Log.Debug("FeatureFlagsModule::Activate -> Remote Configuration source subscribed"); - break; case FeatureFlagsSource.Agentless: // Polling is billable, so it starts here rather than at construction. var source = AgentlessConfigurationSource.Create(_settings, _settingsManager, ApplyConfiguration); @@ -205,8 +202,9 @@ internal async Task InitializeAsync(CancellationToken cancellationToken) deliveryUnavailableReason = _deliveryUnavailableReason; } - // When activation could not start any delivery source (for example, agentless without an - // API key), no configuration can ever arrive, so waiting would only delay startup. + // When no delivery source could start (agentless without an API key, or the Remote + // Configuration source where Remote Configuration is unavailable), no configuration can + // ever arrive, so waiting would only delay startup. // Returning instead would report the provider as usable while every evaluation keeps // returning its default, so the failure is raised: the SDK turns it into an error status // and an error event without taking the application down. @@ -268,6 +266,38 @@ internal bool ApplyConfiguration(ServerConfiguration configuration) } } + /// + /// Subscribes to the Remote Configuration product carrying flag configuration. Called at + /// startup, not on activation: the configuration arrives on the poll the agent already makes, + /// so subscribing early adds no request, and every other tracer subscribes at startup too. + /// Deferring it made .NET the one tracer that never advertised the capability until the + /// application resolved a flag. + /// + private void SubscribeToRemoteConfiguration() + { + lock (_stateLock) + { + if (_disposed) + { + return; + } + + if (!_isRemoteConfigurationAvailable) + { + Log.Warning("Feature Flags are configured to use the Remote Configuration source, but Remote Configuration is not available. No flag configuration will be received."); + _deliveryUnavailableReason = "the Remote Configuration source is selected, but Remote Configuration is not available in this environment"; + return; + } + + var ffeProduct = new FfeProduct(configs => ApplyConfigurations(configs)); + _rcmSubscription = new Subscription(ffeProduct.UpdateFromRcm, RcmProducts.FfeFlags); + _rcmSubscriptionManager.SubscribeToChanges(_rcmSubscription); + _rcmSubscriptionManager.SetCapability(RcmCapabilitiesIndices.FfeFlagConfigurationRules, true); + _deliveryStarted = true; + Log.Debug("FeatureFlagsModule::SubscribeToRemoteConfiguration -> Remote Configuration source subscribed"); + } + } + private void ApplyConfigurations(List> list) { Log.Debug("FeatureFlagsModule::ApplyConfigurations -> New config received. {Count}", list.Count); diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs index c91834803234..eef2ddb993ef 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs @@ -33,8 +33,10 @@ public void UpdateRemoteConfig_WithEmptyList_InvokesCallbackAndReturnsProviderNo // Arrange var rcmManager = new MockRcmSubscriptionManager(); var settings = CreateSettings(); - var module = new FeatureFlagsModule(settings, rcmManager); - module.Activate(); + + // Through Create(), because that is what registers the Remote Configuration subscription + // this test drives. + var module = CreateModule(settings, rcmManager); var callbackInvoked = false; module.RegisterOnNewConfigEventHandler(() => callbackInvoked = true); @@ -49,7 +51,7 @@ public void UpdateRemoteConfig_WithEmptyList_InvokesCallbackAndReturnsProviderNo }); var configPath = RemoteConfigurationPath.FromPath($"datadog/2/{RcmProducts.FfeFlags}/test-config/config"); var subscription = rcmManager.LastSubscription - ?? throw new InvalidOperationException("Activation did not register a Remote Configuration subscription."); + ?? throw new InvalidOperationException("Create did not register a Remote Configuration subscription."); subscription.Invoke( new Dictionary> @@ -100,19 +102,17 @@ public void Create_WithAgentlessSource_DoesNotSubscribeToRc() } [Fact] - public void Create_WithRemoteConfigSource_DoesNotSubscribeUntilActivated() + public void Create_WithRemoteConfigSource_SubscribesImmediately() { var rcmManager = new MockRcmSubscriptionManager(); var settings = CreateSettings((ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSource, "remote_config")); + // Every tracer subscribes at startup when this source is selected, so the shared parametric + // suite asserts an apply status without evaluating a flag first. Deferring the subscription + // to Activate() would make .NET the only tracer that never advertises the capability until + // the application resolves a flag. using var module = CreateModule(settings, rcmManager); - // Subscription is deferred to Activate() so merely enabling Feature Flags does not start - // a billed RC subscription. - rcmManager.HasAnySubscription.Should().BeFalse(); - - module.Activate(); - rcmManager.HasAnySubscription.Should().BeTrue(); rcmManager.ProductKeys.Should().Contain(RcmProducts.FfeFlags); } @@ -229,13 +229,13 @@ public async Task InitializeAsync_WhenRemoteConfigurationIsUnavailable_FailsWith } [Fact] - public void Activate_WhenCalledConcurrently_SubscribesOnce() + public void Activate_WhenCalledConcurrently_LeavesTheSingleStartupSubscription() { var rcmManager = new MockRcmSubscriptionManager(); using var module = CreateModule(CreateSettings(), rcmManager); - // Activation claims its flag and completes its setup atomically, so a second caller cannot - // subscribe a second time, nor observe the module as activated while setup is still running. + // Create() subscribed once. Activation claims its flag atomically, so no caller can add a + // second subscription, nor observe the module as activated while setup is still running. const int callers = 16; using var start = new Barrier(callers); Parallel.For( @@ -251,7 +251,7 @@ public void Activate_WhenCalledConcurrently_SubscribesOnce() } [Fact] - public void Activate_AfterDispose_DoesNotSubscribe() + public void Activate_AfterDispose_DoesNotSubscribeAgain() { var rcmManager = new MockRcmSubscriptionManager(); var module = CreateModule(CreateSettings(), rcmManager); @@ -260,9 +260,10 @@ public void Activate_AfterDispose_DoesNotSubscribe() module.Activate(); // Disposal has already run its unsubscribe, so a subscription registered afterwards would - // never be removed, leaving a billed delivery path active for the rest of the process. + // never be removed, leaving a delivery path active for the rest of the process. Only the one + // subscription Create() made is expected, and it is gone. rcmManager.HasAnySubscription.Should().BeFalse(); - rcmManager.ProductKeys.Should().BeEmpty(); + rcmManager.ProductKeys.Should().ContainSingle().Which.Should().Be(RcmProducts.FfeFlags); } [Fact] @@ -271,7 +272,6 @@ public void Dispose_AfterSubscribing_Unsubscribes() var rcmManager = new MockRcmSubscriptionManager(); var module = CreateModule(CreateSettings(), rcmManager); - module.Activate(); rcmManager.HasAnySubscription.Should().BeTrue(); module.Dispose(); From d868f5ace16f2899cb9764e689dc7a6e33dfa6a2 Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 26 Aug 2026 15:53:54 +0300 Subject: [PATCH 37/86] [FeatureFlags] Align the provider initialization timeout default with the other tracers --- .../Configuration/supported-configurations.yaml | 6 +++--- .../src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs | 4 +++- .../ConfigurationKeys.FeatureFlags.g.cs | 2 +- .../FeatureFlags/FeatureFlagsSettingsTests.cs | 6 +++--- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/tracer/src/Datadog.Trace/Configuration/supported-configurations.yaml b/tracer/src/Datadog.Trace/Configuration/supported-configurations.yaml index 3523c5a3c676..7347d243d4d2 100644 --- a/tracer/src/Datadog.Trace/Configuration/supported-configurations.yaml +++ b/tracer/src/Datadog.Trace/Configuration/supported-configurations.yaml @@ -3158,16 +3158,16 @@ supportedConfigurations: Enables Feature Flags Provider (Experimental). Default value is false (disabled). DD_EXPERIMENTAL_FLAGGING_PROVIDER_INITIALIZATION_TIMEOUT_MS: - - implementation: B + - implementation: A scope: managed type: int - default: '10000' + default: '30000' product: FeatureFlags const_name: FlaggingProviderInitializationTimeoutMs documentation: |- Configuration key for how long, in milliseconds, provider initialization waits for the first flag configuration to arrive before returning. - Default value is 10000 (10 seconds). + Default value is 30000 (30 seconds), matching the other tracers. Initialization does not fail when the timeout expires: the provider stays not-ready, evaluations return the caller's default value, and the provider becomes ready when configuration arrives. DD_FEATURE_FLAGS_ENABLED: diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs index 426bd6780484..654148504d05 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs @@ -28,7 +28,9 @@ internal sealed class FeatureFlagsSettings internal const int DefaultPollIntervalSeconds = 30; internal const int DefaultRequestTimeoutSeconds = 5; - internal const int DefaultInitializationTimeoutMs = 10_000; + // Matches the Go, Java and Node tracers, so the same slow first configuration does not give + // one language the caller's default value while the others still return a real one. + internal const int DefaultInitializationTimeoutMs = 30_000; // An interval above this is indistinguishable from "never poll" and is more likely a // misconfiguration (for example milliseconds passed as seconds) than an intent. diff --git a/tracer/src/Datadog.Trace/Generated/net6.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs b/tracer/src/Datadog.Trace/Generated/net6.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs index 6d3efb137e4e..fc6c32d2b92b 100644 --- a/tracer/src/Datadog.Trace/Generated/net6.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs +++ b/tracer/src/Datadog.Trace/Generated/net6.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs @@ -26,7 +26,7 @@ internal static class FeatureFlags /// /// Configuration key for how long, in milliseconds, provider initialization waits for the first /// flag configuration to arrive before returning. - /// Default value is 10000 (10 seconds). + /// Default value is 30000 (30 seconds), matching the other tracers. /// Initialization does not fail when the timeout expires: the provider stays not-ready, evaluations /// return the caller's default value, and the provider becomes ready when configuration arrives. /// diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs index 3dafd5457de1..e9548b61c6a3 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs @@ -81,7 +81,7 @@ public void UsesDocumentedDefaults() settings.PollInterval.Should().Be(TimeSpan.FromSeconds(30)); settings.RequestTimeout.Should().Be(TimeSpan.FromSeconds(5)); - settings.InitializationTimeout.Should().Be(TimeSpan.FromMilliseconds(10_000)); + settings.InitializationTimeout.Should().Be(TimeSpan.FromMilliseconds(30_000)); settings.AgentlessBaseUrl.Should().BeNull(); } @@ -122,8 +122,8 @@ public void ReadsRequestTimeout(string configured, int expectedSeconds) [Theory] [InlineData("1000", 1000)] - [InlineData("0", 10_000)] - [InlineData("-1", 10_000)] + [InlineData("0", 30_000)] + [InlineData("-1", 30_000)] public void ReadsInitializationTimeout(string configured, int expectedMs) { var settings = CreateSettings( From b2f012a9f7a3bdcc5c7a18824ba000cb89f66da1 Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 26 Aug 2026 15:56:28 +0300 Subject: [PATCH 38/86] Fix comments --- .../ConfigurationKeys.FeatureFlags.g.cs | 2 +- .../ConfigurationKeys.FeatureFlags.g.cs | 2 +- .../ConfigurationKeys.FeatureFlags.g.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tracer/src/Datadog.Trace/Generated/net461/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs b/tracer/src/Datadog.Trace/Generated/net461/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs index 6d3efb137e4e..fc6c32d2b92b 100644 --- a/tracer/src/Datadog.Trace/Generated/net461/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs +++ b/tracer/src/Datadog.Trace/Generated/net461/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs @@ -26,7 +26,7 @@ internal static class FeatureFlags /// /// Configuration key for how long, in milliseconds, provider initialization waits for the first /// flag configuration to arrive before returning. - /// Default value is 10000 (10 seconds). + /// Default value is 30000 (30 seconds), matching the other tracers. /// Initialization does not fail when the timeout expires: the provider stays not-ready, evaluations /// return the caller's default value, and the provider becomes ready when configuration arrives. /// diff --git a/tracer/src/Datadog.Trace/Generated/netcoreapp3.1/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs b/tracer/src/Datadog.Trace/Generated/netcoreapp3.1/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs index 6d3efb137e4e..fc6c32d2b92b 100644 --- a/tracer/src/Datadog.Trace/Generated/netcoreapp3.1/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs +++ b/tracer/src/Datadog.Trace/Generated/netcoreapp3.1/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs @@ -26,7 +26,7 @@ internal static class FeatureFlags /// /// Configuration key for how long, in milliseconds, provider initialization waits for the first /// flag configuration to arrive before returning. - /// Default value is 10000 (10 seconds). + /// Default value is 30000 (30 seconds), matching the other tracers. /// Initialization does not fail when the timeout expires: the provider stays not-ready, evaluations /// return the caller's default value, and the provider becomes ready when configuration arrives. /// diff --git a/tracer/src/Datadog.Trace/Generated/netstandard2.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs b/tracer/src/Datadog.Trace/Generated/netstandard2.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs index 6d3efb137e4e..fc6c32d2b92b 100644 --- a/tracer/src/Datadog.Trace/Generated/netstandard2.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs +++ b/tracer/src/Datadog.Trace/Generated/netstandard2.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs @@ -26,7 +26,7 @@ internal static class FeatureFlags /// /// Configuration key for how long, in milliseconds, provider initialization waits for the first /// flag configuration to arrive before returning. - /// Default value is 10000 (10 seconds). + /// Default value is 30000 (30 seconds), matching the other tracers. /// Initialization does not fail when the timeout expires: the provider stays not-ready, evaluations /// return the caller's default value, and the provider becomes ready when configuration arrives. /// From 5654f49e6fdab9206411dc0c68182f19f01ccf77 Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 26 Aug 2026 16:30:42 +0300 Subject: [PATCH 39/86] [FeatureFlags] Signal agentless poller shutdown with a TaskCompletionSource --- .../Agentless/AgentlessConfigurationSource.cs | 35 +++++++++---------- .../AgentlessConfigurationSourceTests.cs | 3 +- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs index a0bdd1279537..7058d0d01ed4 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs @@ -47,8 +47,11 @@ internal sealed class AgentlessConfigurationSource : IDisposable private readonly TimeSpan _pollInterval; private readonly TimeSpan _requestTimeout; private readonly Func _applyConfiguration; - private readonly Func _waitAsync; - private readonly CancellationTokenSource _shutdown = new(); + private readonly Func _waitAsync; + + // Not a CancellationTokenSource: cancellation throws, and an exception on the shutdown path can + // crash the runtime, so shutdown is signalled by completing a task instead. + private readonly TaskCompletionSource _shutdown = new(TaskCreationOptions.RunContinuationsAsynchronously); private readonly Random _random = new(); // Only ever touched from the poll loop. @@ -73,7 +76,7 @@ internal AgentlessConfigurationSource( TimeSpan requestTimeout, Func applyConfiguration, string? environment = null, - Func? waitAsync = null) + Func? waitAsync = null) { _endpoint = endpoint; _requestFactory = requestFactory; @@ -161,7 +164,7 @@ internal async Task PollAsync() { result = await RequestAsync().ConfigureAwait(false); - if (_shutdown.IsCancellationRequested) + if (_shutdown.Task.IsCompleted) { // A shutdown mid-poll leaves the response unusable for state transitions: keep // last-known-good and the current ETag. @@ -182,13 +185,13 @@ internal async Task PollAsync() await WaitAsync(RetryDelay(attempt)).ConfigureAwait(false); - if (_shutdown.IsCancellationRequested) + if (_shutdown.Task.IsCompleted) { return; } } - if (_shutdown.IsCancellationRequested) + if (_shutdown.Task.IsCompleted) { // A shutdown during the final attempt leaves the response unusable for state // transitions: keep last-known-good and the current ETag. @@ -203,14 +206,15 @@ public void Dispose() // The request in flight is bounded by the request timeout, and the loop is never joined, // so a shutdown does not wait for it. A poll that completes after disposal is prevented // from applying its result by the shutdown check in PollAsync. + _shutdown.TrySetResult(true); + try { _environmentSubscription?.Dispose(); - _shutdown.Cancel(); } catch (Exception ex) { - Log.Debug(ex, "Error cancelling the Feature Flags agentless poll loop"); + Log.Debug(ex, "Error unsubscribing the Feature Flags agentless poll loop from settings changes"); } } @@ -257,7 +261,7 @@ private async Task RunAsync() { Log.Debug("AgentlessConfigurationSource::RunAsync -> Enter"); - while (!_shutdown.IsCancellationRequested) + while (!_shutdown.Task.IsCompleted) { try { @@ -275,17 +279,10 @@ private async Task RunAsync() Log.Debug("AgentlessConfigurationSource::RunAsync -> Exit"); } + // A shutdown ends the wait early. The delay itself is left to expire on its own: it holds no + // thread, and the loop has already exited by the time it does. private async Task WaitAsync(TimeSpan delay) - { - try - { - await _waitAsync(delay, _shutdown.Token).ConfigureAwait(false); - } - catch (OperationCanceledException) - { - // Shutting down - } - } + => await Task.WhenAny(_waitAsync(delay), _shutdown.Task).ConfigureAwait(false); private TimeSpan RetryDelay(int attempt) { diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs index a807554c0cc7..276f28b37251 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs @@ -11,7 +11,6 @@ using System.IO.Compression; using System.Linq; using System.Text; -using System.Threading; using System.Threading.Tasks; using Datadog.Trace.Agent; using Datadog.Trace.FeatureFlags.Agentless; @@ -265,7 +264,7 @@ private static AgentlessEndpoint CreateEndpoint() return endpoint ?? throw new InvalidOperationException("TryCreate reported success without producing an endpoint."); } - private static Task NoWait(TimeSpan delay, CancellationToken cancellationToken) => Task.CompletedTask; + private static Task NoWait(TimeSpan delay) => Task.CompletedTask; private class ThrowingApiRequest(Uri endpoint) : TestApiRequest(endpoint) { From 0eadda95b7c2c683e81871690ebae03f55479048 Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 26 Aug 2026 16:39:32 +0300 Subject: [PATCH 40/86] [FeatureFlags] Use ThreadSafeRandom.Shared for agentless retry jitter --- .../FeatureFlags/Agentless/AgentlessConfigurationSource.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs index 7058d0d01ed4..b2e5f47bd662 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs @@ -52,7 +52,6 @@ internal sealed class AgentlessConfigurationSource : IDisposable // Not a CancellationTokenSource: cancellation throws, and an exception on the shutdown path can // crash the runtime, so shutdown is signalled by completing a task instead. private readonly TaskCompletionSource _shutdown = new(TaskCreationOptions.RunContinuationsAsynchronously); - private readonly Random _random = new(); // Only ever touched from the poll loop. private readonly HashSet _loggedFailureCategories = new(); @@ -290,11 +289,7 @@ private TimeSpan RetryDelay(int attempt) ? Clamp(_pollInterval.TotalSeconds / 6, FirstRetryMin, FirstRetryMax) : Clamp(_pollInterval.TotalSeconds / 3, SecondRetryMin, SecondRetryMax); - double jitter; - lock (_random) - { - jitter = 1 - RetryJitter + (_random.NextDouble() * RetryJitter * 2); - } + var jitter = 1 - RetryJitter + (ThreadSafeRandom.Shared.NextDouble() * RetryJitter * 2); return TimeSpan.FromSeconds(Math.Max(MinRetryDelay.TotalSeconds, seconds * jitter)); From e2a6f9a6a9fd69f2e1717e142039d5972c219910 Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 26 Aug 2026 16:42:08 +0300 Subject: [PATCH 41/86] [FeatureFlags] Log agentless delivery failures as warnings --- .../FeatureFlags/Agentless/AgentlessConfigurationSource.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs index b2e5f47bd662..bcd0d5dafddf 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs @@ -442,13 +442,13 @@ private void WarnFailure(in PollResult result, int attempts) switch (result.StatusCode) { case 401 or 403: - Log.Error("Feature Flags agentless endpoint returned HTTP {StatusCode}; verify endpoint authentication", result.StatusCode!.Value); + Log.Warning("Feature Flags agentless endpoint returned HTTP {StatusCode}; verify endpoint authentication", result.StatusCode!.Value); break; case not null: - Log.Error("Feature Flags agentless endpoint returned HTTP {StatusCode} after {Attempts} attempts", result.StatusCode.Value, attempts); + Log.Warning("Feature Flags agentless endpoint returned HTTP {StatusCode} after {Attempts} attempts", result.StatusCode.Value, attempts); break; default: - Log.Error(result.Error, "Feature Flags agentless request failed after {Attempts} attempts", attempts); + Log.Warning(result.Error, "Feature Flags agentless request failed after {Attempts} attempts", attempts); break; } } From 4f892ab9286cd70ed89f66b1979d43b82abc23e5 Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 26 Aug 2026 16:48:41 +0300 Subject: [PATCH 42/86] [FeatureFlags] Fix stream disposal when reading the agentless response body --- .../Agentless/AgentlessConfigurationSource.cs | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs index bcd0d5dafddf..68e358202fa5 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs @@ -356,23 +356,23 @@ private async Task RequestAsync() private async Task ReadBodyAsync(IApiResponse response) { - var stream = await response.GetStreamAsync().ConfigureAwait(false); - GZipStream? decompressed = null; - - try - { - if (response.GetContentEncodingType() == ContentEncodingType.GZip) - { - decompressed = new GZipStream(stream, CompressionMode.Decompress); - } - - using var reader = new StreamReader(decompressed ?? stream, response.GetCharsetEncoding()); - return await reader.ReadToEndAsync().ConfigureAwait(false); - } - finally - { - decompressed?.Dispose(); - } + using var stream = await response.GetStreamAsync().ConfigureAwait(false); + + using var decompressed = + response.GetContentEncodingType() == ContentEncodingType.GZip + ? new GZipStream(stream, CompressionMode.Decompress, leaveOpen: true) + : null; + + // Every parameter has to be given to reach leaveOpen. A byte order mark is not expected, and + // letting one be detected would override the encoding the response declared. + using var reader = new StreamReader( + decompressed ?? stream, + response.GetCharsetEncoding(), + detectEncodingFromByteOrderMarks: false, + bufferSize: 1024, // the default + leaveOpen: true); + + return await reader.ReadToEndAsync().ConfigureAwait(false); } private Task ApplyAsync(PollResult result) From a522bfb49d5880c388297395c9b499abf0daf557 Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 26 Aug 2026 16:52:31 +0300 Subject: [PATCH 43/86] [FeatureFlags] Make the agentless apply step synchronous and pass PollResult by in --- .../Agentless/AgentlessConfigurationSource.cs | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs index 68e358202fa5..1cffba761f54 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs @@ -170,7 +170,7 @@ internal async Task PollAsync() return; } - if (!IsRetryable(result)) + if (!IsRetryable(in result)) { break; } @@ -178,7 +178,7 @@ internal async Task PollAsync() if (attempt == MaxAttempts) { // Every attempt failed in a retryable way. Last-known-good stays in place. - WarnFailure(result, MaxAttempts); + WarnFailure(in result, MaxAttempts); return; } @@ -197,7 +197,7 @@ internal async Task PollAsync() return; } - await ApplyAsync(result).ConfigureAwait(false); + Apply(in result); } public void Dispose() @@ -375,19 +375,19 @@ private async Task ReadBodyAsync(IApiResponse response) return await reader.ReadToEndAsync().ConfigureAwait(false); } - private Task ApplyAsync(PollResult result) + private void Apply(in PollResult result) { switch (result.StatusCode) { case 304: // Nothing changed, and the ETag stays as it is. - return Task.CompletedTask; + return; case 401 or 403: - WarnFailure(result, attempts: 1); - return Task.CompletedTask; + WarnFailure(in result, attempts: 1); + return; case not 200: - WarnFailure(result, attempts: 1); - return Task.CompletedTask; + WarnFailure(in result, attempts: 1); + return; } if (!UfcConfigurationParser.TryParse(result.Body, out var configuration, out var error)) @@ -398,7 +398,7 @@ private Task ApplyAsync(PollResult result) Log.Error("Feature Flags agentless endpoint returned an unusable payload: {Error}", error); } - return Task.CompletedTask; + return; } if (!_applyConfiguration(configuration)) @@ -409,7 +409,7 @@ private Task ApplyAsync(PollResult result) Log.Warning("Feature Flags agentless configuration could not be applied"); } - return Task.CompletedTask; + return; } // The ETag advances only once parsing and applying have both succeeded. Advancing on @@ -417,8 +417,6 @@ private Task ApplyAsync(PollResult result) // answer 304, pinning the process to stale configuration with no way back. var newEtag = result.ETag?.Trim(); _etag = StringUtil.IsNullOrEmpty(newEtag) ? null : newEtag; - - return Task.CompletedTask; } /// From ffcfc15e2c89da28c4a3d9a6b72a62228be6acff Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 26 Aug 2026 16:53:54 +0300 Subject: [PATCH 44/86] [FeatureFlags] Start the agentless poll loop with Task.Run --- .../FeatureFlags/Agentless/AgentlessConfigurationSource.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs index 1cffba761f54..cf3b18ee6040 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs @@ -146,10 +146,9 @@ public void Start() return; } - // Deliberately not wrapped in Task.Run: this is called from provider initialization, which - // is waiting for the first configuration, so the first request should go out on the calling - // thread rather than queue behind whatever else is on the thread pool. - _ = RunAsync().ContinueWith(t => Log.Error(t.Exception, "Feature Flags agentless poll loop failed"), TaskContinuationOptions.OnlyOnFaulted); + // The loop runs on the thread pool, so nothing of it happens on the caller's thread. Nothing + // ever awaits it either, so a fault is observed here or not at all. + _ = Task.Run(RunAsync).ContinueWith(t => Log.Error(t.Exception, "Feature Flags agentless poll loop failed"), TaskContinuationOptions.OnlyOnFaulted); } /// From da215dbfb715d922bc94f0fba943ac2c9b500fef Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 26 Aug 2026 17:01:55 +0300 Subject: [PATCH 45/86] [FeatureFlags] Rebuild the agentless request URI only when the environment changes --- .../Agentless/AgentlessConfigurationSource.cs | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs index cf3b18ee6040..f8c0ced5886b 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs @@ -56,8 +56,9 @@ internal sealed class AgentlessConfigurationSource : IDisposable // Only ever touched from the poll loop. private readonly HashSet _loggedFailureCategories = new(); - // Written by the settings-change callback, read by the poll loop. - private string? _environment; + // Written by the settings-change callback, read by the poll loop. The URI is stored rather than + // the environment it carries, so it is only built when the environment changes. + private Uri _requestUri; private IDisposable? _environmentSubscription; // Only ever touched from the poll loop. @@ -82,7 +83,7 @@ internal AgentlessConfigurationSource( _pollInterval = pollInterval; _requestTimeout = requestTimeout; _applyConfiguration = applyConfiguration; - _environment = environment; + _requestUri = endpoint.BuildRequestUri(environment); _waitAsync = waitAsync ?? Task.Delay; } @@ -117,8 +118,8 @@ internal AgentlessConfigurationSource( manager.InitialMutableSettings.Environment); // The environment is tracked rather than captured: customers can change it in code while - // the application runs, and flags are targeted per environment. Only the value is stored - // here, so that the poll loop stays the only thing that touches the request state. + // the application runs, and flags are targeted per environment. Only the request URI is + // stored here, so that the poll loop stays the only thing that touches the request state. source._environmentSubscription = manager.SubscribeToChanges(changes => { if (changes.UpdatedMutable is { } mutable) @@ -131,10 +132,11 @@ internal AgentlessConfigurationSource( } /// - /// Records the environment to request configuration for. Applied by the poll loop on its next - /// request, so a change never disturbs a request already in flight. + /// Records the environment to request configuration for, as the URI that carries it. Picked up + /// by the poll loop on its next request, so a change never disturbs a request already in flight. /// - internal void UpdateEnvironment(string? environment) => Volatile.Write(ref _environment, environment); + internal void UpdateEnvironment(string? environment) + => Volatile.Write(ref _requestUri, _endpoint.BuildRequestUri(environment)); /// /// Starts polling. Idempotent. @@ -300,9 +302,9 @@ private async Task RequestAsync() { try { - // The environment is applied per request rather than baked into the endpoint, because - // it can be changed in code after startup. - var uri = _endpoint.BuildRequestUri(Volatile.Read(ref _environment)); + // Read per request rather than captured, because the environment it carries can be + // changed in code after startup. + var uri = Volatile.Read(ref _requestUri); // An ETag only identifies the configuration served for the URI it came from. Sending it // against a different environment would earn a 304 and pin the process to the previous From 0ad52cacd408ca646779477659b25b494954c2cd Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 26 Aug 2026 17:13:44 +0300 Subject: [PATCH 46/86] [FeatureFlags] Parse the agentless payload straight from the response stream --- .../Agentless/AgentlessConfigurationSource.cs | 69 +++++++++++-------- .../Agentless/UfcConfigurationParser.cs | 11 ++- .../UfcConfigurationParserTests.cs | 18 +++-- 3 files changed, 57 insertions(+), 41 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs index f8c0ced5886b..058d06e9d98f 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs @@ -339,43 +339,50 @@ private async Task RequestAsync() t => { try { using var r = t.Result; } catch { } }, TaskContinuationOptions.None); - return new PollResult(statusCode: null, etag: null, body: null, error: new TimeoutException($"Feature Flags agentless request timed out after {_requestTimeout.TotalSeconds}s")); + return new PollResult(statusCode: null, etag: null, configuration: null, parseError: null, error: new TimeoutException($"Feature Flags agentless request timed out after {_requestTimeout.TotalSeconds}s")); } using var response = await getTask.ConfigureAwait(false); #endif - // Only a 200 carries configuration; other bodies are never decoded as one. - var body = response.StatusCode == 200 ? await ReadBodyAsync(response).ConfigureAwait(false) : null; - return new PollResult(response.StatusCode, response.GetHeader("ETag"), body, error: null); + // Only a 200 carries configuration; other bodies are never decoded as one. The payload + // is parsed here, while the response is still open, so it never has to be held as a + // string. A payload that does not parse is reported, not thrown: it is not retryable. + ServerConfiguration? configuration = null; + string? parseError = null; + + if (response.StatusCode == 200) + { + using var stream = await response.GetStreamAsync().ConfigureAwait(false); + + using var decompressed = + response.GetContentEncodingType() == ContentEncodingType.GZip + ? new GZipStream(stream, CompressionMode.Decompress, leaveOpen: true) + : null; + + // Every parameter has to be given to reach leaveOpen. A byte order mark is not + // expected, and letting one be detected would override the declared encoding. + using var reader = new StreamReader( + decompressed ?? stream, + response.GetCharsetEncoding(), + detectEncodingFromByteOrderMarks: false, + bufferSize: 1024, // the default + leaveOpen: true); + + if (UfcConfigurationParser.TryParse(reader, out var parsed, out parseError)) + { + configuration = parsed; + } + } + + return new PollResult(response.StatusCode, response.GetHeader("ETag"), configuration, parseError, error: null); } catch (Exception ex) { - return new PollResult(statusCode: null, etag: null, body: null, error: ex); + return new PollResult(statusCode: null, etag: null, configuration: null, parseError: null, error: ex); } } - private async Task ReadBodyAsync(IApiResponse response) - { - using var stream = await response.GetStreamAsync().ConfigureAwait(false); - - using var decompressed = - response.GetContentEncodingType() == ContentEncodingType.GZip - ? new GZipStream(stream, CompressionMode.Decompress, leaveOpen: true) - : null; - - // Every parameter has to be given to reach leaveOpen. A byte order mark is not expected, and - // letting one be detected would override the encoding the response declared. - using var reader = new StreamReader( - decompressed ?? stream, - response.GetCharsetEncoding(), - detectEncodingFromByteOrderMarks: false, - bufferSize: 1024, // the default - leaveOpen: true); - - return await reader.ReadToEndAsync().ConfigureAwait(false); - } - private void Apply(in PollResult result) { switch (result.StatusCode) @@ -391,12 +398,12 @@ private void Apply(in PollResult result) return; } - if (!UfcConfigurationParser.TryParse(result.Body, out var configuration, out var error)) + if (result.Configuration is not { } configuration) { if (!_malformedPayloadLogged) { _malformedPayloadLogged = true; - Log.Error("Feature Flags agentless endpoint returned an unusable payload: {Error}", error); + Log.Error("Feature Flags agentless endpoint returned an unusable payload: {Error}", result.ParseError); } return; @@ -452,13 +459,15 @@ private void WarnFailure(in PollResult result, int attempts) } } - internal readonly struct PollResult(int? statusCode, string? etag, string? body, Exception? error) + internal readonly struct PollResult(int? statusCode, string? etag, ServerConfiguration? configuration, string? parseError, Exception? error) { public int? StatusCode { get; } = statusCode; public string? ETag { get; } = etag; - public string? Body { get; } = body; + public ServerConfiguration? Configuration { get; } = configuration; + + public string? ParseError { get; } = parseError; public Exception? Error { get; } = error; } diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs index a078f5f4374d..50e1fd6fa565 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs @@ -26,11 +26,11 @@ internal static class UfcConfigurationParser /// which is the document the evaluator consumes. A raw UFC document is rejected, including from /// a custom endpoint, so that every source agrees on one wire format. /// - /// The response body. + /// The response body. Read straight from the response, so it never has to be held as a string. /// The parsed configuration. /// Why the payload was rejected. /// true when the payload matches the contract. - public static bool TryParse(string? body, [NotNullWhen(true)] out ServerConfiguration? configuration, out string? error) + public static bool TryParse(TextReader body, [NotNullWhen(true)] out ServerConfiguration? configuration, out string? error) { configuration = null; error = null; @@ -38,11 +38,10 @@ public static bool TryParse(string? body, [NotNullWhen(true)] out ServerConfigur JToken payload; try { - using var stringReader = new StringReader(body ?? string.Empty); - // Timestamps stay strings: the model carries createdAt verbatim, and letting Newtonsoft - // turn it into a date would also make the type check below fail. - using var jsonReader = new JsonTextReader(stringReader) { DateParseHandling = DateParseHandling.None }; + // turn it into a date would also make the type check below fail. The reader belongs to + // the caller, which owns the response it came from. + using var jsonReader = new JsonTextReader(body) { DateParseHandling = DateParseHandling.None, CloseInput = false }; payload = JToken.ReadFrom(jsonReader); } catch (Exception) diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/UfcConfigurationParserTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/UfcConfigurationParserTests.cs index b57c9568ebcd..cfdf5f85adf9 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/UfcConfigurationParserTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/UfcConfigurationParserTests.cs @@ -6,6 +6,7 @@ #nullable enable using System.Collections.Generic; +using System.IO; using Datadog.Trace.FeatureFlags.Agentless; using Datadog.Trace.FeatureFlags.Rcm.Model; using FluentAssertions; @@ -29,7 +30,7 @@ public class UfcConfigurationParserTests [Fact] public void ParsesValidEnvelope() { - UfcConfigurationParser.TryParse(ValidEnvelope, out var configuration, out var error) + Parse(ValidEnvelope, out var configuration, out var error) .Should().BeTrue(); error.Should().BeNull(); @@ -45,7 +46,7 @@ public void ParsesValidEnvelope() [InlineData("{ \"data\": ")] public void RejectsMalformedJson(string? body) { - UfcConfigurationParser.TryParse(body, out var configuration, out var error).Should().BeFalse(); + Parse(body, out var configuration, out var error).Should().BeFalse(); configuration.Should().BeNull(); error.Should().Be("Malformed UFC payload"); @@ -66,7 +67,7 @@ public void RejectsMalformedJson(string? body) [InlineData("""{ "data": { "type": [1, 2], "attributes": { "format": "SERVER", "createdAt": "x", "environment": { "name": "prod" }, "flags": {} } } }""")] public void RejectsInvalidEnvelope(string body) { - UfcConfigurationParser.TryParse(body, out var configuration, out var error).Should().BeFalse(); + Parse(body, out var configuration, out var error).Should().BeFalse(); configuration.Should().BeNull(); error.Should().Be("Expected a JSON:API Universal Flag Configuration resource"); @@ -87,7 +88,7 @@ public void RejectsInvalidEnvelope(string body) [InlineData("""{ "data": { "type": "universal-flag-configuration", "attributes": { "format": "SERVER", "createdAt": "x", "environment": { "name": "prod" }, "flags": [] } } }""")] public void RejectsInvalidAttributes(string body) { - UfcConfigurationParser.TryParse(body, out var configuration, out var error).Should().BeFalse(); + Parse(body, out var configuration, out var error).Should().BeFalse(); configuration.Should().BeNull(); error.Should().Be("Expected a Universal Flag Configuration v1 object"); @@ -103,10 +104,17 @@ public void ParsesFlagsFromEnvelope() "flags": { "test-flag": { "key": "test-flag", "enabled": true, "variationType": "BOOLEAN" } } } } } """; - UfcConfigurationParser.TryParse(body, out var configuration, out _).Should().BeTrue(); + Parse(body, out var configuration, out _).Should().BeTrue(); configuration!.Flags.Should().NotBeNull(); configuration!.Flags!.Should().ContainKey("test-flag"); configuration!.Flags!["test-flag"].Enabled.Should().BeTrue(); } + + // The parser reads the response stream directly, so a body under test is handed to it as a reader. + private static bool Parse(string? body, out ServerConfiguration? configuration, out string? error) + { + using var reader = new StringReader(body ?? string.Empty); + return UfcConfigurationParser.TryParse(reader, out configuration, out error); + } } From e9936a2667e7b527ea706e7f86586eb347eaedfc Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 26 Aug 2026 17:27:24 +0300 Subject: [PATCH 47/86] [FeatureFlags] Deserialize the UFC envelope without building a JSON tree --- .../Agentless/UfcConfigurationParser.cs | 149 ++++++++++++++---- .../Rcm/Model/FlagCollectionJsonConverter.cs | 9 ++ .../UfcConfigurationParserTests.cs | 16 +- 3 files changed, 140 insertions(+), 34 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs index 50e1fd6fa565..b03f17141196 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs @@ -10,7 +10,6 @@ using System.IO; using Datadog.Trace.FeatureFlags.Rcm.Model; using Datadog.Trace.Vendors.Newtonsoft.Json; -using Datadog.Trace.Vendors.Newtonsoft.Json.Linq; namespace Datadog.Trace.FeatureFlags.Agentless; @@ -21,10 +20,19 @@ internal static class UfcConfigurationParser { private const string ResourceType = "universal-flag-configuration"; + private const string MalformedError = "Malformed UFC payload"; + private const string ResourceError = "Expected a JSON:API Universal Flag Configuration resource"; + private const string AttributesError = "Expected a Universal Flag Configuration v1 object"; + /// /// Validates a JSON:API Universal Flag Configuration response and returns data.attributes, /// which is the document the evaluator consumes. A raw UFC document is rejected, including from /// a custom endpoint, so that every source agrees on one wire format. + /// + /// The envelope is walked with the reader rather than loaded into a JSON tree, and + /// data.attributes is deserialized in place, so the payload is read exactly once and no + /// copy of it is ever held. + /// /// /// The response body. Read straight from the response, so it never has to be held as a string. /// The parsed configuration. @@ -35,56 +43,133 @@ public static bool TryParse(TextReader body, [NotNullWhen(true)] out ServerConfi configuration = null; error = null; - JToken payload; + var sawData = false; + string? resourceType = null; + ServerConfiguration? attributes = null; + try { // Timestamps stay strings: the model carries createdAt verbatim, and letting Newtonsoft // turn it into a date would also make the type check below fail. The reader belongs to // the caller, which owns the response it came from. - using var jsonReader = new JsonTextReader(body) { DateParseHandling = DateParseHandling.None, CloseInput = false }; - payload = JToken.ReadFrom(jsonReader); + using var reader = new JsonTextReader(body) { DateParseHandling = DateParseHandling.None, CloseInput = false }; + var serializer = new JsonSerializer { DateParseHandling = DateParseHandling.None }; + + if (!reader.Read()) + { + // Nothing at all, so there is no document to judge against the contract. + error = MalformedError; + return false; + } + + if (reader.TokenType != JsonToken.StartObject) + { + error = ResourceError; + return false; + } + + while (reader.Read() && reader.TokenType == JsonToken.PropertyName) + { + if ((string?)reader.Value != "data") + { + reader.Skip(); + continue; + } + + sawData = true; + + if (!reader.Read()) + { + // The document ended where the resource should have been. + error = MalformedError; + return false; + } + + if (reader.TokenType != JsonToken.StartObject) + { + error = ResourceError; + return false; + } + + while (reader.Read() && reader.TokenType == JsonToken.PropertyName) + { + switch ((string?)reader.Value) + { + case "type": + if (!reader.Read()) + { + error = MalformedError; + return false; + } + + // A type that is not a string cannot identify the resource. Checked on + // the token, because a number would otherwise be read as its digits. + if (reader.TokenType != JsonToken.String) + { + error = ResourceError; + return false; + } + + resourceType = (string?)reader.Value; + break; + + case "attributes": + if (!reader.Read()) + { + error = MalformedError; + return false; + } + + if (reader.TokenType != JsonToken.StartObject) + { + error = AttributesError; + return false; + } + + attributes = serializer.Deserialize(reader); + break; + + default: + reader.Skip(); + break; + } + } + } + + // A document that ends before the root object closes was truncated in transit, whatever + // was found in it up to that point. + if (reader.TokenType != JsonToken.EndObject) + { + error = MalformedError; + return false; + } } catch (Exception) { - error = "Malformed UFC payload"; + error = MalformedError; return false; } - if (payload is not JObject - || payload["data"] is not JObject data - || data["type"]?.Type != JTokenType.String - || data["type"]?.Value() != ResourceType) + if (!sawData || resourceType != ResourceType) { - error = "Expected a JSON:API Universal Flag Configuration resource"; + error = ResourceError; return false; } - if (data["attributes"] is not JObject attributes - || attributes["format"]?.Type != JTokenType.String - || attributes["createdAt"]?.Type != JTokenType.String - || attributes["environment"] is not JObject environment - || environment["name"]?.Type != JTokenType.String - || attributes["flags"] is not JObject) - { - error = "Expected a Universal Flag Configuration v1 object"; - return false; - } - - try - { - configuration = attributes.ToObject(); - } - catch (Exception) - { - configuration = null; - } - - if (configuration is null) + // Every member of the v1 contract has to be there. A member of the wrong shape arrives as + // null, because the flag collection rejects anything that is not an object and Newtonsoft + // leaves a member it cannot convert unset. + if (attributes is null + || attributes.Format is null + || attributes.CreatedAt is null + || attributes.Environment?.Name is null + || attributes.Flags is null) { - error = "Expected a Universal Flag Configuration v1 object"; + error = AttributesError; return false; } + configuration = attributes; return true; } } diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Rcm/Model/FlagCollectionJsonConverter.cs b/tracer/src/Datadog.Trace/FeatureFlags/Rcm/Model/FlagCollectionJsonConverter.cs index 87a4a8937986..101818093e56 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Rcm/Model/FlagCollectionJsonConverter.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Rcm/Model/FlagCollectionJsonConverter.cs @@ -25,6 +25,15 @@ internal sealed class FlagCollectionJsonConverter : JsonConverter Date: Wed, 26 Aug 2026 17:31:53 +0300 Subject: [PATCH 48/86] [FeatureFlags] Subscribe to settings changes in the agentless constructor --- .../Agentless/AgentlessConfigurationSource.cs | 40 ++++++++++--------- .../AgentlessConfigurationSourceTests.cs | 2 +- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs index 058d06e9d98f..35f966af1c4e 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs @@ -56,10 +56,11 @@ internal sealed class AgentlessConfigurationSource : IDisposable // Only ever touched from the poll loop. private readonly HashSet _loggedFailureCategories = new(); + private readonly IDisposable? _environmentSubscription; + // Written by the settings-change callback, read by the poll loop. The URI is stored rather than // the environment it carries, so it is only built when the environment changes. private Uri _requestUri; - private IDisposable? _environmentSubscription; // Only ever touched from the poll loop. private bool _malformedPayloadLogged; @@ -76,6 +77,7 @@ internal AgentlessConfigurationSource( TimeSpan requestTimeout, Func applyConfiguration, string? environment = null, + TracerSettings.SettingsManager? settingsManager = null, Func? waitAsync = null) { _endpoint = endpoint; @@ -85,6 +87,17 @@ internal AgentlessConfigurationSource( _applyConfiguration = applyConfiguration; _requestUri = endpoint.BuildRequestUri(environment); _waitAsync = waitAsync ?? Task.Delay; + + // Subscribed last, so every field the callback touches is already set. The environment is + // tracked rather than captured: customers can change it in code while the application runs, + // and flags are targeted per environment. + _environmentSubscription = settingsManager?.SubscribeToChanges(changes => + { + if (changes.UpdatedMutable is { } mutable) + { + UpdateEnvironment(mutable.Environment); + } + }); } /// @@ -109,26 +122,14 @@ internal AgentlessConfigurationSource( return null; } - var source = new AgentlessConfigurationSource( + return new AgentlessConfigurationSource( endpoint, CreateRequestFactory(endpoint, settings), settings.PollInterval, settings.RequestTimeout, applyConfiguration, - manager.InitialMutableSettings.Environment); - - // The environment is tracked rather than captured: customers can change it in code while - // the application runs, and flags are targeted per environment. Only the request URI is - // stored here, so that the poll loop stays the only thing that touches the request state. - source._environmentSubscription = manager.SubscribeToChanges(changes => - { - if (changes.UpdatedMutable is { } mutable) - { - source.UpdateEnvironment(mutable.Environment); - } - }); - - return source; + manager.InitialMutableSettings.Environment, + manager); } /// @@ -199,6 +200,10 @@ internal async Task PollAsync() } Apply(in result); + + // A failure with no status code never reached the endpoint, so it is worth another attempt. + static bool IsRetryable(in PollResult result) + => result.StatusCode is not { } status || status is 408 or 429 or (>= 500 and <= 599); } public void Dispose() @@ -254,9 +259,6 @@ private static ApiWebRequestFactory CreateRequestFactory(AgentlessEndpoint endpo #endif } - private static bool IsRetryable(in PollResult result) - => result.StatusCode is not { } status || status is 408 or 429 or (>= 500 and <= 599); - private async Task RunAsync() { Log.Debug("AgentlessConfigurationSource::RunAsync -> Enter"); diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs index 276f28b37251..b87daf911085 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs @@ -256,7 +256,7 @@ private static AgentlessConfigurationSource CreateSource( return true; }, environment, - NoWait); + waitAsync: NoWait); private static AgentlessEndpoint CreateEndpoint() { From 97fdde3202cb4193ebe1e1fda3f1a211671e284f Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 26 Aug 2026 18:00:02 +0300 Subject: [PATCH 49/86] [FeatureFlags] Add dd_env to the managed agentless endpoint only --- .../Agentless/AgentlessEndpoint.cs | 50 ++++--------------- .../FeatureFlags/AgentlessEndpointTests.cs | 29 +++-------- 2 files changed, 18 insertions(+), 61 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs index 11e258035245..a92e60db653f 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs @@ -31,19 +31,15 @@ internal sealed class AgentlessEndpoint internal const string ManagedHostPrefix = "ufc-server.ff-cdn."; /// - /// The query parameter carrying the environment to request configuration for. + /// The query parameter carrying the environment to request configuration for. Added to the + /// managed endpoint only. /// internal const string EnvParameterName = "dd_env"; - // Set when the configured base URL already carries dd_env. The operator chose that value - // deliberately, so it is left alone rather than duplicated or overwritten. - private readonly bool _pinsEnv; - - private AgentlessEndpoint(Uri uri, bool isManaged, bool pinsEnv) + private AgentlessEndpoint(Uri uri, bool isManaged) { Uri = uri; IsManaged = isManaged; - _pinsEnv = pinsEnv; } /// @@ -62,8 +58,8 @@ private AgentlessEndpoint(Uri uri, bool isManaged, bool pinsEnv) /// /// Builds the endpoint. Without a custom the managed Datadog CDN /// endpoint is derived from the (lowercased) site, so staging and government sites resolve - /// with no allowlist. A custom base URL that is an origin receives the canonical path; one that - /// carries a path is used verbatim. + /// with no allowlist, and is the only endpoint dd_env is added to. A custom base URL that + /// is an origin receives the canonical path; one that carries a path is used verbatim. /// /// The environment is not part of the endpoint: it can be changed in code while the application /// runs, so it is applied per request by instead. @@ -106,7 +102,7 @@ public static bool TryCreate(string? site, string? baseUrl, [NotNullWhen(true)] return false; } - endpoint = new AgentlessEndpoint(managedUri, isManaged: true, pinsEnv: false); + endpoint = new AgentlessEndpoint(managedUri, isManaged: true); return true; } @@ -138,7 +134,7 @@ public static bool TryCreate(string? site, string? baseUrl, [NotNullWhen(true)] custom = new UriBuilder(custom) { Path = DefaultPath }.Uri; } - endpoint = new AgentlessEndpoint(custom, isManaged: false, pinsEnv: HasEnvParameter(custom.Query)); + endpoint = new AgentlessEndpoint(custom, isManaged: false); return true; } @@ -147,15 +143,16 @@ public static bool TryCreate(string? site, string? baseUrl, [NotNullWhen(true)] /// added as a query parameter rather than baked into the endpoint, because it can change while /// the application runs. /// - /// Any query the configured base URL already carries is kept: it may hold credentials or routing - /// the operator needs. An endpoint that already pins dd_env is returned unchanged. + /// A configured base URL is opaque: it is requested exactly as the operator wrote it, since it + /// may hold credentials, routing, or a scope of its own. Only the managed endpoint carries + /// dd_env, which matches the other tracers. /// /// /// The current environment, or null when none is configured. /// The URI to request. public Uri BuildRequestUri(string? env) { - if (_pinsEnv) + if (!IsManaged) { return Uri; } @@ -180,29 +177,4 @@ public Uri BuildRequestUri(string? env) builder.Query = existing.Length > 1 ? existing.TrimStart('?') + "&" + parameter : parameter; return builder.Uri; } - - /// - /// Reports whether a query string already carries a dd_env parameter. Matching the name - /// alone would also hit a value such as ?next=dd_env, so the surrounding delimiters are - /// checked too. - /// - private static bool HasEnvParameter(string query) - { - var index = query.IndexOf(EnvParameterName, StringComparison.OrdinalIgnoreCase); - while (index >= 0) - { - var preceding = index == 0 ? '?' : query[index - 1]; - var followingIndex = index + EnvParameterName.Length; - var following = followingIndex < query.Length ? query[followingIndex] : '\0'; - - if (preceding is '?' or '&' && following is '=' or '&' or '\0') - { - return true; - } - - index = query.IndexOf(EnvParameterName, index + 1, StringComparison.OrdinalIgnoreCase); - } - - return false; - } } diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs index 2f53914f4b7c..00f67195754e 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs @@ -67,36 +67,21 @@ public void TruncatesAnOverlongDdEnvValue() => Create("datadoghq.com").BuildRequestUri(new string('a', 500)) .Query.Should().Be("?dd_env=" + new string('a', 200)); - [Fact] - public void KeepsTheQueryConfiguredOnACustomEndpoint() - { - // The query may carry credentials or routing the operator needs, so dd_env is appended to it - // rather than replacing it. - var endpoint = Create("datadoghq.com", baseUrl: "https://flags.example.com/ufc?token=abc"); - - endpoint.BuildRequestUri("production").Query.Should().Be("?token=abc&dd_env=production"); - } - [Theory] + // A configured base URL is opaque: the operator may have scoped it themselves, and it may carry + // credentials or routing, so it is requested exactly as written. Java, JS, Go and Python all + // treat a custom endpoint the same way. + [InlineData("https://flags.example.com/ufc")] + [InlineData("https://flags.example.com/ufc?token=abc")] [InlineData("https://flags.example.com/ufc?dd_env=staging")] [InlineData("https://flags.example.com/ufc?token=abc&dd_env=staging")] - public void LeavesACustomEndpointThatAlreadyPinsDdEnvAlone(string baseUrl) + public void DoesNotAddDdEnvToACustomEndpoint(string baseUrl) { - var endpoint = Create("datadoghq.com", baseUrl: baseUrl); + var endpoint = Create("datadoghq.com", baseUrl); endpoint.BuildRequestUri("production").Should().Be(endpoint.Uri); } - [Fact] - public void AddsDdEnvToACustomEndpointWithoutAQuery() - => Create("datadoghq.com", baseUrl: "https://flags.example.com/ufc") - .BuildRequestUri("production").Query.Should().Be("?dd_env=production"); - - [Fact] - public void DoesNotMistakeAQueryValueForAPinnedDdEnv() - => Create("datadoghq.com", baseUrl: "https://flags.example.com/ufc?next=dd_env") - .BuildRequestUri("production").Query.Should().Be("?next=dd_env&dd_env=production"); - [Theory] [InlineData("https://flags.example.com", "https://flags.example.com" + DefaultPath)] [InlineData("https://flags.example.com/", "https://flags.example.com" + DefaultPath)] From eba74ae8c3fd432ff5e830c0760ac655877d7b59 Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 26 Aug 2026 18:08:36 +0300 Subject: [PATCH 50/86] [FeatureFlags] Name the offline source after the value that selects it --- .../FeatureFlags/FeatureFlagsSettings.cs | 16 ++++++++-------- .../FeatureFlags/FeatureFlagsSource.cs | 6 ++++-- .../FeatureFlags/FeatureFlagsSettingsTests.cs | 16 ++++++++-------- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs index 654148504d05..193f3db804b5 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs @@ -32,8 +32,8 @@ internal sealed class FeatureFlagsSettings // one language the caller's default value while the others still return a real one. internal const int DefaultInitializationTimeoutMs = 30_000; - // An interval above this is indistinguishable from "never poll" and is more likely a - // misconfiguration (for example milliseconds passed as seconds) than an intent. + // One hour. An interval above this is more likely a misconfiguration (for example milliseconds + // passed as seconds) than an intent, and the other tracers cap it at the same value. private const int MaxPollIntervalSeconds = 3600; private static readonly IDatadogLogger Log = DatadogLogging.GetLoggerFor(typeof(FeatureFlagsSettings)); @@ -68,10 +68,10 @@ public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetr // adopters onto Remote Configuration, and everything else defaults to agentless. DefaultResult defaultSource = enabled switch { - false => new(FeatureFlagsSource.Disabled, OfflineSourceName), + false => new(FeatureFlagsSource.Offline, OfflineSourceName), null when legacyEnabled is not null => legacyEnabled.Value ? new(FeatureFlagsSource.RemoteConfig, RemoteConfigSourceName) - : new(FeatureFlagsSource.Disabled, OfflineSourceName), + : new(FeatureFlagsSource.Offline, OfflineSourceName), _ => new(FeatureFlagsSource.Agentless, AgentlessSourceName), }; @@ -114,14 +114,14 @@ public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetr } /// - /// Gets the resolved delivery source. means nothing is contacted. + /// Gets the resolved delivery source. means nothing is contacted. /// public FeatureFlagsSource Source { get; } /// /// Gets a value indicating whether Feature Flags are enabled at all. /// - public bool Enabled => Source != FeatureFlagsSource.Disabled; + public bool Enabled => Source != FeatureFlagsSource.Offline; /// /// Gets the configured override for the agentless endpoint, or null to derive it from the site. @@ -193,11 +193,11 @@ private static bool TryMatch(string value, out FeatureFlagsSource source) // "offline" is a reserved fail-closed sentinel: the provider is intentionally off. if (string.Equals(value, OfflineSourceName, StringComparison.OrdinalIgnoreCase)) { - source = FeatureFlagsSource.Disabled; + source = FeatureFlagsSource.Offline; return true; } - source = FeatureFlagsSource.Disabled; + source = FeatureFlagsSource.Offline; return false; } } diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSource.cs index dd50047ede42..558a28900adf 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSource.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSource.cs @@ -13,9 +13,11 @@ namespace Datadog.Trace.FeatureFlags; internal enum FeatureFlagsSource { /// - /// Feature Flags are disabled: no configuration is loaded, and neither delivery path is contacted. + /// Nothing is contacted and no configuration is loaded, so evaluations return the caller's + /// default value. Named after the offline value that selects it: it is a source rather + /// than an off switch, because it is reserved for serving configuration supplied at startup. /// - Disabled, + Offline, /// /// Configuration is fetched over HTTP, without the Datadog Agent. diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs index e9548b61c6a3..b83c204da4d9 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs @@ -23,10 +23,10 @@ public class FeatureFlagsSettingsTests // Nothing configured: agentless is the default. [InlineData(null, null, null, FeatureFlagsSource.Agentless)] // The stable kill switch wins over everything, including a legacy opt-in and an explicit source. - [InlineData("false", null, null, FeatureFlagsSource.Disabled)] - [InlineData("false", null, "true", FeatureFlagsSource.Disabled)] - [InlineData("false", "agentless", null, FeatureFlagsSource.Disabled)] - [InlineData("false", "remote_config", null, FeatureFlagsSource.Disabled)] + [InlineData("false", null, null, FeatureFlagsSource.Offline)] + [InlineData("false", null, "true", FeatureFlagsSource.Offline)] + [InlineData("false", "agentless", null, FeatureFlagsSource.Offline)] + [InlineData("false", "remote_config", null, FeatureFlagsSource.Offline)] // Enabling explicitly does not imply the historical Remote Configuration source. [InlineData("true", null, null, FeatureFlagsSource.Agentless)] // An explicit source wins over the legacy key, in both directions. @@ -34,7 +34,7 @@ public class FeatureFlagsSettingsTests [InlineData(null, "remote_config", "false", FeatureFlagsSource.RemoteConfig)] // The legacy key grandfathers existing adopters, who opted in when RC was the only source. [InlineData(null, null, "true", FeatureFlagsSource.RemoteConfig)] - [InlineData(null, null, "false", FeatureFlagsSource.Disabled)] + [InlineData(null, null, "false", FeatureFlagsSource.Offline)] // An explicit new-key value takes precedence over the legacy key, so a stale legacy disable // does not silently keep Feature Flags off during migration. [InlineData("true", null, "false", FeatureFlagsSource.Agentless)] @@ -44,15 +44,15 @@ public class FeatureFlagsSettingsTests [InlineData(null, "invalid", null, FeatureFlagsSource.Agentless)] [InlineData(null, "invalid", "true", FeatureFlagsSource.RemoteConfig)] // "offline" is a reserved, recognised fail-closed sentinel (not an unrecognised value). - [InlineData(null, "offline", null, FeatureFlagsSource.Disabled)] - [InlineData(null, "offline", "true", FeatureFlagsSource.Disabled)] + [InlineData(null, "offline", null, FeatureFlagsSource.Offline)] + [InlineData(null, "offline", "true", FeatureFlagsSource.Offline)] public void ResolvesSource(string? enabled, string? source, string? legacyEnabled, object expected) { var expectedSource = (FeatureFlagsSource)expected; var settings = CreateSettings(enabled, source, legacyEnabled); settings.Source.Should().Be(expectedSource); - settings.Enabled.Should().Be(expectedSource != FeatureFlagsSource.Disabled); + settings.Enabled.Should().Be(expectedSource != FeatureFlagsSource.Offline); } [Theory] From 1c063c33d8e0817ceb2a7384c2ba85d49d59e0fc Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 26 Aug 2026 18:16:13 +0300 Subject: [PATCH 51/86] [FeatureFlags] Address review comments on source resolution and endpoint validation --- .../Agentless/AgentlessEndpoint.cs | 14 ++++++++------ .../FeatureFlags/FeatureFlagsSettings.cs | 18 ++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs index a92e60db653f..2780dafddcf7 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs @@ -85,17 +85,18 @@ public static bool TryCreate(string? site, string? baseUrl, [NotNullWhen(true)] return false; } - var managedHost = ManagedHostPrefix + trimmedSite.ToLowerInvariant(); // A site accidentally set to e.g. "https://datadoghq.com" would produce a host like - // "ufc-server.ff-cdn.https://datadoghq.com" which Uri.TryCreate accepts as valid - // (treating the "//" as a path separator). Catch it explicitly; whitespace and - // invalid ports are already rejected by TryCreate. - if (managedHost.Contains("://")) + // "ufc-server.ff-cdn.https://datadoghq.com", which Uri.TryCreate accepts as valid + // (treating the "//" as a path separator), so it is caught here. Whitespace and invalid + // ports need no check: Uri.TryCreate does reject those inside a host. + if (trimmedSite.Contains("://")) { error = "The configured Datadog site is not valid"; return false; } + var managedHost = ManagedHostPrefix + trimmedSite.ToLowerInvariant(); + if (!Uri.TryCreate($"https://{managedHost}{DefaultPath}", UriKind.Absolute, out var managedUri)) { error = "The configured Datadog site is not valid"; @@ -106,7 +107,8 @@ public static bool TryCreate(string? site, string? baseUrl, [NotNullWhen(true)] return true; } - // A URL with internal whitespace is malformed, and Uri parsing is lenient enough to accept it. + // Uri parsing rejects whitespace inside a host, but accepts it in a path or query, so a + // URL carrying it there is malformed and has to be caught explicitly. foreach (var character in configured) { if (char.IsWhiteSpace(character)) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs index 193f3db804b5..0c22fb787e33 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs @@ -61,17 +61,17 @@ public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetr #pragma warning restore 618 } - // The source is resolved in a single read so configuration telemetry reports the value we - // actually use. Shared across tracers, so the precedence is deliberate: the stable kill + // The source key is read once, with every other outcome expressed as its default, so + // configuration telemetry reports the one value we act on rather than one entry per + // candidate key. Shared across tracers, so the precedence is deliberate: the stable kill // switch wins over everything (expressed as a validator that rejects any configured value), // an explicit source wins over the legacy key, the legacy key grandfathers existing // adopters onto Remote Configuration, and everything else defaults to agentless. - DefaultResult defaultSource = enabled switch + DefaultResult defaultSource = (enabled, legacyEnabled) switch { - false => new(FeatureFlagsSource.Offline, OfflineSourceName), - null when legacyEnabled is not null => legacyEnabled.Value - ? new(FeatureFlagsSource.RemoteConfig, RemoteConfigSourceName) - : new(FeatureFlagsSource.Offline, OfflineSourceName), + (false, _) => new(FeatureFlagsSource.Offline, OfflineSourceName), + (null, true) => new(FeatureFlagsSource.RemoteConfig, RemoteConfigSourceName), + (null, false) => new(FeatureFlagsSource.Offline, OfflineSourceName), _ => new(FeatureFlagsSource.Agentless, AgentlessSourceName), }; @@ -166,9 +166,7 @@ private static ParsingResult ConvertSource(string? value) return ParsingResult.Failure(); } - // Compared without allocating. A value with surrounding whitespace is trimmed only once the - // direct comparisons have failed, so the common path stays allocation-free. - if (TryMatch(value, out var source) || TryMatch(value.Trim(), out source)) + if (TryMatch(value.Trim(), out var source)) { return ParsingResult.Success(source); } From 85eacdb937edbbde64a1766c86087ee1d2d1e50e Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 26 Aug 2026 18:30:51 +0300 Subject: [PATCH 52/86] FeatureFlags] Document the agentless base URL contract --- .../Configuration/supported-configurations.yaml | 11 ++++++++--- .../FeatureFlags/FeatureFlagsSettings.cs | 11 +++++++---- .../ConfigurationKeys.FeatureFlags.g.cs | 11 ++++++++--- .../ConfigurationKeys.FeatureFlags.g.cs | 11 ++++++++--- .../ConfigurationKeys.FeatureFlags.g.cs | 11 ++++++++--- .../ConfigurationKeys.FeatureFlags.g.cs | 11 ++++++++--- 6 files changed, 47 insertions(+), 19 deletions(-) diff --git a/tracer/src/Datadog.Trace/Configuration/supported-configurations.yaml b/tracer/src/Datadog.Trace/Configuration/supported-configurations.yaml index 7347d243d4d2..de6472239a3b 100644 --- a/tracer/src/Datadog.Trace/Configuration/supported-configurations.yaml +++ b/tracer/src/Datadog.Trace/Configuration/supported-configurations.yaml @@ -3206,9 +3206,14 @@ supportedConfigurations: const_name: FeatureFlagsConfigurationSourceAgentlessBaseUrl documentation: |- Configuration key for overriding the endpoint used by the agentless configuration source. - When the URL has no path, or a path of /, the standard rules-based server path is appended; - any other path is used verbatim as the exact endpoint. - If unset, the endpoint is derived from . + If unset, the endpoint is derived from and Datadog hosts it. + A configured URL is treated as an endpoint of your own, which changes three things: + the Datadog API key is not sent to it, so it is responsible for its own authentication; + it is requested exactly as written, so dd_env is not added and any environment or tenant + scope has to be part of the URL you configure; + and only its path is completed, when it has none or a path of /, with the standard + rules-based server path. Any other path is used verbatim as the exact endpoint. + The value may carry credentials, so it is never written to logs or telemetry. DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_POLL_INTERVAL_SECONDS: - implementation: A scope: managed diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs index 0c22fb787e33..766612537db8 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs @@ -67,11 +67,14 @@ public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetr // switch wins over everything (expressed as a validator that rejects any configured value), // an explicit source wins over the legacy key, the legacy key grandfathers existing // adopters onto Remote Configuration, and everything else defaults to agentless. - DefaultResult defaultSource = (enabled, legacyEnabled) switch + // Not a tuple pattern: net461 has no System.ValueTuple, so (enabled, legacyEnabled) switch + // does not compile there. + DefaultResult defaultSource = enabled switch { - (false, _) => new(FeatureFlagsSource.Offline, OfflineSourceName), - (null, true) => new(FeatureFlagsSource.RemoteConfig, RemoteConfigSourceName), - (null, false) => new(FeatureFlagsSource.Offline, OfflineSourceName), + false => new(FeatureFlagsSource.Offline, OfflineSourceName), + null when legacyEnabled is not null => legacyEnabled.Value + ? new(FeatureFlagsSource.RemoteConfig, RemoteConfigSourceName) + : new(FeatureFlagsSource.Offline, OfflineSourceName), _ => new(FeatureFlagsSource.Agentless, AgentlessSourceName), }; diff --git a/tracer/src/Datadog.Trace/Generated/net461/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs b/tracer/src/Datadog.Trace/Generated/net461/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs index fc6c32d2b92b..288cd8f848eb 100644 --- a/tracer/src/Datadog.Trace/Generated/net461/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs +++ b/tracer/src/Datadog.Trace/Generated/net461/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs @@ -49,9 +49,14 @@ internal static class FeatureFlags /// /// Configuration key for overriding the endpoint used by the agentless configuration source. - /// When the URL has no path, or a path of /, the standard rules-based server path is appended; - /// any other path is used verbatim as the exact endpoint. - /// If unset, the endpoint is derived from . + /// If unset, the endpoint is derived from and Datadog hosts it. + /// A configured URL is treated as an endpoint of your own, which changes three things: + /// the Datadog API key is not sent to it, so it is responsible for its own authentication; + /// it is requested exactly as written, so dd_env is not added and any environment or tenant + /// scope has to be part of the URL you configure; + /// and only its path is completed, when it has none or a path of /, with the standard + /// rules-based server path. Any other path is used verbatim as the exact endpoint. + /// The value may carry credentials, so it is never written to logs or telemetry. /// public const string FeatureFlagsConfigurationSourceAgentlessBaseUrl = "DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_BASE_URL"; diff --git a/tracer/src/Datadog.Trace/Generated/net6.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs b/tracer/src/Datadog.Trace/Generated/net6.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs index fc6c32d2b92b..288cd8f848eb 100644 --- a/tracer/src/Datadog.Trace/Generated/net6.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs +++ b/tracer/src/Datadog.Trace/Generated/net6.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs @@ -49,9 +49,14 @@ internal static class FeatureFlags /// /// Configuration key for overriding the endpoint used by the agentless configuration source. - /// When the URL has no path, or a path of /, the standard rules-based server path is appended; - /// any other path is used verbatim as the exact endpoint. - /// If unset, the endpoint is derived from . + /// If unset, the endpoint is derived from and Datadog hosts it. + /// A configured URL is treated as an endpoint of your own, which changes three things: + /// the Datadog API key is not sent to it, so it is responsible for its own authentication; + /// it is requested exactly as written, so dd_env is not added and any environment or tenant + /// scope has to be part of the URL you configure; + /// and only its path is completed, when it has none or a path of /, with the standard + /// rules-based server path. Any other path is used verbatim as the exact endpoint. + /// The value may carry credentials, so it is never written to logs or telemetry. /// public const string FeatureFlagsConfigurationSourceAgentlessBaseUrl = "DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_BASE_URL"; diff --git a/tracer/src/Datadog.Trace/Generated/netcoreapp3.1/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs b/tracer/src/Datadog.Trace/Generated/netcoreapp3.1/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs index fc6c32d2b92b..288cd8f848eb 100644 --- a/tracer/src/Datadog.Trace/Generated/netcoreapp3.1/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs +++ b/tracer/src/Datadog.Trace/Generated/netcoreapp3.1/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs @@ -49,9 +49,14 @@ internal static class FeatureFlags /// /// Configuration key for overriding the endpoint used by the agentless configuration source. - /// When the URL has no path, or a path of /, the standard rules-based server path is appended; - /// any other path is used verbatim as the exact endpoint. - /// If unset, the endpoint is derived from . + /// If unset, the endpoint is derived from and Datadog hosts it. + /// A configured URL is treated as an endpoint of your own, which changes three things: + /// the Datadog API key is not sent to it, so it is responsible for its own authentication; + /// it is requested exactly as written, so dd_env is not added and any environment or tenant + /// scope has to be part of the URL you configure; + /// and only its path is completed, when it has none or a path of /, with the standard + /// rules-based server path. Any other path is used verbatim as the exact endpoint. + /// The value may carry credentials, so it is never written to logs or telemetry. /// public const string FeatureFlagsConfigurationSourceAgentlessBaseUrl = "DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_BASE_URL"; diff --git a/tracer/src/Datadog.Trace/Generated/netstandard2.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs b/tracer/src/Datadog.Trace/Generated/netstandard2.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs index fc6c32d2b92b..288cd8f848eb 100644 --- a/tracer/src/Datadog.Trace/Generated/netstandard2.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs +++ b/tracer/src/Datadog.Trace/Generated/netstandard2.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs @@ -49,9 +49,14 @@ internal static class FeatureFlags /// /// Configuration key for overriding the endpoint used by the agentless configuration source. - /// When the URL has no path, or a path of /, the standard rules-based server path is appended; - /// any other path is used verbatim as the exact endpoint. - /// If unset, the endpoint is derived from . + /// If unset, the endpoint is derived from and Datadog hosts it. + /// A configured URL is treated as an endpoint of your own, which changes three things: + /// the Datadog API key is not sent to it, so it is responsible for its own authentication; + /// it is requested exactly as written, so dd_env is not added and any environment or tenant + /// scope has to be part of the URL you configure; + /// and only its path is completed, when it has none or a path of /, with the standard + /// rules-based server path. Any other path is used verbatim as the exact endpoint. + /// The value may carry credentials, so it is never written to logs or telemetry. /// public const string FeatureFlagsConfigurationSourceAgentlessBaseUrl = "DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_BASE_URL"; From 4149d7b0d2cb86b8e24ebc7b4f121a19ee9ce985 Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 26 Aug 2026 18:49:27 +0300 Subject: [PATCH 53/86] [FeatureFlags] Fail closed on an unrecognised configuration source --- .../FeatureFlags/FeatureFlagsSettings.cs | 19 +++++++++++++------ .../FeatureFlags/FeatureFlagsSettingsTests.cs | 9 +++++---- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs index 766612537db8..42140bd6f726 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs @@ -65,8 +65,9 @@ public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetr // configuration telemetry reports the one value we act on rather than one entry per // candidate key. Shared across tracers, so the precedence is deliberate: the stable kill // switch wins over everything (expressed as a validator that rejects any configured value), - // an explicit source wins over the legacy key, the legacy key grandfathers existing - // adopters onto Remote Configuration, and everything else defaults to agentless. + // an explicit source wins over the legacy key (an unrecognised one fails closed, so a typo + // never starts billed delivery), the legacy key grandfathers existing adopters onto Remote + // Configuration, and everything else defaults to agentless. // Not a tuple pattern: net461 has no System.ValueTuple, so (enabled, legacyEnabled) switch // does not compile there. DefaultResult defaultSource = enabled switch @@ -158,9 +159,8 @@ public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetr /// /// Converts a configured source name to a . A blank value is - /// treated as unset, and an unrecognised one is reported as a parsing failure so that it shows - /// up as rejected in configuration telemetry rather than as a value nobody configured. Both - /// fall back to the default, which is what an unset key would have selected anyway. + /// treated as unset and falls back to the default, which is what an absent key would have + /// selected anyway. An unrecognised value fails closed instead: nothing is contacted. /// private static ParsingResult ConvertSource(string? value) { @@ -174,7 +174,14 @@ private static ParsingResult ConvertSource(string? value) return ParsingResult.Success(source); } - return ParsingResult.Failure(); + // A value nobody recognises fails closed rather than falling back to agentless: guessing a + // billed delivery path from a typo is worse than delivering nothing. Shared across tracers, + // and asserted by the system-tests parametric suite. + Log.Warning( + "Unsupported Feature Flags configuration source {Source}. No configuration will be delivered.", + value); + + return ParsingResult.Success(FeatureFlagsSource.Offline); } private static bool TryMatch(string value, out FeatureFlagsSource source) diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs index b83c204da4d9..96055611a967 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs @@ -39,10 +39,11 @@ public class FeatureFlagsSettingsTests // does not silently keep Feature Flags off during migration. [InlineData("true", null, "false", FeatureFlagsSource.Agentless)] [InlineData("true", null, "true", FeatureFlagsSource.Agentless)] - // An unrecognised source is a parsing failure, reported as such in configuration telemetry, so - // the key behaves as if it were unset rather than resolving to a value nobody configured. - [InlineData(null, "invalid", null, FeatureFlagsSource.Agentless)] - [InlineData(null, "invalid", "true", FeatureFlagsSource.RemoteConfig)] + // An unrecognised source fails closed, and does so before the legacy key is considered: starting + // billed delivery off a typo is worse than delivering nothing. Java and JS resolve it the same + // way, and the system-tests parametric suite asserts no request is made. + [InlineData(null, "invalid", null, FeatureFlagsSource.Offline)] + [InlineData(null, "invalid", "true", FeatureFlagsSource.Offline)] // "offline" is a reserved, recognised fail-closed sentinel (not an unrecognised value). [InlineData(null, "offline", null, FeatureFlagsSource.Offline)] [InlineData(null, "offline", "true", FeatureFlagsSource.Offline)] From 3bfd025a59ca657587d9ccf632eafa4c551f98ae Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 26 Aug 2026 18:57:54 +0300 Subject: [PATCH 54/86] [FeatureFlags] Reject a Datadog site that can redirect the managed endpoint --- .../Agentless/AgentlessEndpoint.cs | 18 +++++++++++------- .../FeatureFlags/AgentlessEndpointTests.cs | 6 ++++++ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs index 2780dafddcf7..08868b22573d 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessEndpoint.cs @@ -85,14 +85,18 @@ public static bool TryCreate(string? site, string? baseUrl, [NotNullWhen(true)] return false; } - // A site accidentally set to e.g. "https://datadoghq.com" would produce a host like - // "ufc-server.ff-cdn.https://datadoghq.com", which Uri.TryCreate accepts as valid - // (treating the "//" as a path separator), so it is caught here. Whitespace and invalid - // ports need no check: Uri.TryCreate does reject those inside a host. - if (trimmedSite.Contains("://")) + // The site is concatenated into a host, so every character that can change what a URL means + // has to be rejected before that happens. "@" is the dangerous one: it would make the rest of + // the value the real host, and the API key would be sent there. "/", "?" and "#" would start a + // path, query or fragment, and ":" a port or a scheme. Uri.TryCreate accepts several of these, + // so it cannot be relied on to catch them. The other tracers reject the same set. + foreach (var character in trimmedSite) { - error = "The configured Datadog site is not valid"; - return false; + if (char.IsWhiteSpace(character) || character is '/' or '?' or '#' or '@' or ':') + { + error = "The configured Datadog site is not valid"; + return false; + } } var managedHost = ManagedHostPrefix + trimmedSite.ToLowerInvariant(); diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs index 00f67195754e..6e024bfe7456 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessEndpointTests.cs @@ -134,6 +134,12 @@ public void RejectsWhitespaceOnlySiteWithoutBaseUrl() [InlineData("https://datadoghq.com")] // user accidentally includes the scheme [InlineData("data dog hq.com")] // internal spaces [InlineData("datadoghq.com:99999")] // invalid port + // "@" would end the userinfo and make the remainder the real host, so the request, and with it + // the API key, would go to a host the operator never named. + [InlineData("datadoghq.com@attacker.example")] + [InlineData("datadoghq.com/../evil")] // a path escapes the host + [InlineData("datadoghq.com?x=1")] // a query escapes the host + [InlineData("datadoghq.com#f")] // a fragment escapes the host public void RejectsMalformedSiteWithoutThrowing(string site) { AgentlessEndpoint.TryCreate(site, baseUrl: null, out var endpoint, out var error) From d8e1083f6ca35507e628ca44220761d9af90b8fd Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 26 Aug 2026 20:19:46 +0300 Subject: [PATCH 55/86] [FeatureFlags] Reject a Datadog site that can redirect the managed endpoint --- .../FeatureFlags/FeatureFlagsSettings.cs | 45 +++++++------------ .../FeatureFlags/FeatureFlagsSource.cs | 5 +-- 2 files changed, 18 insertions(+), 32 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs index 42140bd6f726..023c93103631 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs @@ -68,8 +68,7 @@ public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetr // an explicit source wins over the legacy key (an unrecognised one fails closed, so a typo // never starts billed delivery), the legacy key grandfathers existing adopters onto Remote // Configuration, and everything else defaults to agentless. - // Not a tuple pattern: net461 has no System.ValueTuple, so (enabled, legacyEnabled) switch - // does not compile there. + // net461 has no System.ValueTuple, so a tuple pattern over both values does not compile. DefaultResult defaultSource = enabled switch { false => new(FeatureFlagsSource.Offline, OfflineSourceName), @@ -169,9 +168,22 @@ private static ParsingResult ConvertSource(string? value) return ParsingResult.Failure(); } - if (TryMatch(value.Trim(), out var source)) + var trimmed = value.Trim(); + + if (string.Equals(trimmed, AgentlessSourceName, StringComparison.OrdinalIgnoreCase)) + { + return ParsingResult.Success(FeatureFlagsSource.Agentless); + } + + if (string.Equals(trimmed, RemoteConfigSourceName, StringComparison.OrdinalIgnoreCase)) + { + return ParsingResult.Success(FeatureFlagsSource.RemoteConfig); + } + + // "offline" is a reserved sentinel: the provider is intentionally off. + if (string.Equals(trimmed, OfflineSourceName, StringComparison.OrdinalIgnoreCase)) { - return ParsingResult.Success(source); + return ParsingResult.Success(FeatureFlagsSource.Offline); } // A value nobody recognises fails closed rather than falling back to agentless: guessing a @@ -183,29 +195,4 @@ private static ParsingResult ConvertSource(string? value) return ParsingResult.Success(FeatureFlagsSource.Offline); } - - private static bool TryMatch(string value, out FeatureFlagsSource source) - { - if (string.Equals(value, AgentlessSourceName, StringComparison.OrdinalIgnoreCase)) - { - source = FeatureFlagsSource.Agentless; - return true; - } - - if (string.Equals(value, RemoteConfigSourceName, StringComparison.OrdinalIgnoreCase)) - { - source = FeatureFlagsSource.RemoteConfig; - return true; - } - - // "offline" is a reserved fail-closed sentinel: the provider is intentionally off. - if (string.Equals(value, OfflineSourceName, StringComparison.OrdinalIgnoreCase)) - { - source = FeatureFlagsSource.Offline; - return true; - } - - source = FeatureFlagsSource.Offline; - return false; - } } diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSource.cs index 558a28900adf..3c85ae61433f 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSource.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSource.cs @@ -13,9 +13,8 @@ namespace Datadog.Trace.FeatureFlags; internal enum FeatureFlagsSource { /// - /// Nothing is contacted and no configuration is loaded, so evaluations return the caller's - /// default value. Named after the offline value that selects it: it is a source rather - /// than an off switch, because it is reserved for serving configuration supplied at startup. + /// Selected by offline. Nothing is contacted and no configuration is loaded, so + /// evaluations return the caller's default value. /// Offline, From aa8fc5be7168090b51ec7d5a093cd1ff8579f849 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 27 Aug 2026 09:33:49 +0300 Subject: [PATCH 56/86] [FeatureFlags] Separate whether Feature Flags run from where configuration comes from --- .../FeatureFlags/FeatureFlagsSettings.cs | 26 ++++++----- .../FeatureFlags/FeatureFlagsSettingsTests.cs | 43 ++++++++++--------- 2 files changed, 37 insertions(+), 32 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs index 023c93103631..9bbb0aa7234b 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs @@ -61,17 +61,17 @@ public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetr #pragma warning restore 618 } + // Where configuration comes from is a separate question from whether the product runs, and + // the two are answered separately below, as the other tracers answer them. + // // The source key is read once, with every other outcome expressed as its default, so // configuration telemetry reports the one value we act on rather than one entry per - // candidate key. Shared across tracers, so the precedence is deliberate: the stable kill - // switch wins over everything (expressed as a validator that rejects any configured value), - // an explicit source wins over the legacy key (an unrecognised one fails closed, so a typo - // never starts billed delivery), the legacy key grandfathers existing adopters onto Remote + // candidate key. Shared across tracers, so the precedence is deliberate: an explicit source + // wins over the legacy key, the legacy key grandfathers existing adopters onto Remote // Configuration, and everything else defaults to agentless. // net461 has no System.ValueTuple, so a tuple pattern over both values does not compile. DefaultResult defaultSource = enabled switch { - false => new(FeatureFlagsSource.Offline, OfflineSourceName), null when legacyEnabled is not null => legacyEnabled.Value ? new(FeatureFlagsSource.RemoteConfig, RemoteConfigSourceName) : new(FeatureFlagsSource.Offline, OfflineSourceName), @@ -80,10 +80,13 @@ public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetr Source = config .WithKeys(ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSource) - .GetAs( - defaultSource, - validator: enabled == false ? static _ => false : static _ => true, - converter: ConvertSource); + .GetAs(defaultSource, validator: null, converter: ConvertSource); + + // The stable kill switch turns the product off whatever the source says. Beyond that, only a + // delivery source has anything to run: offline delivers nothing, and an unrecognised value + // resolves to offline so that a typo fails closed instead of starting billed delivery. + Enabled = enabled != false + && Source is FeatureFlagsSource.Agentless or FeatureFlagsSource.RemoteConfig; var agentlessBaseUrl = config .WithKeys(ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSourceAgentlessBaseUrl) @@ -122,9 +125,10 @@ public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetr public FeatureFlagsSource Source { get; } /// - /// Gets a value indicating whether Feature Flags are enabled at all. + /// Gets a value indicating whether Feature Flags run at all. Independent of , + /// which says where configuration would come from. /// - public bool Enabled => Source != FeatureFlagsSource.Offline; + public bool Enabled { get; } /// /// Gets the configured override for the agentless endpoint, or null to derive it from the site. diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs index 96055611a967..79d67eedb464 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsSettingsTests.cs @@ -19,41 +19,42 @@ public class FeatureFlagsSettingsTests { // The source-selection contract is shared across tracers, so these cases mirror the // system-tests parametric suite (tests/parametric/test_ffe/test_configuration_sources.py). + // Where configuration would come from and whether Feature Flags run are asserted separately: + // the kill switch turns the product off without changing the source it would have used. [Theory] // Nothing configured: agentless is the default. - [InlineData(null, null, null, FeatureFlagsSource.Agentless)] + [InlineData(null, null, null, FeatureFlagsSource.Agentless, true)] // The stable kill switch wins over everything, including a legacy opt-in and an explicit source. - [InlineData("false", null, null, FeatureFlagsSource.Offline)] - [InlineData("false", null, "true", FeatureFlagsSource.Offline)] - [InlineData("false", "agentless", null, FeatureFlagsSource.Offline)] - [InlineData("false", "remote_config", null, FeatureFlagsSource.Offline)] + [InlineData("false", null, null, FeatureFlagsSource.Agentless, false)] + [InlineData("false", null, "true", FeatureFlagsSource.Agentless, false)] + [InlineData("false", "agentless", null, FeatureFlagsSource.Agentless, false)] + [InlineData("false", "remote_config", null, FeatureFlagsSource.RemoteConfig, false)] // Enabling explicitly does not imply the historical Remote Configuration source. - [InlineData("true", null, null, FeatureFlagsSource.Agentless)] + [InlineData("true", null, null, FeatureFlagsSource.Agentless, true)] // An explicit source wins over the legacy key, in both directions. - [InlineData(null, "agentless", "true", FeatureFlagsSource.Agentless)] - [InlineData(null, "remote_config", "false", FeatureFlagsSource.RemoteConfig)] + [InlineData(null, "agentless", "true", FeatureFlagsSource.Agentless, true)] + [InlineData(null, "remote_config", "false", FeatureFlagsSource.RemoteConfig, true)] // The legacy key grandfathers existing adopters, who opted in when RC was the only source. - [InlineData(null, null, "true", FeatureFlagsSource.RemoteConfig)] - [InlineData(null, null, "false", FeatureFlagsSource.Offline)] + [InlineData(null, null, "true", FeatureFlagsSource.RemoteConfig, true)] + [InlineData(null, null, "false", FeatureFlagsSource.Offline, false)] // An explicit new-key value takes precedence over the legacy key, so a stale legacy disable // does not silently keep Feature Flags off during migration. - [InlineData("true", null, "false", FeatureFlagsSource.Agentless)] - [InlineData("true", null, "true", FeatureFlagsSource.Agentless)] + [InlineData("true", null, "false", FeatureFlagsSource.Agentless, true)] + [InlineData("true", null, "true", FeatureFlagsSource.Agentless, true)] // An unrecognised source fails closed, and does so before the legacy key is considered: starting // billed delivery off a typo is worse than delivering nothing. Java and JS resolve it the same // way, and the system-tests parametric suite asserts no request is made. - [InlineData(null, "invalid", null, FeatureFlagsSource.Offline)] - [InlineData(null, "invalid", "true", FeatureFlagsSource.Offline)] - // "offline" is a reserved, recognised fail-closed sentinel (not an unrecognised value). - [InlineData(null, "offline", null, FeatureFlagsSource.Offline)] - [InlineData(null, "offline", "true", FeatureFlagsSource.Offline)] - public void ResolvesSource(string? enabled, string? source, string? legacyEnabled, object expected) + [InlineData(null, "invalid", null, FeatureFlagsSource.Offline, false)] + [InlineData(null, "invalid", "true", FeatureFlagsSource.Offline, false)] + // "offline" is a recognised source that delivers nothing, so there is nothing to run yet. + [InlineData(null, "offline", null, FeatureFlagsSource.Offline, false)] + [InlineData(null, "offline", "true", FeatureFlagsSource.Offline, false)] + public void ResolvesSource(string? enabled, string? source, string? legacyEnabled, object expected, bool expectedEnabled) { - var expectedSource = (FeatureFlagsSource)expected; var settings = CreateSettings(enabled, source, legacyEnabled); - settings.Source.Should().Be(expectedSource); - settings.Enabled.Should().Be(expectedSource != FeatureFlagsSource.Offline); + settings.Source.Should().Be((FeatureFlagsSource)expected); + settings.Enabled.Should().Be(expectedEnabled); } [Theory] From 42aaffc6297f1d2b2320805445acabfc85693d9d Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 13 Aug 2026 14:53:55 +0300 Subject: [PATCH 57/86] feat(feature-flags): add UfcConfigurationParser for JSON:API envelope validation --- .../Agentless/UfcConfigurationParser.cs | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs new file mode 100644 index 000000000000..58bbfe2691e9 --- /dev/null +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs @@ -0,0 +1,90 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +#nullable enable + +using System; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using Datadog.Trace.FeatureFlags.Rcm.Model; +using Datadog.Trace.Vendors.Newtonsoft.Json; +using Datadog.Trace.Vendors.Newtonsoft.Json.Linq; + +namespace Datadog.Trace.FeatureFlags.Agentless; + +/// +/// Reads the JSON:API envelope returned by the agentless endpoint. +/// +internal static class UfcConfigurationParser +{ + private const string ResourceType = "universal-flag-configuration"; + + /// + /// Validates a JSON:API Universal Flag Configuration response and returns data.attributes, + /// which is the document the evaluator consumes. A raw UFC document is rejected, including from + /// a custom endpoint, so that every source agrees on one wire format. + /// + /// The response body. + /// The parsed configuration. + /// Why the payload was rejected. + /// true when the payload matches the contract. + public static bool TryParse(string? body, [NotNullWhen(true)] out ServerConfiguration? configuration, out string? error) + { + configuration = null; + error = null; + + JToken payload; + try + { + using var stringReader = new StringReader(body ?? string.Empty); + + // Timestamps stay strings: the model carries createdAt verbatim, and letting Newtonsoft + // turn it into a date would also make the type check below fail. + using var jsonReader = new JsonTextReader(stringReader) { DateParseHandling = DateParseHandling.None }; + payload = JToken.ReadFrom(jsonReader); + } + catch (Exception) + { + error = "Malformed UFC payload"; + return false; + } + + if (payload is not JObject + || payload["data"] is not JObject data + || data["type"]?.Value() != ResourceType) + { + error = "Expected a JSON:API Universal Flag Configuration resource"; + return false; + } + + if (data["attributes"] is not JObject attributes + || attributes["format"]?.Type != JTokenType.String + || attributes["createdAt"]?.Type != JTokenType.String + || attributes["environment"] is not JObject environment + || environment["name"]?.Type != JTokenType.String + || attributes["flags"] is not JObject) + { + error = "Expected a Universal Flag Configuration v1 object"; + return false; + } + + try + { + configuration = attributes.ToObject(); + } + catch (Exception) + { + configuration = null; + } + + if (configuration is null) + { + error = "Expected a Universal Flag Configuration v1 object"; + return false; + } + + return true; + } +} From 5c818628c5affa4982717d16ac4386932836fcd1 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 13 Aug 2026 15:01:50 +0300 Subject: [PATCH 58/86] test(feature-flags): add UfcConfigurationParserTests for JSON:API envelope validation --- .../Agentless/AgentlessConfigurationSource.cs | 399 ++++++++++++++++++ .../UfcConfigurationParserTests.cs | 108 +++++ 2 files changed, 507 insertions(+) create mode 100644 tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs create mode 100644 tracer/test/Datadog.Trace.Tests/FeatureFlags/UfcConfigurationParserTests.cs diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs new file mode 100644 index 000000000000..6d23a7045c31 --- /dev/null +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs @@ -0,0 +1,399 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +#nullable enable + +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Threading; +using System.Threading.Tasks; +using Datadog.Trace.Agent; +using Datadog.Trace.Agent.Transports; +using Datadog.Trace.FeatureFlags.Rcm.Model; +using Datadog.Trace.Headers; +using Datadog.Trace.Logging; +using Datadog.Trace.Telemetry; +using Datadog.Trace.Util; + +namespace Datadog.Trace.FeatureFlags.Agentless; + +/// +/// Polls the agentless endpoint for flag configuration. Polling is billable, so it is only +/// started once application code has activated the provider. +/// +internal sealed class AgentlessConfigurationSource : IDisposable +{ + private const int MaxAttempts = 3; + private const double RetryJitter = 0.2; + + private static readonly TimeSpan FirstRetryMin = TimeSpan.FromSeconds(2); + private static readonly TimeSpan FirstRetryMax = TimeSpan.FromSeconds(10); + private static readonly TimeSpan SecondRetryMin = TimeSpan.FromSeconds(5); + private static readonly TimeSpan SecondRetryMax = TimeSpan.FromSeconds(30); + + // A jittered retry delay never drops below this, so a short poll interval cannot turn + // retries into a burst against the endpoint. + private static readonly TimeSpan MinRetryDelay = TimeSpan.FromSeconds(1); + + private static readonly IDatadogLogger Log = DatadogLogging.GetLoggerFor(typeof(AgentlessConfigurationSource)); + + private readonly IApiRequestFactory _requestFactory; + private readonly Uri _endpoint; + private readonly TimeSpan _pollInterval; + private readonly Func _applyConfiguration; + private readonly Func _waitAsync; + private readonly CancellationTokenSource _shutdown = new(); + private readonly Random _random = new(); + + // Only ever touched from the poll loop. + private readonly HashSet _loggedFailureCategories = new(); + private bool _malformedPayloadLogged; + private bool _applyFailureLogged; + private string? _etag; + + private int _started; + + internal AgentlessConfigurationSource( + Uri endpoint, + IApiRequestFactory requestFactory, + TimeSpan pollInterval, + Func applyConfiguration, + Func? waitAsync = null) + { + _endpoint = endpoint; + _requestFactory = requestFactory; + _pollInterval = pollInterval; + _applyConfiguration = applyConfiguration; + _waitAsync = waitAsync ?? Task.Delay; + } + + /// + /// Creates the source, or returns null when it cannot be operated: a base URL that is + /// not a URL, or the managed endpoint without an API key. Polling anyway would only produce + /// failures every interval. + /// + public static AgentlessConfigurationSource? Create(FeatureFlagsSettings settings, Func applyConfiguration) + { + if (!AgentlessEndpoint.TryCreate(settings.Site, settings.Env, settings.AgentlessBaseUrl, out var endpoint, out var error)) + { + Log.Error("Feature Flags agentless source is unavailable: {Error}", error); + return null; + } + + if (endpoint.IsManaged && StringUtil.IsNullOrEmpty(settings.ApiKey)) + { + Log.Error("Feature Flags agentless source requires an API key. Set DD_API_KEY, or point DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_BASE_URL at an endpoint of your own."); + return null; + } + + return new AgentlessConfigurationSource( + endpoint.Uri, + CreateRequestFactory(endpoint, settings), + settings.PollInterval, + applyConfiguration); + } + + /// + /// Starts polling. Idempotent. + /// + public void Start() + { + if (Interlocked.CompareExchange(ref _started, 1, 0) != 0) + { + return; + } + + // Deliberately not wrapped in Task.Run: this is called from provider initialization, which + // is waiting for the first configuration, so the first request should go out on the calling + // thread rather than queue behind whatever else is on the thread pool. + _ = RunAsync().ContinueWith(t => Log.Error(t.Exception, "Feature Flags agentless poll loop failed"), TaskContinuationOptions.OnlyOnFaulted); + } + + /// + /// Runs a single poll, including its in-tick retries. + /// + internal async Task PollAsync() + { + var result = default(PollResult); + + for (var attempt = 1; attempt <= MaxAttempts; attempt++) + { + result = await RequestAsync().ConfigureAwait(false); + + if (_shutdown.IsCancellationRequested) + { + // A shutdown mid-poll leaves the response unusable for state transitions: keep + // last-known-good and the current ETag. + return; + } + + if (!IsRetryable(result)) + { + break; + } + + if (attempt == MaxAttempts) + { + // Every attempt failed in a retryable way. Last-known-good stays in place. + WarnFailure(result, MaxAttempts); + return; + } + + await WaitAsync(RetryDelay(attempt)).ConfigureAwait(false); + + if (_shutdown.IsCancellationRequested) + { + return; + } + } + + if (_shutdown.IsCancellationRequested) + { + // A shutdown during the final attempt leaves the response unusable for state + // transitions: keep last-known-good and the current ETag. + return; + } + + await ApplyAsync(result).ConfigureAwait(false); + } + + public void Dispose() + { + // The request in flight is bounded by the request timeout, and the loop is never joined, + // so a shutdown does not wait for it. A poll that completes after disposal is prevented + // from applying its result by the shutdown check in PollAsync. + try + { + _shutdown.Cancel(); + } + catch (Exception ex) + { + Log.Debug(ex, "Error cancelling the Feature Flags agentless poll loop"); + } + } + + // The concrete type is returned rather than the interface because CA1859 asks for it on a + // private member, which is also why the signature varies by target framework. +#if NETCOREAPP + private static HttpClientRequestFactory CreateRequestFactory(AgentlessEndpoint endpoint, FeatureFlagsSettings settings) +#else + private static ApiWebRequestFactory CreateRequestFactory(AgentlessEndpoint endpoint, FeatureFlagsSettings settings) +#endif + { + var headers = new List> + { + // The endpoint serves gzip, and neither transport decompresses for us. + new("Accept-Encoding", "gzip"), + new(TelemetryConstants.ClientLibraryLanguageHeader, TracerConstants.Language), + new(TelemetryConstants.ClientLibraryVersionHeader, TracerConstants.ThreePartVersion), + + // Without this the poll is itself instrumented, producing a span per poll and letting + // auto-instrumentation recurse through the poller's own client. + new(HttpHeaderNames.TracingEnabled, "false"), + }; + + if (endpoint.IsManaged) + { + // A custom endpoint is left to report its own authentication failure rather than + // having the Datadog credential sent to it. + headers.Add(new(TelemetryConstants.ApiKeyHeader, settings.ApiKey!)); + } + +#if NETCOREAPP + return new HttpClientRequestFactory(endpoint.Uri, headers.ToArray(), timeout: settings.RequestTimeout); +#else + return new ApiWebRequestFactory(endpoint.Uri, headers.ToArray(), timeout: settings.RequestTimeout); +#endif + } + + private static bool IsRetryable(in PollResult result) + => result.StatusCode is not { } status || status is 408 or 429 or (>= 500 and <= 599); + + private async Task RunAsync() + { + Log.Debug("AgentlessConfigurationSource::RunAsync -> Enter"); + + while (!_shutdown.IsCancellationRequested) + { + try + { + await PollAsync().ConfigureAwait(false); + } + catch (Exception ex) + { + Log.Debug(ex, "Feature Flags agentless poll failed unexpectedly"); + } + + // Fixed delay after completion, so polls never overlap. + await WaitAsync(_pollInterval).ConfigureAwait(false); + } + + Log.Debug("AgentlessConfigurationSource::RunAsync -> Exit"); + } + + private async Task WaitAsync(TimeSpan delay) + { + try + { + await _waitAsync(delay, _shutdown.Token).ConfigureAwait(false); + } + catch (OperationCanceledException) + { + // Shutting down + } + } + + private TimeSpan RetryDelay(int attempt) + { + var seconds = attempt == 1 + ? Clamp(_pollInterval.TotalSeconds / 6, FirstRetryMin, FirstRetryMax) + : Clamp(_pollInterval.TotalSeconds / 3, SecondRetryMin, SecondRetryMax); + + double jitter; + lock (_random) + { + jitter = 1 - RetryJitter + (_random.NextDouble() * RetryJitter * 2); + } + + return TimeSpan.FromSeconds(Math.Max(MinRetryDelay.TotalSeconds, seconds * jitter)); + + static double Clamp(double value, TimeSpan minimum, TimeSpan maximum) + => Math.Max(minimum.TotalSeconds, Math.Min(maximum.TotalSeconds, value)); + } + + private async Task RequestAsync() + { + try + { + var request = _requestFactory.Create(_endpoint); + if (_etag is { } etag) + { + request.AddHeader("If-None-Match", etag); + } + + using var response = await request.GetAsync().ConfigureAwait(false); + + // Only a 200 carries configuration; other bodies are never decoded as one. + var body = response.StatusCode == 200 ? await ReadBodyAsync(response).ConfigureAwait(false) : null; + return new PollResult(response.StatusCode, response.GetHeader("ETag"), body, error: null); + } + catch (Exception ex) + { + return new PollResult(statusCode: null, etag: null, body: null, error: ex); + } + } + + private async Task ReadBodyAsync(IApiResponse response) + { + var stream = await response.GetStreamAsync().ConfigureAwait(false); + GZipStream? decompressed = null; + + try + { + if (response.GetContentEncodingType() == ContentEncodingType.GZip) + { + decompressed = new GZipStream(stream, CompressionMode.Decompress); + } + + using var reader = new StreamReader(decompressed ?? stream, response.GetCharsetEncoding()); + return await reader.ReadToEndAsync().ConfigureAwait(false); + } + finally + { + decompressed?.Dispose(); + } + } + + private Task ApplyAsync(PollResult result) + { + switch (result.StatusCode) + { + case 304: + // Nothing changed, and the ETag stays as it is. + return Task.CompletedTask; + case 401 or 403: + WarnFailure(result, attempts: 1); + return Task.CompletedTask; + case not 200: + WarnFailure(result, attempts: 1); + return Task.CompletedTask; + } + + if (!UfcConfigurationParser.TryParse(result.Body, out var configuration, out var error)) + { + if (!_malformedPayloadLogged) + { + _malformedPayloadLogged = true; + Log.Error("Feature Flags agentless endpoint returned an unusable payload: {Error}", error); + } + + return Task.CompletedTask; + } + + if (!_applyConfiguration(configuration)) + { + if (!_applyFailureLogged) + { + _applyFailureLogged = true; + Log.Warning("Feature Flags agentless configuration could not be applied"); + } + + return Task.CompletedTask; + } + + // The ETag advances only once parsing and applying have both succeeded. Advancing on + // receipt would acknowledge a payload that was never applied, and every later poll would + // answer 304, pinning the process to stale configuration with no way back. + var newEtag = result.ETag?.Trim(); + _etag = StringUtil.IsNullOrEmpty(newEtag) ? null : newEtag; + + return Task.CompletedTask; + } + + /// + /// Warns once per failure category. A dead endpoint would otherwise produce a warning every + /// poll interval, indefinitely. + /// + private void WarnFailure(in PollResult result, int attempts) + { + var category = result.StatusCode switch + { + 401 or 403 => "authentication", + not null => "http", + _ => "request", + }; + + if (!_loggedFailureCategories.Add(category)) + { + return; + } + + switch (result.StatusCode) + { + case 401 or 403: + Log.Warning("Feature Flags agentless endpoint returned HTTP {StatusCode}; verify endpoint authentication", result.StatusCode!.Value); + break; + case not null: + Log.Warning("Feature Flags agentless endpoint returned HTTP {StatusCode} after {Attempts} attempts", result.StatusCode.Value, attempts); + break; + default: + Log.Warning(result.Error, "Feature Flags agentless request failed after {Attempts} attempts", attempts); + break; + } + } + + internal readonly struct PollResult(int? statusCode, string? etag, string? body, Exception? error) + { + public int? StatusCode { get; } = statusCode; + + public string? ETag { get; } = etag; + + public string? Body { get; } = body; + + public Exception? Error { get; } = error; + } +} diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/UfcConfigurationParserTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/UfcConfigurationParserTests.cs new file mode 100644 index 000000000000..14fc51ab85a7 --- /dev/null +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/UfcConfigurationParserTests.cs @@ -0,0 +1,108 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +#nullable enable + +using System.Collections.Generic; +using Datadog.Trace.FeatureFlags.Agentless; +using Datadog.Trace.FeatureFlags.Rcm.Model; +using FluentAssertions; +using Xunit; + +namespace Datadog.Trace.Tests.FeatureFlags; + +public class UfcConfigurationParserTests +{ + private const string ValidEnvelope = """ + { "data": { "type": "universal-flag-configuration", + "attributes": { "format": "SERVER", "createdAt": "2025-01-01T00:00:00Z", + "environment": { "name": "production" }, "flags": {} } } } + """; + + private const string Attributes = """ + { "format": "SERVER", "createdAt": "2025-01-01T00:00:00Z", + "environment": { "name": "production" }, "flags": {} } + """; + + [Fact] + public void ParsesValidEnvelope() + { + UfcConfigurationParser.TryParse(ValidEnvelope, out var configuration, out var error) + .Should().BeTrue(); + + error.Should().BeNull(); + configuration.Should().NotBeNull(); + configuration!.Environment!.Name.Should().Be("production"); + configuration.Flags.Should().BeEmpty(); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData("not json")] + [InlineData("{ \"data\": ")] + public void RejectsMalformedJson(string? body) + { + UfcConfigurationParser.TryParse(body, out var configuration, out var error).Should().BeFalse(); + + configuration.Should().BeNull(); + error.Should().Be("Malformed UFC payload"); + } + + [Theory] + // A raw UFC document is rejected too, so every source agrees on one wire format. + [InlineData(Attributes)] + // Wrong resource type + [InlineData("""{ "data": { "type": "wrong-type", "attributes": { "format": "SERVER", "createdAt": "x", "environment": { "name": "prod" }, "flags": {} } } }""")] + // Missing data + [InlineData("""{ "meta": {} }""")] + // data is not an object + [InlineData("""{ "data": "string" }""")] + public void RejectsInvalidEnvelope(string body) + { + UfcConfigurationParser.TryParse(body, out var configuration, out var error).Should().BeFalse(); + + configuration.Should().BeNull(); + error.Should().Be("Expected a JSON:API Universal Flag Configuration resource"); + } + + [Theory] + // Missing format + [InlineData("""{ "data": { "type": "universal-flag-configuration", "attributes": { "createdAt": "x", "environment": { "name": "prod" }, "flags": {} } } }""")] + // Missing createdAt + [InlineData("""{ "data": { "type": "universal-flag-configuration", "attributes": { "format": "SERVER", "environment": { "name": "prod" }, "flags": {} } } }""")] + // Missing environment + [InlineData("""{ "data": { "type": "universal-flag-configuration", "attributes": { "format": "SERVER", "createdAt": "x", "flags": {} } } }""")] + // environment.name is not a string + [InlineData("""{ "data": { "type": "universal-flag-configuration", "attributes": { "format": "SERVER", "createdAt": "x", "environment": { "name": 123 }, "flags": {} } } }""")] + // Missing flags + [InlineData("""{ "data": { "type": "universal-flag-configuration", "attributes": { "format": "SERVER", "createdAt": "x", "environment": { "name": "prod" } } } }""")] + // flags is not an object + [InlineData("""{ "data": { "type": "universal-flag-configuration", "attributes": { "format": "SERVER", "createdAt": "x", "environment": { "name": "prod" }, "flags": [] } } }""")] + public void RejectsInvalidAttributes(string body) + { + UfcConfigurationParser.TryParse(body, out var configuration, out var error).Should().BeFalse(); + + configuration.Should().BeNull(); + error.Should().Be("Expected a Universal Flag Configuration v1 object"); + } + + [Fact] + public void ParsesFlagsFromEnvelope() + { + var body = """ + { "data": { "type": "universal-flag-configuration", + "attributes": { "format": "SERVER", "createdAt": "2025-01-01T00:00:00Z", + "environment": { "name": "production" }, + "flags": { "test-flag": { "key": "test-flag", "enabled": true, "variationType": "BOOLEAN" } } } } } + """; + + UfcConfigurationParser.TryParse(body, out var configuration, out _).Should().BeTrue(); + + configuration!.Flags.Should().NotBeNull(); + configuration!.Flags!.Should().ContainKey("test-flag"); + configuration!.Flags!["test-flag"].Enabled.Should().BeTrue(); + } +} From c7a0d5fee7d3e12b7f07e21e32025d619178db46 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 13 Aug 2026 15:47:50 +0300 Subject: [PATCH 59/86] test(feature-flags): add AgentlessConfigurationSourceTests for poller retry, ETag, gzip, and shutdown --- .../AgentlessConfigurationSourceTests.cs | 284 ++++++++++++++++++ 1 file changed, 284 insertions(+) create mode 100644 tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs new file mode 100644 index 000000000000..935c778b96f4 --- /dev/null +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs @@ -0,0 +1,284 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +#nullable enable + +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Datadog.Trace.Agent; +using Datadog.Trace.FeatureFlags.Agentless; +using Datadog.Trace.FeatureFlags.Rcm.Model; +using Datadog.Trace.TestHelpers.TransportHelpers; +using FluentAssertions; +using Xunit; + +namespace Datadog.Trace.Tests.FeatureFlags; + +public class AgentlessConfigurationSourceTests +{ + private const string Body = """ + { "data": { "type": "universal-flag-configuration", + "attributes": { "format": "SERVER", "createdAt": "2025-01-01T00:00:00Z", + "environment": { "name": "production" }, "flags": {} } } } + """; + + private static readonly Uri Endpoint = new("https://ufc-server.ff-cdn.datadoghq.com/api/v2/feature-flagging/config/rules-based/server"); + + [Fact] + public async Task AppliesConfigurationFromA200() + { + var applied = new List(); + var factory = new TestRequestFactory(uri => new TestApiRequest(uri, responseContent: Body)); + using var source = CreateSource(factory, applied); + + await source.PollAsync(); + + applied.Should().ContainSingle(); + applied[0].Environment!.Name.Should().Be("production"); + factory.RequestsSent.Should().ContainSingle(); + } + + [Fact] + public async Task SendsTheEtagOfTheLastAppliedConfiguration() + { + var applied = new List(); + var factory = new TestRequestFactory( + uri => new TestApiRequest(uri, responseContent: Body, responseHeaders: new() { { "ETag", "\"ufc-v1\"" } })); + using var source = CreateSource(factory, applied); + + await source.PollAsync(); + applied.Should().ContainSingle(); + + // Second poll should send If-None-Match + await source.PollAsync(); + factory.RequestsSent.Should().HaveCount(2); + factory.RequestsSent[1].ExtraHeaders.Should().ContainKey("If-None-Match"); + factory.RequestsSent[1].ExtraHeaders["If-None-Match"].Should().Be("\"ufc-v1\""); + } + + [Fact] + public async Task DoesNotApplyOn304() + { + var applied = new List(); + var factory = new TestRequestFactory( + uri => new TestApiRequest(uri, statusCode: 304, responseContent: "{}")); + using var source = CreateSource(factory, applied); + + await source.PollAsync(); + + applied.Should().BeEmpty(); + } + + [Fact] + public async Task DoesNotApplyOn401() + { + var applied = new List(); + var factory = new TestRequestFactory( + uri => new TestApiRequest(uri, statusCode: 401, responseContent: "Unauthorized")); + using var source = CreateSource(factory, applied); + + await source.PollAsync(); + + applied.Should().BeEmpty(); + } + + [Fact] + public async Task DoesNotApplyOnMalformedPayload() + { + var applied = new List(); + var factory = new TestRequestFactory( + uri => new TestApiRequest(uri, statusCode: 200, responseContent: "not json")); + using var source = CreateSource(factory, applied); + + await source.PollAsync(); + + applied.Should().BeEmpty(); + } + + [Fact] + public async Task DoesNotApplyAfterDisposal() + { + var applied = new List(); + var factory = new TestRequestFactory(uri => new TestApiRequest(uri, responseContent: Body)); + var source = CreateSource(factory, applied); + + // A shutdown mid-poll leaves the response unusable for a state transition. + source.Dispose(); + await source.PollAsync(); + + factory.RequestsSent.Should().ContainSingle(); + applied.Should().BeEmpty(); + } + + [Fact] + public async Task DoesNotApplyWhenDisposedAfterRequestSucceeds() + { + var applied = new List(); + AgentlessConfigurationSource? sourceRef = null; + var factory = new TestRequestFactory(uri => + { + var request = new DisposingApiRequest(uri, Body); + request.Source = sourceRef; + return request; + }); + using var source = CreateSource(factory, applied); + sourceRef = source; + + await source.PollAsync(); + + applied.Should().BeEmpty(); + } + + [Fact] + public async Task RetriesOn500ThenAppliesOnSuccess() + { + var applied = new List(); + var factory = new TestRequestFactory( + uri => new TestApiRequest(uri, statusCode: 500, responseContent: "error"), + uri => new TestApiRequest(uri, responseContent: Body)); + using var source = CreateSource(factory, applied); + + await source.PollAsync(); + + applied.Should().ContainSingle(); + factory.RequestsSent.Should().HaveCount(2); + } + + [Fact] + public async Task RetriesUpToMaxAttemptsOn500() + { + var applied = new List(); + var factory = new TestRequestFactory( + uri => new TestApiRequest(uri, statusCode: 500, responseContent: "error"), + uri => new TestApiRequest(uri, statusCode: 500, responseContent: "error"), + uri => new TestApiRequest(uri, statusCode: 500, responseContent: "error")); + using var source = CreateSource(factory, applied); + + await source.PollAsync(); + + applied.Should().BeEmpty(); + factory.RequestsSent.Should().HaveCount(3); + } + + [Fact] + public async Task DoesNotRetryOn400() + { + var applied = new List(); + var factory = new TestRequestFactory( + uri => new TestApiRequest(uri, statusCode: 400, responseContent: "bad request")); + using var source = CreateSource(factory, applied); + + await source.PollAsync(); + + applied.Should().BeEmpty(); + factory.RequestsSent.Should().ContainSingle(); + } + + [Fact] + public async Task HandlesGzipResponse() + { + var applied = new List(); + var factory = new TestRequestFactory(uri => new GzipApiRequest(uri, Body)); + using var source = CreateSource(factory, applied); + + await source.PollAsync(); + + applied.Should().ContainSingle(); + applied[0].Environment!.Name.Should().Be("production"); + } + + [Fact] + public async Task HandlesNetworkError() + { + var applied = new List(); + var factory = new TestRequestFactory( + uri => new ThrowingApiRequest(uri), + uri => new ThrowingApiRequest(uri), + uri => new ThrowingApiRequest(uri)); + using var source = CreateSource(factory, applied); + + await source.PollAsync(); + + applied.Should().BeEmpty(); + factory.RequestsSent.Should().HaveCount(3); + } + + private static AgentlessConfigurationSource CreateSource(TestRequestFactory factory, List applied) + => new( + Endpoint, + factory, + TimeSpan.FromSeconds(30), + configuration => + { + applied.Add(configuration); + return true; + }, + NoWait); + + private static Task NoWait(TimeSpan delay, CancellationToken cancellationToken) => Task.CompletedTask; + + private class ThrowingApiRequest(Uri endpoint) : TestApiRequest(endpoint) + { + public override Task GetAsync() => throw new IOException("The connection was refused"); + } + + private class GzipApiRequest(Uri endpoint, string body) : TestApiRequest(endpoint) + { + public override Task GetAsync() => Task.FromResult(new GzipApiResponse(body)); + } + + private class GzipApiResponse(string body) : IApiResponse + { + public int StatusCode => 200; + + public long ContentLength => -1; + + public string? ContentTypeHeader => "application/json"; + + public string? ContentEncodingHeader => "gzip"; + + public void Dispose() + { + } + + public string? GetHeader(string headerName) => null; + + public Encoding GetCharsetEncoding() => Encoding.UTF8; + + public ContentEncodingType GetContentEncodingType() => ContentEncodingType.GZip; + + public Task GetStreamAsync() + { + var compressed = new MemoryStream(); + using (var gzip = new GZipStream(compressed, CompressionMode.Compress, leaveOpen: true)) + { + var bytes = Encoding.UTF8.GetBytes(body); + gzip.Write(bytes, 0, bytes.Length); + } + + compressed.Position = 0; + return Task.FromResult(compressed); + } + } + + private class DisposingApiRequest(Uri endpoint, string body) : TestApiRequest(endpoint, responseContent: body) + { + public AgentlessConfigurationSource? Source { get; set; } + + public override Task GetAsync() + { + var response = base.GetAsync(); + // Simulate a shutdown arriving after the request completes but before ApplyAsync. + Source?.Dispose(); + return response; + } + } +} From e084a93f01b63abfb6d88bc45b6efcd3ab0cb42b Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 14 Aug 2026 15:01:41 +0300 Subject: [PATCH 60/86] fix(feature-flags): reject non-string data.type, log failures as errors --- .../Agentless/AgentlessConfigurationSource.cs | 8 ++++---- .../FeatureFlags/Agentless/UfcConfigurationParser.cs | 1 + .../FeatureFlags/UfcConfigurationParserTests.cs | 4 ++++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs index 6d23a7045c31..7ec342a4fc6d 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs @@ -225,7 +225,7 @@ private async Task RunAsync() } catch (Exception ex) { - Log.Debug(ex, "Feature Flags agentless poll failed unexpectedly"); + Log.Error(ex, "Feature Flags agentless poll failed unexpectedly"); } // Fixed delay after completion, so polls never overlap. @@ -375,13 +375,13 @@ private void WarnFailure(in PollResult result, int attempts) switch (result.StatusCode) { case 401 or 403: - Log.Warning("Feature Flags agentless endpoint returned HTTP {StatusCode}; verify endpoint authentication", result.StatusCode!.Value); + Log.Error("Feature Flags agentless endpoint returned HTTP {StatusCode}; verify endpoint authentication", result.StatusCode!.Value); break; case not null: - Log.Warning("Feature Flags agentless endpoint returned HTTP {StatusCode} after {Attempts} attempts", result.StatusCode.Value, attempts); + Log.Error("Feature Flags agentless endpoint returned HTTP {StatusCode} after {Attempts} attempts", result.StatusCode.Value, attempts); break; default: - Log.Warning(result.Error, "Feature Flags agentless request failed after {Attempts} attempts", attempts); + Log.Error(result.Error, "Feature Flags agentless request failed after {Attempts} attempts", attempts); break; } } diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs index 58bbfe2691e9..a078f5f4374d 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs @@ -53,6 +53,7 @@ public static bool TryParse(string? body, [NotNullWhen(true)] out ServerConfigur if (payload is not JObject || payload["data"] is not JObject data + || data["type"]?.Type != JTokenType.String || data["type"]?.Value() != ResourceType) { error = "Expected a JSON:API Universal Flag Configuration resource"; diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/UfcConfigurationParserTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/UfcConfigurationParserTests.cs index 14fc51ab85a7..b57c9568ebcd 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/UfcConfigurationParserTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/UfcConfigurationParserTests.cs @@ -60,6 +60,10 @@ public void RejectsMalformedJson(string? body) [InlineData("""{ "meta": {} }""")] // data is not an object [InlineData("""{ "data": "string" }""")] + // data.type is not a string (object) + [InlineData("""{ "data": { "type": { "nested": true }, "attributes": { "format": "SERVER", "createdAt": "x", "environment": { "name": "prod" }, "flags": {} } } }""")] + // data.type is not a string (array) + [InlineData("""{ "data": { "type": [1, 2], "attributes": { "format": "SERVER", "createdAt": "x", "environment": { "name": "prod" }, "flags": {} } } }""")] public void RejectsInvalidEnvelope(string body) { UfcConfigurationParser.TryParse(body, out var configuration, out var error).Should().BeFalse(); From 1f8f03df5e3f38797f3f7cd434c3002bb7c150db Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 14 Aug 2026 15:15:13 +0300 Subject: [PATCH 61/86] fix(feature-flags): add explicit request timeout race for net461 async WebRequest --- .../Agentless/AgentlessConfigurationSource.cs | 25 +++++++++++++++++++ .../AgentlessConfigurationSourceTests.cs | 1 + 2 files changed, 26 insertions(+) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs index 7ec342a4fc6d..4f2658fda111 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs @@ -44,6 +44,7 @@ internal sealed class AgentlessConfigurationSource : IDisposable private readonly IApiRequestFactory _requestFactory; private readonly Uri _endpoint; private readonly TimeSpan _pollInterval; + private readonly TimeSpan _requestTimeout; private readonly Func _applyConfiguration; private readonly Func _waitAsync; private readonly CancellationTokenSource _shutdown = new(); @@ -61,12 +62,14 @@ internal AgentlessConfigurationSource( Uri endpoint, IApiRequestFactory requestFactory, TimeSpan pollInterval, + TimeSpan requestTimeout, Func applyConfiguration, Func? waitAsync = null) { _endpoint = endpoint; _requestFactory = requestFactory; _pollInterval = pollInterval; + _requestTimeout = requestTimeout; _applyConfiguration = applyConfiguration; _waitAsync = waitAsync ?? Task.Delay; } @@ -94,6 +97,7 @@ internal AgentlessConfigurationSource( endpoint.Uri, CreateRequestFactory(endpoint, settings), settings.PollInterval, + settings.RequestTimeout, applyConfiguration); } @@ -275,7 +279,28 @@ private async Task RequestAsync() request.AddHeader("If-None-Match", etag); } +#if NETCOREAPP + // HttpClient.Timeout applies to async calls, so no explicit race is needed. using var response = await request.GetAsync().ConfigureAwait(false); +#else + // HttpWebRequest.Timeout does not apply to async calls (GetResponseAsync), so we race + // the request against an explicit delay to bound the wait on net461/netstandard2.0. + var getTask = request.GetAsync(); + var timeoutTask = Task.Delay(_requestTimeout); + + if (await Task.WhenAny(getTask, timeoutTask).ConfigureAwait(false) == timeoutTask) + { + // The request is still in flight. Dispose the response when it eventually completes + // (success or fault) so the underlying connection is released. + _ = getTask.ContinueWith( + t => { try { using var r = t.Result; } catch { } }, + TaskContinuationOptions.None); + + return new PollResult(statusCode: null, etag: null, body: null, error: new TimeoutException($"Feature Flags agentless request timed out after {_requestTimeout.TotalSeconds}s")); + } + + using var response = await getTask.ConfigureAwait(false); +#endif // Only a 200 carries configuration; other bodies are never decoded as one. var body = response.StatusCode == 200 ? await ReadBodyAsync(response).ConfigureAwait(false) : null; diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs index 935c778b96f4..e2e39a15acde 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs @@ -216,6 +216,7 @@ private static AgentlessConfigurationSource CreateSource(TestRequestFactory fact Endpoint, factory, TimeSpan.FromSeconds(30), + TimeSpan.FromSeconds(5), configuration => { applied.Add(configuration); From d3b307e5ff771a66ab5c86ceffcd69dc66c4e42d Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 20 Aug 2026 18:18:37 +0300 Subject: [PATCH 62/86] [FeatureFlags] Poll for the current environment instead of the one captured at startup --- .../Agentless/AgentlessConfigurationSource.cs | 66 ++++++++++++++++--- .../AgentlessConfigurationSourceTests.cs | 47 ++++++++++++- 2 files changed, 102 insertions(+), 11 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs index 4f2658fda111..a0bdd1279537 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs @@ -13,6 +13,7 @@ using System.Threading.Tasks; using Datadog.Trace.Agent; using Datadog.Trace.Agent.Transports; +using Datadog.Trace.Configuration; using Datadog.Trace.FeatureFlags.Rcm.Model; using Datadog.Trace.Headers; using Datadog.Trace.Logging; @@ -42,7 +43,7 @@ internal sealed class AgentlessConfigurationSource : IDisposable private static readonly IDatadogLogger Log = DatadogLogging.GetLoggerFor(typeof(AgentlessConfigurationSource)); private readonly IApiRequestFactory _requestFactory; - private readonly Uri _endpoint; + private readonly AgentlessEndpoint _endpoint; private readonly TimeSpan _pollInterval; private readonly TimeSpan _requestTimeout; private readonly Func _applyConfiguration; @@ -52,18 +53,26 @@ internal sealed class AgentlessConfigurationSource : IDisposable // Only ever touched from the poll loop. private readonly HashSet _loggedFailureCategories = new(); + + // Written by the settings-change callback, read by the poll loop. + private string? _environment; + private IDisposable? _environmentSubscription; + + // Only ever touched from the poll loop. private bool _malformedPayloadLogged; private bool _applyFailureLogged; private string? _etag; + private Uri? _etagUri; private int _started; internal AgentlessConfigurationSource( - Uri endpoint, + AgentlessEndpoint endpoint, IApiRequestFactory requestFactory, TimeSpan pollInterval, TimeSpan requestTimeout, Func applyConfiguration, + string? environment = null, Func? waitAsync = null) { _endpoint = endpoint; @@ -71,6 +80,7 @@ internal AgentlessConfigurationSource( _pollInterval = pollInterval; _requestTimeout = requestTimeout; _applyConfiguration = applyConfiguration; + _environment = environment; _waitAsync = waitAsync ?? Task.Delay; } @@ -79,9 +89,12 @@ internal AgentlessConfigurationSource( /// not a URL, or the managed endpoint without an API key. Polling anyway would only produce /// failures every interval. /// - public static AgentlessConfigurationSource? Create(FeatureFlagsSettings settings, Func applyConfiguration) + public static AgentlessConfigurationSource? Create( + FeatureFlagsSettings settings, + TracerSettings.SettingsManager manager, + Func applyConfiguration) { - if (!AgentlessEndpoint.TryCreate(settings.Site, settings.Env, settings.AgentlessBaseUrl, out var endpoint, out var error)) + if (!AgentlessEndpoint.TryCreate(settings.Site, settings.AgentlessBaseUrl, out var endpoint, out var error)) { Log.Error("Feature Flags agentless source is unavailable: {Error}", error); return null; @@ -93,14 +106,34 @@ internal AgentlessConfigurationSource( return null; } - return new AgentlessConfigurationSource( - endpoint.Uri, + var source = new AgentlessConfigurationSource( + endpoint, CreateRequestFactory(endpoint, settings), settings.PollInterval, settings.RequestTimeout, - applyConfiguration); + applyConfiguration, + manager.InitialMutableSettings.Environment); + + // The environment is tracked rather than captured: customers can change it in code while + // the application runs, and flags are targeted per environment. Only the value is stored + // here, so that the poll loop stays the only thing that touches the request state. + source._environmentSubscription = manager.SubscribeToChanges(changes => + { + if (changes.UpdatedMutable is { } mutable) + { + source.UpdateEnvironment(mutable.Environment); + } + }); + + return source; } + /// + /// Records the environment to request configuration for. Applied by the poll loop on its next + /// request, so a change never disturbs a request already in flight. + /// + internal void UpdateEnvironment(string? environment) => Volatile.Write(ref _environment, environment); + /// /// Starts polling. Idempotent. /// @@ -172,6 +205,7 @@ public void Dispose() // from applying its result by the shutdown check in PollAsync. try { + _environmentSubscription?.Dispose(); _shutdown.Cancel(); } catch (Exception ex) @@ -207,6 +241,8 @@ private static ApiWebRequestFactory CreateRequestFactory(AgentlessEndpoint endpo headers.Add(new(TelemetryConstants.ApiKeyHeader, settings.ApiKey!)); } + // The endpoint is only the factory's default: both transports honour the URI passed to + // Create, which is what carries the current environment. #if NETCOREAPP return new HttpClientRequestFactory(endpoint.Uri, headers.ToArray(), timeout: settings.RequestTimeout); #else @@ -273,7 +309,21 @@ private async Task RequestAsync() { try { - var request = _requestFactory.Create(_endpoint); + // The environment is applied per request rather than baked into the endpoint, because + // it can be changed in code after startup. + var uri = _endpoint.BuildRequestUri(Volatile.Read(ref _environment)); + + // An ETag only identifies the configuration served for the URI it came from. Sending it + // against a different environment would earn a 304 and pin the process to the previous + // environment's flags, with no way back. + if (_etagUri is not null && uri != _etagUri) + { + _etag = null; + } + + _etagUri = uri; + + var request = _requestFactory.Create(uri); if (_etag is { } etag) { request.AddHeader("If-None-Match", etag); diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs index e2e39a15acde..a807554c0cc7 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs @@ -30,7 +30,7 @@ public class AgentlessConfigurationSourceTests "environment": { "name": "production" }, "flags": {} } } } """; - private static readonly Uri Endpoint = new("https://ufc-server.ff-cdn.datadoghq.com/api/v2/feature-flagging/config/rules-based/server"); + private const string EndpointUrl = "https://ufc-server.ff-cdn.datadoghq.com/api/v2/feature-flagging/config/rules-based/server"; [Fact] public async Task AppliesConfigurationFromA200() @@ -64,6 +64,37 @@ public async Task SendsTheEtagOfTheLastAppliedConfiguration() factory.RequestsSent[1].ExtraHeaders["If-None-Match"].Should().Be("\"ufc-v1\""); } + [Fact] + public async Task RequestsTheConfiguredEnvironment() + { + var applied = new List(); + var factory = new TestRequestFactory(uri => new TestApiRequest(uri, responseContent: Body)); + using var source = CreateSource(factory, applied, environment: "production"); + + await source.PollAsync(); + + factory.RequestsSent[0].Endpoint.Should().Be(new Uri(EndpointUrl + "?dd_env=production")); + } + + [Fact] + public async Task DropsTheEtagWhenTheEnvironmentChanges() + { + var applied = new List(); + var factory = new TestRequestFactory( + uri => new TestApiRequest(uri, responseContent: Body, responseHeaders: new() { { "ETag", "\"ufc-v1\"" } })); + using var source = CreateSource(factory, applied, environment: "production"); + + await source.PollAsync(); + + // The ETag identifies production's configuration, so it must not be sent against staging: + // a 304 would pin the process to production's flags with no way back. + source.UpdateEnvironment("staging"); + await source.PollAsync(); + + factory.RequestsSent[1].Endpoint.Should().Be(new Uri(EndpointUrl + "?dd_env=staging")); + factory.RequestsSent[1].ExtraHeaders.Should().NotContainKey("If-None-Match"); + } + [Fact] public async Task DoesNotApplyOn304() { @@ -211,9 +242,12 @@ public async Task HandlesNetworkError() factory.RequestsSent.Should().HaveCount(3); } - private static AgentlessConfigurationSource CreateSource(TestRequestFactory factory, List applied) + private static AgentlessConfigurationSource CreateSource( + TestRequestFactory factory, + List applied, + string? environment = null) => new( - Endpoint, + CreateEndpoint(), factory, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(5), @@ -222,8 +256,15 @@ private static AgentlessConfigurationSource CreateSource(TestRequestFactory fact applied.Add(configuration); return true; }, + environment, NoWait); + private static AgentlessEndpoint CreateEndpoint() + { + AgentlessEndpoint.TryCreate("datadoghq.com", baseUrl: null, out var endpoint, out _).Should().BeTrue(); + return endpoint ?? throw new InvalidOperationException("TryCreate reported success without producing an endpoint."); + } + private static Task NoWait(TimeSpan delay, CancellationToken cancellationToken) => Task.CompletedTask; private class ThrowingApiRequest(Uri endpoint) : TestApiRequest(endpoint) From eae179d8abf478ba0821fd97cdd96ecb5702339e Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 26 Aug 2026 16:30:42 +0300 Subject: [PATCH 63/86] [FeatureFlags] Signal agentless poller shutdown with a TaskCompletionSource --- .../Agentless/AgentlessConfigurationSource.cs | 35 +++++++++---------- .../AgentlessConfigurationSourceTests.cs | 3 +- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs index a0bdd1279537..7058d0d01ed4 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs @@ -47,8 +47,11 @@ internal sealed class AgentlessConfigurationSource : IDisposable private readonly TimeSpan _pollInterval; private readonly TimeSpan _requestTimeout; private readonly Func _applyConfiguration; - private readonly Func _waitAsync; - private readonly CancellationTokenSource _shutdown = new(); + private readonly Func _waitAsync; + + // Not a CancellationTokenSource: cancellation throws, and an exception on the shutdown path can + // crash the runtime, so shutdown is signalled by completing a task instead. + private readonly TaskCompletionSource _shutdown = new(TaskCreationOptions.RunContinuationsAsynchronously); private readonly Random _random = new(); // Only ever touched from the poll loop. @@ -73,7 +76,7 @@ internal AgentlessConfigurationSource( TimeSpan requestTimeout, Func applyConfiguration, string? environment = null, - Func? waitAsync = null) + Func? waitAsync = null) { _endpoint = endpoint; _requestFactory = requestFactory; @@ -161,7 +164,7 @@ internal async Task PollAsync() { result = await RequestAsync().ConfigureAwait(false); - if (_shutdown.IsCancellationRequested) + if (_shutdown.Task.IsCompleted) { // A shutdown mid-poll leaves the response unusable for state transitions: keep // last-known-good and the current ETag. @@ -182,13 +185,13 @@ internal async Task PollAsync() await WaitAsync(RetryDelay(attempt)).ConfigureAwait(false); - if (_shutdown.IsCancellationRequested) + if (_shutdown.Task.IsCompleted) { return; } } - if (_shutdown.IsCancellationRequested) + if (_shutdown.Task.IsCompleted) { // A shutdown during the final attempt leaves the response unusable for state // transitions: keep last-known-good and the current ETag. @@ -203,14 +206,15 @@ public void Dispose() // The request in flight is bounded by the request timeout, and the loop is never joined, // so a shutdown does not wait for it. A poll that completes after disposal is prevented // from applying its result by the shutdown check in PollAsync. + _shutdown.TrySetResult(true); + try { _environmentSubscription?.Dispose(); - _shutdown.Cancel(); } catch (Exception ex) { - Log.Debug(ex, "Error cancelling the Feature Flags agentless poll loop"); + Log.Debug(ex, "Error unsubscribing the Feature Flags agentless poll loop from settings changes"); } } @@ -257,7 +261,7 @@ private async Task RunAsync() { Log.Debug("AgentlessConfigurationSource::RunAsync -> Enter"); - while (!_shutdown.IsCancellationRequested) + while (!_shutdown.Task.IsCompleted) { try { @@ -275,17 +279,10 @@ private async Task RunAsync() Log.Debug("AgentlessConfigurationSource::RunAsync -> Exit"); } + // A shutdown ends the wait early. The delay itself is left to expire on its own: it holds no + // thread, and the loop has already exited by the time it does. private async Task WaitAsync(TimeSpan delay) - { - try - { - await _waitAsync(delay, _shutdown.Token).ConfigureAwait(false); - } - catch (OperationCanceledException) - { - // Shutting down - } - } + => await Task.WhenAny(_waitAsync(delay), _shutdown.Task).ConfigureAwait(false); private TimeSpan RetryDelay(int attempt) { diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs index a807554c0cc7..276f28b37251 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs @@ -11,7 +11,6 @@ using System.IO.Compression; using System.Linq; using System.Text; -using System.Threading; using System.Threading.Tasks; using Datadog.Trace.Agent; using Datadog.Trace.FeatureFlags.Agentless; @@ -265,7 +264,7 @@ private static AgentlessEndpoint CreateEndpoint() return endpoint ?? throw new InvalidOperationException("TryCreate reported success without producing an endpoint."); } - private static Task NoWait(TimeSpan delay, CancellationToken cancellationToken) => Task.CompletedTask; + private static Task NoWait(TimeSpan delay) => Task.CompletedTask; private class ThrowingApiRequest(Uri endpoint) : TestApiRequest(endpoint) { From f21deeb6b8c635b46ce606073f97e6136dd555cd Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 26 Aug 2026 16:39:32 +0300 Subject: [PATCH 64/86] [FeatureFlags] Use ThreadSafeRandom.Shared for agentless retry jitter --- .../FeatureFlags/Agentless/AgentlessConfigurationSource.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs index 7058d0d01ed4..b2e5f47bd662 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs @@ -52,7 +52,6 @@ internal sealed class AgentlessConfigurationSource : IDisposable // Not a CancellationTokenSource: cancellation throws, and an exception on the shutdown path can // crash the runtime, so shutdown is signalled by completing a task instead. private readonly TaskCompletionSource _shutdown = new(TaskCreationOptions.RunContinuationsAsynchronously); - private readonly Random _random = new(); // Only ever touched from the poll loop. private readonly HashSet _loggedFailureCategories = new(); @@ -290,11 +289,7 @@ private TimeSpan RetryDelay(int attempt) ? Clamp(_pollInterval.TotalSeconds / 6, FirstRetryMin, FirstRetryMax) : Clamp(_pollInterval.TotalSeconds / 3, SecondRetryMin, SecondRetryMax); - double jitter; - lock (_random) - { - jitter = 1 - RetryJitter + (_random.NextDouble() * RetryJitter * 2); - } + var jitter = 1 - RetryJitter + (ThreadSafeRandom.Shared.NextDouble() * RetryJitter * 2); return TimeSpan.FromSeconds(Math.Max(MinRetryDelay.TotalSeconds, seconds * jitter)); From 8aeefb2633e9ac3eeec2846fec454da30b4e56c3 Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 26 Aug 2026 16:42:08 +0300 Subject: [PATCH 65/86] [FeatureFlags] Log agentless delivery failures as warnings --- .../FeatureFlags/Agentless/AgentlessConfigurationSource.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs index b2e5f47bd662..bcd0d5dafddf 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs @@ -442,13 +442,13 @@ private void WarnFailure(in PollResult result, int attempts) switch (result.StatusCode) { case 401 or 403: - Log.Error("Feature Flags agentless endpoint returned HTTP {StatusCode}; verify endpoint authentication", result.StatusCode!.Value); + Log.Warning("Feature Flags agentless endpoint returned HTTP {StatusCode}; verify endpoint authentication", result.StatusCode!.Value); break; case not null: - Log.Error("Feature Flags agentless endpoint returned HTTP {StatusCode} after {Attempts} attempts", result.StatusCode.Value, attempts); + Log.Warning("Feature Flags agentless endpoint returned HTTP {StatusCode} after {Attempts} attempts", result.StatusCode.Value, attempts); break; default: - Log.Error(result.Error, "Feature Flags agentless request failed after {Attempts} attempts", attempts); + Log.Warning(result.Error, "Feature Flags agentless request failed after {Attempts} attempts", attempts); break; } } From 3640e9d284302a059e9b93f04123a74a3ca610ec Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 26 Aug 2026 16:48:41 +0300 Subject: [PATCH 66/86] [FeatureFlags] Fix stream disposal when reading the agentless response body --- .../Agentless/AgentlessConfigurationSource.cs | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs index bcd0d5dafddf..68e358202fa5 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs @@ -356,23 +356,23 @@ private async Task RequestAsync() private async Task ReadBodyAsync(IApiResponse response) { - var stream = await response.GetStreamAsync().ConfigureAwait(false); - GZipStream? decompressed = null; - - try - { - if (response.GetContentEncodingType() == ContentEncodingType.GZip) - { - decompressed = new GZipStream(stream, CompressionMode.Decompress); - } - - using var reader = new StreamReader(decompressed ?? stream, response.GetCharsetEncoding()); - return await reader.ReadToEndAsync().ConfigureAwait(false); - } - finally - { - decompressed?.Dispose(); - } + using var stream = await response.GetStreamAsync().ConfigureAwait(false); + + using var decompressed = + response.GetContentEncodingType() == ContentEncodingType.GZip + ? new GZipStream(stream, CompressionMode.Decompress, leaveOpen: true) + : null; + + // Every parameter has to be given to reach leaveOpen. A byte order mark is not expected, and + // letting one be detected would override the encoding the response declared. + using var reader = new StreamReader( + decompressed ?? stream, + response.GetCharsetEncoding(), + detectEncodingFromByteOrderMarks: false, + bufferSize: 1024, // the default + leaveOpen: true); + + return await reader.ReadToEndAsync().ConfigureAwait(false); } private Task ApplyAsync(PollResult result) From 7f9b72be924065a0212ba6c289eb2d4d7f7b135f Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 26 Aug 2026 16:52:31 +0300 Subject: [PATCH 67/86] [FeatureFlags] Make the agentless apply step synchronous and pass PollResult by in --- .../Agentless/AgentlessConfigurationSource.cs | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs index 68e358202fa5..1cffba761f54 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs @@ -170,7 +170,7 @@ internal async Task PollAsync() return; } - if (!IsRetryable(result)) + if (!IsRetryable(in result)) { break; } @@ -178,7 +178,7 @@ internal async Task PollAsync() if (attempt == MaxAttempts) { // Every attempt failed in a retryable way. Last-known-good stays in place. - WarnFailure(result, MaxAttempts); + WarnFailure(in result, MaxAttempts); return; } @@ -197,7 +197,7 @@ internal async Task PollAsync() return; } - await ApplyAsync(result).ConfigureAwait(false); + Apply(in result); } public void Dispose() @@ -375,19 +375,19 @@ private async Task ReadBodyAsync(IApiResponse response) return await reader.ReadToEndAsync().ConfigureAwait(false); } - private Task ApplyAsync(PollResult result) + private void Apply(in PollResult result) { switch (result.StatusCode) { case 304: // Nothing changed, and the ETag stays as it is. - return Task.CompletedTask; + return; case 401 or 403: - WarnFailure(result, attempts: 1); - return Task.CompletedTask; + WarnFailure(in result, attempts: 1); + return; case not 200: - WarnFailure(result, attempts: 1); - return Task.CompletedTask; + WarnFailure(in result, attempts: 1); + return; } if (!UfcConfigurationParser.TryParse(result.Body, out var configuration, out var error)) @@ -398,7 +398,7 @@ private Task ApplyAsync(PollResult result) Log.Error("Feature Flags agentless endpoint returned an unusable payload: {Error}", error); } - return Task.CompletedTask; + return; } if (!_applyConfiguration(configuration)) @@ -409,7 +409,7 @@ private Task ApplyAsync(PollResult result) Log.Warning("Feature Flags agentless configuration could not be applied"); } - return Task.CompletedTask; + return; } // The ETag advances only once parsing and applying have both succeeded. Advancing on @@ -417,8 +417,6 @@ private Task ApplyAsync(PollResult result) // answer 304, pinning the process to stale configuration with no way back. var newEtag = result.ETag?.Trim(); _etag = StringUtil.IsNullOrEmpty(newEtag) ? null : newEtag; - - return Task.CompletedTask; } /// From c01d3f2fd5dff3affac0eafeae8ae1ce0cb8186f Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 26 Aug 2026 16:53:54 +0300 Subject: [PATCH 68/86] [FeatureFlags] Start the agentless poll loop with Task.Run --- .../FeatureFlags/Agentless/AgentlessConfigurationSource.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs index 1cffba761f54..cf3b18ee6040 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs @@ -146,10 +146,9 @@ public void Start() return; } - // Deliberately not wrapped in Task.Run: this is called from provider initialization, which - // is waiting for the first configuration, so the first request should go out on the calling - // thread rather than queue behind whatever else is on the thread pool. - _ = RunAsync().ContinueWith(t => Log.Error(t.Exception, "Feature Flags agentless poll loop failed"), TaskContinuationOptions.OnlyOnFaulted); + // The loop runs on the thread pool, so nothing of it happens on the caller's thread. Nothing + // ever awaits it either, so a fault is observed here or not at all. + _ = Task.Run(RunAsync).ContinueWith(t => Log.Error(t.Exception, "Feature Flags agentless poll loop failed"), TaskContinuationOptions.OnlyOnFaulted); } /// From 0610bea7c8ffdba3ec3c1f6da57efeef94370431 Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 26 Aug 2026 17:01:55 +0300 Subject: [PATCH 69/86] [FeatureFlags] Rebuild the agentless request URI only when the environment changes --- .../Agentless/AgentlessConfigurationSource.cs | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs index cf3b18ee6040..f8c0ced5886b 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs @@ -56,8 +56,9 @@ internal sealed class AgentlessConfigurationSource : IDisposable // Only ever touched from the poll loop. private readonly HashSet _loggedFailureCategories = new(); - // Written by the settings-change callback, read by the poll loop. - private string? _environment; + // Written by the settings-change callback, read by the poll loop. The URI is stored rather than + // the environment it carries, so it is only built when the environment changes. + private Uri _requestUri; private IDisposable? _environmentSubscription; // Only ever touched from the poll loop. @@ -82,7 +83,7 @@ internal AgentlessConfigurationSource( _pollInterval = pollInterval; _requestTimeout = requestTimeout; _applyConfiguration = applyConfiguration; - _environment = environment; + _requestUri = endpoint.BuildRequestUri(environment); _waitAsync = waitAsync ?? Task.Delay; } @@ -117,8 +118,8 @@ internal AgentlessConfigurationSource( manager.InitialMutableSettings.Environment); // The environment is tracked rather than captured: customers can change it in code while - // the application runs, and flags are targeted per environment. Only the value is stored - // here, so that the poll loop stays the only thing that touches the request state. + // the application runs, and flags are targeted per environment. Only the request URI is + // stored here, so that the poll loop stays the only thing that touches the request state. source._environmentSubscription = manager.SubscribeToChanges(changes => { if (changes.UpdatedMutable is { } mutable) @@ -131,10 +132,11 @@ internal AgentlessConfigurationSource( } /// - /// Records the environment to request configuration for. Applied by the poll loop on its next - /// request, so a change never disturbs a request already in flight. + /// Records the environment to request configuration for, as the URI that carries it. Picked up + /// by the poll loop on its next request, so a change never disturbs a request already in flight. /// - internal void UpdateEnvironment(string? environment) => Volatile.Write(ref _environment, environment); + internal void UpdateEnvironment(string? environment) + => Volatile.Write(ref _requestUri, _endpoint.BuildRequestUri(environment)); /// /// Starts polling. Idempotent. @@ -300,9 +302,9 @@ private async Task RequestAsync() { try { - // The environment is applied per request rather than baked into the endpoint, because - // it can be changed in code after startup. - var uri = _endpoint.BuildRequestUri(Volatile.Read(ref _environment)); + // Read per request rather than captured, because the environment it carries can be + // changed in code after startup. + var uri = Volatile.Read(ref _requestUri); // An ETag only identifies the configuration served for the URI it came from. Sending it // against a different environment would earn a 304 and pin the process to the previous From c3a452b82b971c13916e5e17c43f6bd3a64684ec Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 26 Aug 2026 17:13:44 +0300 Subject: [PATCH 70/86] [FeatureFlags] Parse the agentless payload straight from the response stream --- .../Agentless/AgentlessConfigurationSource.cs | 69 +++++++++++-------- .../Agentless/UfcConfigurationParser.cs | 11 ++- .../UfcConfigurationParserTests.cs | 18 +++-- 3 files changed, 57 insertions(+), 41 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs index f8c0ced5886b..058d06e9d98f 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs @@ -339,43 +339,50 @@ private async Task RequestAsync() t => { try { using var r = t.Result; } catch { } }, TaskContinuationOptions.None); - return new PollResult(statusCode: null, etag: null, body: null, error: new TimeoutException($"Feature Flags agentless request timed out after {_requestTimeout.TotalSeconds}s")); + return new PollResult(statusCode: null, etag: null, configuration: null, parseError: null, error: new TimeoutException($"Feature Flags agentless request timed out after {_requestTimeout.TotalSeconds}s")); } using var response = await getTask.ConfigureAwait(false); #endif - // Only a 200 carries configuration; other bodies are never decoded as one. - var body = response.StatusCode == 200 ? await ReadBodyAsync(response).ConfigureAwait(false) : null; - return new PollResult(response.StatusCode, response.GetHeader("ETag"), body, error: null); + // Only a 200 carries configuration; other bodies are never decoded as one. The payload + // is parsed here, while the response is still open, so it never has to be held as a + // string. A payload that does not parse is reported, not thrown: it is not retryable. + ServerConfiguration? configuration = null; + string? parseError = null; + + if (response.StatusCode == 200) + { + using var stream = await response.GetStreamAsync().ConfigureAwait(false); + + using var decompressed = + response.GetContentEncodingType() == ContentEncodingType.GZip + ? new GZipStream(stream, CompressionMode.Decompress, leaveOpen: true) + : null; + + // Every parameter has to be given to reach leaveOpen. A byte order mark is not + // expected, and letting one be detected would override the declared encoding. + using var reader = new StreamReader( + decompressed ?? stream, + response.GetCharsetEncoding(), + detectEncodingFromByteOrderMarks: false, + bufferSize: 1024, // the default + leaveOpen: true); + + if (UfcConfigurationParser.TryParse(reader, out var parsed, out parseError)) + { + configuration = parsed; + } + } + + return new PollResult(response.StatusCode, response.GetHeader("ETag"), configuration, parseError, error: null); } catch (Exception ex) { - return new PollResult(statusCode: null, etag: null, body: null, error: ex); + return new PollResult(statusCode: null, etag: null, configuration: null, parseError: null, error: ex); } } - private async Task ReadBodyAsync(IApiResponse response) - { - using var stream = await response.GetStreamAsync().ConfigureAwait(false); - - using var decompressed = - response.GetContentEncodingType() == ContentEncodingType.GZip - ? new GZipStream(stream, CompressionMode.Decompress, leaveOpen: true) - : null; - - // Every parameter has to be given to reach leaveOpen. A byte order mark is not expected, and - // letting one be detected would override the encoding the response declared. - using var reader = new StreamReader( - decompressed ?? stream, - response.GetCharsetEncoding(), - detectEncodingFromByteOrderMarks: false, - bufferSize: 1024, // the default - leaveOpen: true); - - return await reader.ReadToEndAsync().ConfigureAwait(false); - } - private void Apply(in PollResult result) { switch (result.StatusCode) @@ -391,12 +398,12 @@ private void Apply(in PollResult result) return; } - if (!UfcConfigurationParser.TryParse(result.Body, out var configuration, out var error)) + if (result.Configuration is not { } configuration) { if (!_malformedPayloadLogged) { _malformedPayloadLogged = true; - Log.Error("Feature Flags agentless endpoint returned an unusable payload: {Error}", error); + Log.Error("Feature Flags agentless endpoint returned an unusable payload: {Error}", result.ParseError); } return; @@ -452,13 +459,15 @@ private void WarnFailure(in PollResult result, int attempts) } } - internal readonly struct PollResult(int? statusCode, string? etag, string? body, Exception? error) + internal readonly struct PollResult(int? statusCode, string? etag, ServerConfiguration? configuration, string? parseError, Exception? error) { public int? StatusCode { get; } = statusCode; public string? ETag { get; } = etag; - public string? Body { get; } = body; + public ServerConfiguration? Configuration { get; } = configuration; + + public string? ParseError { get; } = parseError; public Exception? Error { get; } = error; } diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs index a078f5f4374d..50e1fd6fa565 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs @@ -26,11 +26,11 @@ internal static class UfcConfigurationParser /// which is the document the evaluator consumes. A raw UFC document is rejected, including from /// a custom endpoint, so that every source agrees on one wire format. /// - /// The response body. + /// The response body. Read straight from the response, so it never has to be held as a string. /// The parsed configuration. /// Why the payload was rejected. /// true when the payload matches the contract. - public static bool TryParse(string? body, [NotNullWhen(true)] out ServerConfiguration? configuration, out string? error) + public static bool TryParse(TextReader body, [NotNullWhen(true)] out ServerConfiguration? configuration, out string? error) { configuration = null; error = null; @@ -38,11 +38,10 @@ public static bool TryParse(string? body, [NotNullWhen(true)] out ServerConfigur JToken payload; try { - using var stringReader = new StringReader(body ?? string.Empty); - // Timestamps stay strings: the model carries createdAt verbatim, and letting Newtonsoft - // turn it into a date would also make the type check below fail. - using var jsonReader = new JsonTextReader(stringReader) { DateParseHandling = DateParseHandling.None }; + // turn it into a date would also make the type check below fail. The reader belongs to + // the caller, which owns the response it came from. + using var jsonReader = new JsonTextReader(body) { DateParseHandling = DateParseHandling.None, CloseInput = false }; payload = JToken.ReadFrom(jsonReader); } catch (Exception) diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/UfcConfigurationParserTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/UfcConfigurationParserTests.cs index b57c9568ebcd..cfdf5f85adf9 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/UfcConfigurationParserTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/UfcConfigurationParserTests.cs @@ -6,6 +6,7 @@ #nullable enable using System.Collections.Generic; +using System.IO; using Datadog.Trace.FeatureFlags.Agentless; using Datadog.Trace.FeatureFlags.Rcm.Model; using FluentAssertions; @@ -29,7 +30,7 @@ public class UfcConfigurationParserTests [Fact] public void ParsesValidEnvelope() { - UfcConfigurationParser.TryParse(ValidEnvelope, out var configuration, out var error) + Parse(ValidEnvelope, out var configuration, out var error) .Should().BeTrue(); error.Should().BeNull(); @@ -45,7 +46,7 @@ public void ParsesValidEnvelope() [InlineData("{ \"data\": ")] public void RejectsMalformedJson(string? body) { - UfcConfigurationParser.TryParse(body, out var configuration, out var error).Should().BeFalse(); + Parse(body, out var configuration, out var error).Should().BeFalse(); configuration.Should().BeNull(); error.Should().Be("Malformed UFC payload"); @@ -66,7 +67,7 @@ public void RejectsMalformedJson(string? body) [InlineData("""{ "data": { "type": [1, 2], "attributes": { "format": "SERVER", "createdAt": "x", "environment": { "name": "prod" }, "flags": {} } } }""")] public void RejectsInvalidEnvelope(string body) { - UfcConfigurationParser.TryParse(body, out var configuration, out var error).Should().BeFalse(); + Parse(body, out var configuration, out var error).Should().BeFalse(); configuration.Should().BeNull(); error.Should().Be("Expected a JSON:API Universal Flag Configuration resource"); @@ -87,7 +88,7 @@ public void RejectsInvalidEnvelope(string body) [InlineData("""{ "data": { "type": "universal-flag-configuration", "attributes": { "format": "SERVER", "createdAt": "x", "environment": { "name": "prod" }, "flags": [] } } }""")] public void RejectsInvalidAttributes(string body) { - UfcConfigurationParser.TryParse(body, out var configuration, out var error).Should().BeFalse(); + Parse(body, out var configuration, out var error).Should().BeFalse(); configuration.Should().BeNull(); error.Should().Be("Expected a Universal Flag Configuration v1 object"); @@ -103,10 +104,17 @@ public void ParsesFlagsFromEnvelope() "flags": { "test-flag": { "key": "test-flag", "enabled": true, "variationType": "BOOLEAN" } } } } } """; - UfcConfigurationParser.TryParse(body, out var configuration, out _).Should().BeTrue(); + Parse(body, out var configuration, out _).Should().BeTrue(); configuration!.Flags.Should().NotBeNull(); configuration!.Flags!.Should().ContainKey("test-flag"); configuration!.Flags!["test-flag"].Enabled.Should().BeTrue(); } + + // The parser reads the response stream directly, so a body under test is handed to it as a reader. + private static bool Parse(string? body, out ServerConfiguration? configuration, out string? error) + { + using var reader = new StringReader(body ?? string.Empty); + return UfcConfigurationParser.TryParse(reader, out configuration, out error); + } } From 1f2d697d128bc313b67dd5aff7e707cf4bc3c370 Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 26 Aug 2026 17:27:24 +0300 Subject: [PATCH 71/86] [FeatureFlags] Deserialize the UFC envelope without building a JSON tree --- .../Agentless/UfcConfigurationParser.cs | 149 ++++++++++++++---- .../Rcm/Model/FlagCollectionJsonConverter.cs | 9 ++ .../UfcConfigurationParserTests.cs | 16 +- 3 files changed, 140 insertions(+), 34 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs index 50e1fd6fa565..b03f17141196 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/UfcConfigurationParser.cs @@ -10,7 +10,6 @@ using System.IO; using Datadog.Trace.FeatureFlags.Rcm.Model; using Datadog.Trace.Vendors.Newtonsoft.Json; -using Datadog.Trace.Vendors.Newtonsoft.Json.Linq; namespace Datadog.Trace.FeatureFlags.Agentless; @@ -21,10 +20,19 @@ internal static class UfcConfigurationParser { private const string ResourceType = "universal-flag-configuration"; + private const string MalformedError = "Malformed UFC payload"; + private const string ResourceError = "Expected a JSON:API Universal Flag Configuration resource"; + private const string AttributesError = "Expected a Universal Flag Configuration v1 object"; + /// /// Validates a JSON:API Universal Flag Configuration response and returns data.attributes, /// which is the document the evaluator consumes. A raw UFC document is rejected, including from /// a custom endpoint, so that every source agrees on one wire format. + /// + /// The envelope is walked with the reader rather than loaded into a JSON tree, and + /// data.attributes is deserialized in place, so the payload is read exactly once and no + /// copy of it is ever held. + /// /// /// The response body. Read straight from the response, so it never has to be held as a string. /// The parsed configuration. @@ -35,56 +43,133 @@ public static bool TryParse(TextReader body, [NotNullWhen(true)] out ServerConfi configuration = null; error = null; - JToken payload; + var sawData = false; + string? resourceType = null; + ServerConfiguration? attributes = null; + try { // Timestamps stay strings: the model carries createdAt verbatim, and letting Newtonsoft // turn it into a date would also make the type check below fail. The reader belongs to // the caller, which owns the response it came from. - using var jsonReader = new JsonTextReader(body) { DateParseHandling = DateParseHandling.None, CloseInput = false }; - payload = JToken.ReadFrom(jsonReader); + using var reader = new JsonTextReader(body) { DateParseHandling = DateParseHandling.None, CloseInput = false }; + var serializer = new JsonSerializer { DateParseHandling = DateParseHandling.None }; + + if (!reader.Read()) + { + // Nothing at all, so there is no document to judge against the contract. + error = MalformedError; + return false; + } + + if (reader.TokenType != JsonToken.StartObject) + { + error = ResourceError; + return false; + } + + while (reader.Read() && reader.TokenType == JsonToken.PropertyName) + { + if ((string?)reader.Value != "data") + { + reader.Skip(); + continue; + } + + sawData = true; + + if (!reader.Read()) + { + // The document ended where the resource should have been. + error = MalformedError; + return false; + } + + if (reader.TokenType != JsonToken.StartObject) + { + error = ResourceError; + return false; + } + + while (reader.Read() && reader.TokenType == JsonToken.PropertyName) + { + switch ((string?)reader.Value) + { + case "type": + if (!reader.Read()) + { + error = MalformedError; + return false; + } + + // A type that is not a string cannot identify the resource. Checked on + // the token, because a number would otherwise be read as its digits. + if (reader.TokenType != JsonToken.String) + { + error = ResourceError; + return false; + } + + resourceType = (string?)reader.Value; + break; + + case "attributes": + if (!reader.Read()) + { + error = MalformedError; + return false; + } + + if (reader.TokenType != JsonToken.StartObject) + { + error = AttributesError; + return false; + } + + attributes = serializer.Deserialize(reader); + break; + + default: + reader.Skip(); + break; + } + } + } + + // A document that ends before the root object closes was truncated in transit, whatever + // was found in it up to that point. + if (reader.TokenType != JsonToken.EndObject) + { + error = MalformedError; + return false; + } } catch (Exception) { - error = "Malformed UFC payload"; + error = MalformedError; return false; } - if (payload is not JObject - || payload["data"] is not JObject data - || data["type"]?.Type != JTokenType.String - || data["type"]?.Value() != ResourceType) + if (!sawData || resourceType != ResourceType) { - error = "Expected a JSON:API Universal Flag Configuration resource"; + error = ResourceError; return false; } - if (data["attributes"] is not JObject attributes - || attributes["format"]?.Type != JTokenType.String - || attributes["createdAt"]?.Type != JTokenType.String - || attributes["environment"] is not JObject environment - || environment["name"]?.Type != JTokenType.String - || attributes["flags"] is not JObject) - { - error = "Expected a Universal Flag Configuration v1 object"; - return false; - } - - try - { - configuration = attributes.ToObject(); - } - catch (Exception) - { - configuration = null; - } - - if (configuration is null) + // Every member of the v1 contract has to be there. A member of the wrong shape arrives as + // null, because the flag collection rejects anything that is not an object and Newtonsoft + // leaves a member it cannot convert unset. + if (attributes is null + || attributes.Format is null + || attributes.CreatedAt is null + || attributes.Environment?.Name is null + || attributes.Flags is null) { - error = "Expected a Universal Flag Configuration v1 object"; + error = AttributesError; return false; } + configuration = attributes; return true; } } diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Rcm/Model/FlagCollectionJsonConverter.cs b/tracer/src/Datadog.Trace/FeatureFlags/Rcm/Model/FlagCollectionJsonConverter.cs index 87a4a8937986..101818093e56 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Rcm/Model/FlagCollectionJsonConverter.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Rcm/Model/FlagCollectionJsonConverter.cs @@ -25,6 +25,15 @@ internal sealed class FlagCollectionJsonConverter : JsonConverter Date: Wed, 26 Aug 2026 17:31:53 +0300 Subject: [PATCH 72/86] [FeatureFlags] Subscribe to settings changes in the agentless constructor --- .../Agentless/AgentlessConfigurationSource.cs | 40 ++++++++++--------- .../AgentlessConfigurationSourceTests.cs | 2 +- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs index 058d06e9d98f..35f966af1c4e 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs @@ -56,10 +56,11 @@ internal sealed class AgentlessConfigurationSource : IDisposable // Only ever touched from the poll loop. private readonly HashSet _loggedFailureCategories = new(); + private readonly IDisposable? _environmentSubscription; + // Written by the settings-change callback, read by the poll loop. The URI is stored rather than // the environment it carries, so it is only built when the environment changes. private Uri _requestUri; - private IDisposable? _environmentSubscription; // Only ever touched from the poll loop. private bool _malformedPayloadLogged; @@ -76,6 +77,7 @@ internal AgentlessConfigurationSource( TimeSpan requestTimeout, Func applyConfiguration, string? environment = null, + TracerSettings.SettingsManager? settingsManager = null, Func? waitAsync = null) { _endpoint = endpoint; @@ -85,6 +87,17 @@ internal AgentlessConfigurationSource( _applyConfiguration = applyConfiguration; _requestUri = endpoint.BuildRequestUri(environment); _waitAsync = waitAsync ?? Task.Delay; + + // Subscribed last, so every field the callback touches is already set. The environment is + // tracked rather than captured: customers can change it in code while the application runs, + // and flags are targeted per environment. + _environmentSubscription = settingsManager?.SubscribeToChanges(changes => + { + if (changes.UpdatedMutable is { } mutable) + { + UpdateEnvironment(mutable.Environment); + } + }); } /// @@ -109,26 +122,14 @@ internal AgentlessConfigurationSource( return null; } - var source = new AgentlessConfigurationSource( + return new AgentlessConfigurationSource( endpoint, CreateRequestFactory(endpoint, settings), settings.PollInterval, settings.RequestTimeout, applyConfiguration, - manager.InitialMutableSettings.Environment); - - // The environment is tracked rather than captured: customers can change it in code while - // the application runs, and flags are targeted per environment. Only the request URI is - // stored here, so that the poll loop stays the only thing that touches the request state. - source._environmentSubscription = manager.SubscribeToChanges(changes => - { - if (changes.UpdatedMutable is { } mutable) - { - source.UpdateEnvironment(mutable.Environment); - } - }); - - return source; + manager.InitialMutableSettings.Environment, + manager); } /// @@ -199,6 +200,10 @@ internal async Task PollAsync() } Apply(in result); + + // A failure with no status code never reached the endpoint, so it is worth another attempt. + static bool IsRetryable(in PollResult result) + => result.StatusCode is not { } status || status is 408 or 429 or (>= 500 and <= 599); } public void Dispose() @@ -254,9 +259,6 @@ private static ApiWebRequestFactory CreateRequestFactory(AgentlessEndpoint endpo #endif } - private static bool IsRetryable(in PollResult result) - => result.StatusCode is not { } status || status is 408 or 429 or (>= 500 and <= 599); - private async Task RunAsync() { Log.Debug("AgentlessConfigurationSource::RunAsync -> Enter"); diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs index 276f28b37251..b87daf911085 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs @@ -256,7 +256,7 @@ private static AgentlessConfigurationSource CreateSource( return true; }, environment, - NoWait); + waitAsync: NoWait); private static AgentlessEndpoint CreateEndpoint() { From 2edc435bbd420ae0d51cc6f4ebb83d2dc8d208a3 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 27 Aug 2026 14:22:33 +0300 Subject: [PATCH 73/86] [FeatureFlags] Let the HTTP abstraction own the agentless request timeout --- .../Agentless/AgentlessConfigurationSource.cs | 25 ------------------- .../AgentlessConfigurationSourceTests.cs | 1 - 2 files changed, 26 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs index 35f966af1c4e..d42449987fdb 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs @@ -45,7 +45,6 @@ internal sealed class AgentlessConfigurationSource : IDisposable private readonly IApiRequestFactory _requestFactory; private readonly AgentlessEndpoint _endpoint; private readonly TimeSpan _pollInterval; - private readonly TimeSpan _requestTimeout; private readonly Func _applyConfiguration; private readonly Func _waitAsync; @@ -74,7 +73,6 @@ internal AgentlessConfigurationSource( AgentlessEndpoint endpoint, IApiRequestFactory requestFactory, TimeSpan pollInterval, - TimeSpan requestTimeout, Func applyConfiguration, string? environment = null, TracerSettings.SettingsManager? settingsManager = null, @@ -83,7 +81,6 @@ internal AgentlessConfigurationSource( _endpoint = endpoint; _requestFactory = requestFactory; _pollInterval = pollInterval; - _requestTimeout = requestTimeout; _applyConfiguration = applyConfiguration; _requestUri = endpoint.BuildRequestUri(environment); _waitAsync = waitAsync ?? Task.Delay; @@ -126,7 +123,6 @@ internal AgentlessConfigurationSource( endpoint, CreateRequestFactory(endpoint, settings), settings.PollInterval, - settings.RequestTimeout, applyConfiguration, manager.InitialMutableSettings.Environment, manager); @@ -324,28 +320,7 @@ private async Task RequestAsync() request.AddHeader("If-None-Match", etag); } -#if NETCOREAPP - // HttpClient.Timeout applies to async calls, so no explicit race is needed. using var response = await request.GetAsync().ConfigureAwait(false); -#else - // HttpWebRequest.Timeout does not apply to async calls (GetResponseAsync), so we race - // the request against an explicit delay to bound the wait on net461/netstandard2.0. - var getTask = request.GetAsync(); - var timeoutTask = Task.Delay(_requestTimeout); - - if (await Task.WhenAny(getTask, timeoutTask).ConfigureAwait(false) == timeoutTask) - { - // The request is still in flight. Dispose the response when it eventually completes - // (success or fault) so the underlying connection is released. - _ = getTask.ContinueWith( - t => { try { using var r = t.Result; } catch { } }, - TaskContinuationOptions.None); - - return new PollResult(statusCode: null, etag: null, configuration: null, parseError: null, error: new TimeoutException($"Feature Flags agentless request timed out after {_requestTimeout.TotalSeconds}s")); - } - - using var response = await getTask.ConfigureAwait(false); -#endif // Only a 200 carries configuration; other bodies are never decoded as one. The payload // is parsed here, while the response is still open, so it never has to be held as a diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs index b87daf911085..c65b3f466c55 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/AgentlessConfigurationSourceTests.cs @@ -249,7 +249,6 @@ private static AgentlessConfigurationSource CreateSource( CreateEndpoint(), factory, TimeSpan.FromSeconds(30), - TimeSpan.FromSeconds(5), configuration => { applied.Add(configuration); From d72f107eab7432f52cb5a6e50377eee018dce634 Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 28 Aug 2026 09:31:03 +0300 Subject: [PATCH 74/86] [FeatureFlags] Signal initialization cancellation with a TaskCompletionSource --- .../FeatureFlags/FeatureFlagsModule.cs | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs index 12f4b7ce0eee..ed4160d24ae7 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs @@ -213,23 +213,22 @@ internal async Task InitializeAsync(CancellationToken cancellationToken) throw new FeatureFlagsDeliveryUnavailableException(deliveryUnavailableReason); } - using var timeoutCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); - var timeout = Task.Delay(_settings.InitializationTimeout, timeoutCancellation.Token); - var completed = await Task.WhenAny(_firstConfigReceived.Task, timeout).ConfigureAwait(false); + // Cancellation is signalled by completing a task: cancelling a token source throws, and + // an exception on this path can crash buggy runtimes. + var cancelled = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + using var registration = cancellationToken.Register(() => cancelled.TrySetResult(true)); - // Stop the timer, otherwise it holds a callback for the whole initialization timeout. - timeoutCancellation.Cancel(); + var timeout = Task.Delay(_settings.InitializationTimeout); + var completed = await Task.WhenAny(_firstConfigReceived.Task, timeout, cancelled.Task).ConfigureAwait(false); - if (completed != timeout) + if (completed == timeout) { - return; + // Evaluations keep returning the caller's default with PROVIDER_NOT_READY until + // configuration lands, which promotes the provider then. + Log.Warning( + "Feature Flags configuration did not arrive within {TimeoutMs}ms. Evaluations use their default values until it does.", + _settings.InitializationTimeout.TotalMilliseconds); } - - // Evaluations keep returning the caller's default with PROVIDER_NOT_READY until - // configuration lands, which promotes the provider then. - Log.Warning( - "Feature Flags configuration did not arrive within {TimeoutMs}ms. Evaluations use their default values until it does.", - _settings.InitializationTimeout.TotalMilliseconds); } internal void RegisterOnNewConfigEventHandler(Action? onNewConfig) From 651898131df13a132e65451e58c8c371b52d799f Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 28 Aug 2026 16:32:36 +0300 Subject: [PATCH 75/86] [FeatureFlags] Trigger system-tests base image build From 9d9c452aca0b86172918adf23c438073b38fe3c4 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 10 Sep 2026 11:53:12 +0300 Subject: [PATCH 76/86] [FeatureFlags] Skip the state lock once activation has happened --- .../Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs index ed4160d24ae7..c9a31f22e9ee 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs @@ -135,6 +135,14 @@ public void Dispose() /// internal void Activate() { + // Every evaluation calls this, so the steady state must not take the lock. The flag only + // ever goes false to true, so a stale read costs one lock acquisition and nothing else: + // the check inside the lock is what decides. + if (Volatile.Read(ref _activated)) + { + return; + } + AgentlessConfigurationSource? sourceToStart = null; lock (_stateLock) @@ -345,7 +353,7 @@ private void ReportExposure(in ExposureEvent exposure) // Created on first use because most applications never evaluate a flag, and under the lock // because the evaluation path races disposal. Only the very first exposure takes the lock: - // afterwards the field is read directly, keeping the evaluation path lock-free. Internal so + // afterwards the field is read directly, keeping the exposure path lock-free. Internal so // tests can assert the disposal behaviour without starting a send loop. internal ExposureApi? GetExposureApi() { From cefe935ed676f55d74b055429740c20f4e8663e2 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 10 Sep 2026 12:12:25 +0300 Subject: [PATCH 77/86] [FeatureFlags] Document that initialization blocks the caller until the timeout --- tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs index c9a31f22e9ee..c0ccd2223881 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs @@ -190,6 +190,12 @@ internal void Activate() /// when no source could start at all, /// which is permanent for the life of the process and must not be reported as a ready provider. /// + /// + /// The wait ends only when a configuration arrives, so a service with no flag configuration + /// waits the whole timeout. The application is blocked for that long, because OpenFeature + /// awaits this from SetProviderAsync, so the timeout has to stay below whatever budget + /// the application's readiness probe allows. + /// /// internal async Task InitializeAsync(CancellationToken cancellationToken) { From 73cce16164012e7864b90debe2d13ac6390c513a Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 10 Sep 2026 12:16:20 +0300 Subject: [PATCH 78/86] [FeatureFlags] Keep a throwing config handler from holding back the agentless ETag --- .../FeatureFlags/FeatureFlagsModule.cs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs index c0ccd2223881..e4a805526ac9 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs @@ -269,14 +269,27 @@ internal bool ApplyConfiguration(ServerConfiguration configuration) { Interlocked.Exchange(ref _evaluator, new FeatureFlagsEvaluator(ReportExposure, configuration, _spanEnrichmentEnabled)); _firstConfigReceived.TrySetResult(true); - _onNewConfigEventHander?.Invoke(); - return true; } catch (Exception ex) { Log.Warning(ex, "FeatureFlagsModule::ApplyConfiguration -> Error applying configuration"); return false; } + + // The handler comes from application code, and the agentless source reads the return value + // to decide whether to advance its ETag. Reporting a failed apply because a handler threw + // would make every later poll re-download the whole payload instead of getting a 304, so + // the configuration is already applied by this point and the handler cannot change that. + try + { + _onNewConfigEventHander?.Invoke(); + } + catch (Exception ex) + { + Log.Warning(ex, "FeatureFlagsModule::ApplyConfiguration -> Error in the configuration event handler"); + } + + return true; } /// From 44a629f7028d6378c35775a1107a23bacb2bd802 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 10 Sep 2026 14:28:26 +0300 Subject: [PATCH 79/86] [FeatureFlags] Keep a throwing config handler from holding back the agentless ETag --- .../FeatureFlags/FeatureFlagsModuleTests.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs index eef2ddb993ef..476640d42a80 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs @@ -161,6 +161,19 @@ public async Task InitializeAsync_WhenConfigurationArrivesWhileWaiting_Returns() await initialization; } + [Fact] + public void ApplyConfiguration_WhenTheEventHandlerThrows_ReportsTheConfigurationAsApplied() + { + using var module = CreateModule(CreateSettings(), new MockRcmSubscriptionManager()); + + module.RegisterOnNewConfigEventHandler(() => throw new InvalidOperationException("from application code")); + + // False would tell the agentless source the configuration was not applied, so it would hold + // its ETag back and re-download the whole payload on every later poll. + module.ApplyConfiguration(new ServerConfiguration()).Should().BeTrue(); + module.FirstConfigReceived.IsCompleted.Should().BeTrue(); + } + [Fact] public async Task InitializeAsync_OnTimeout_ReturnsWithoutThrowing() { From 77cfab02f70c28f1cf319678b85d77bed8f94c03 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 10 Sep 2026 14:35:05 +0300 Subject: [PATCH 80/86] [FeatureFlags] Emit the provider event before the application's config handler --- .../DatadogProvider.cs | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/tracer/src/Datadog.FeatureFlags.OpenFeature/DatadogProvider.cs b/tracer/src/Datadog.FeatureFlags.OpenFeature/DatadogProvider.cs index 3e5ffd3f6ebd..62224f4d5ee9 100644 --- a/tracer/src/Datadog.FeatureFlags.OpenFeature/DatadogProvider.cs +++ b/tracer/src/Datadog.FeatureFlags.OpenFeature/DatadogProvider.cs @@ -60,10 +60,11 @@ public static void RegisterOnNewConfigEventHandler(Action onNewConfig) private void SignalGeneralUpdate() { + // This provider is the only source of its own status events, so the notification is written + // before anything the application supplied runs: a handler that throws must not be able to + // suppress it. try { - _onNewConfig?.Invoke(); - // The first configuration is what makes this provider usable, and only a ready event // promotes it: initialization reports an error when no delivery source could start, and // OpenFeature keeps that status until told otherwise. Later configurations are changes, @@ -71,13 +72,20 @@ private void SignalGeneralUpdate() if (Interlocked.CompareExchange(ref _readySignalled, 1, 0) == 0) { SignalReady(); - return; } + else + { + // Specific flag keys are unknown, so this payload only reports that something changed. + // An event already queued says exactly the same thing, which is why a full channel is + // left alone: the notification is on its way regardless. + EventChannel.Writer.TryWrite(CreatePayload(ProviderEventTypes.ProviderConfigurationChanged, "A backend update occurred, but specific changes are unknown.")); + } + } + catch { } - // Specific flag keys are unknown, so this payload only reports that something changed. - // An event already queued says exactly the same thing, which is why a full channel is - // left alone: the notification is on its way regardless. - EventChannel.Writer.TryWrite(CreatePayload(ProviderEventTypes.ProviderConfigurationChanged, "A backend update occurred, but specific changes are unknown.")); + try + { + _onNewConfig?.Invoke(); } catch { } } From cd03d2ae8e30a17186d16e740e1826e46d7a505e Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 10 Sep 2026 14:45:01 +0300 Subject: [PATCH 81/86] [FeatureFlags] Test the module's agentless activation and disposal --- .../Agentless/AgentlessConfigurationSource.cs | 2 +- .../FeatureFlags/FeatureFlagsModule.cs | 26 +++- .../IFeatureFlagsDeliverySource.cs | 21 +++ .../FeatureFlags/FeatureFlagsModuleTests.cs | 138 +++++++++++++++--- 4 files changed, 160 insertions(+), 27 deletions(-) create mode 100644 tracer/src/Datadog.Trace/FeatureFlags/IFeatureFlagsDeliverySource.cs diff --git a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs index d42449987fdb..64fb68ea7d47 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/Agentless/AgentlessConfigurationSource.cs @@ -26,7 +26,7 @@ namespace Datadog.Trace.FeatureFlags.Agentless; /// Polls the agentless endpoint for flag configuration. Polling is billable, so it is only /// started once application code has activated the provider. /// -internal sealed class AgentlessConfigurationSource : IDisposable +internal sealed class AgentlessConfigurationSource : IFeatureFlagsDeliverySource { private const int MaxAttempts = 3; private const double RetryJitter = 0.2; diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs index e4a805526ac9..db3c4d308369 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs @@ -37,6 +37,10 @@ internal sealed class FeatureFlagsModule : IDisposable private readonly TracerSettings.SettingsManager _settingsManager; private readonly bool _isRemoteConfigurationAvailable; private readonly Func _exposureApiFactory; + + // A factory rather than the static Create, so a test can supply a source that records what the + // module does with it: whether it is started before activation, and whether it is disposed. + private readonly Func _agentlessSourceFactory; private readonly bool _spanEnrichmentEnabled; private readonly IRcmSubscriptionManager _rcmSubscriptionManager; private readonly TaskCompletionSource _firstConfigReceived = new(TaskCreationOptions.RunContinuationsAsynchronously); @@ -44,20 +48,25 @@ internal sealed class FeatureFlagsModule : IDisposable private Action? _onNewConfigEventHander; private FeatureFlagsEvaluator? _evaluator; - private AgentlessConfigurationSource? _agentlessSource; + private IFeatureFlagsDeliverySource? _agentlessSource; private ExposureApi? _exposureApi; private string? _deliveryUnavailableReason; private bool _activated; private bool _disposed; private bool _deliveryStarted; - internal FeatureFlagsModule(TracerSettings settings, IRcmSubscriptionManager rcmSubscriptionManager) + internal FeatureFlagsModule( + TracerSettings settings, + IRcmSubscriptionManager rcmSubscriptionManager, + Func? agentlessSourceFactory = null) { _settings = settings.FeatureFlags; _settingsManager = settings.Manager; _isRemoteConfigurationAvailable = settings.IsRemoteConfigurationAvailable; _spanEnrichmentEnabled = settings.IsSpanEnrichmentEnabled; _exposureApiFactory = () => new ExposureApi(settings); + _agentlessSourceFactory = agentlessSourceFactory + ?? (static module => AgentlessConfigurationSource.Create(module._settings, module._settingsManager, module.ApplyConfiguration)); _rcmSubscriptionManager = rcmSubscriptionManager; Log.Debug("FeatureFlagsModule ENABLED with source {Source}", _settings.Source); @@ -70,14 +79,17 @@ internal FeatureFlagsModule(TracerSettings settings, IRcmSubscriptionManager rcm internal FeatureFlagsSettings Settings => _settings; - public static FeatureFlagsModule? Create(TracerSettings settings, IRcmSubscriptionManager rcmSubscriptionManager) + public static FeatureFlagsModule? Create( + TracerSettings settings, + IRcmSubscriptionManager rcmSubscriptionManager, + Func? agentlessSourceFactory = null) { if (!settings.FeatureFlags.Enabled) { return null; } - var module = new FeatureFlagsModule(settings, rcmSubscriptionManager); + var module = new FeatureFlagsModule(settings, rcmSubscriptionManager, agentlessSourceFactory); // Subscribing here rather than in the constructor: SubscribeToChanges can invoke the // callback, which must not reach a module that is still being constructed. @@ -92,7 +104,7 @@ internal FeatureFlagsModule(TracerSettings settings, IRcmSubscriptionManager rcm public void Dispose() { ISubscription? subscription; - AgentlessConfigurationSource? agentlessSource; + IFeatureFlagsDeliverySource? agentlessSource; ExposureApi? exposureApi; lock (_stateLock) @@ -143,7 +155,7 @@ internal void Activate() return; } - AgentlessConfigurationSource? sourceToStart = null; + IFeatureFlagsDeliverySource? sourceToStart = null; lock (_stateLock) { @@ -158,7 +170,7 @@ internal void Activate() { case FeatureFlagsSource.Agentless: // Polling is billable, so it starts here rather than at construction. - var source = AgentlessConfigurationSource.Create(_settings, _settingsManager, ApplyConfiguration); + var source = _agentlessSourceFactory(this); if (source is null) { // Create logs the specific reason, which may name configuration the diff --git a/tracer/src/Datadog.Trace/FeatureFlags/IFeatureFlagsDeliverySource.cs b/tracer/src/Datadog.Trace/FeatureFlags/IFeatureFlagsDeliverySource.cs new file mode 100644 index 000000000000..776a50b78849 --- /dev/null +++ b/tracer/src/Datadog.Trace/FeatureFlags/IFeatureFlagsDeliverySource.cs @@ -0,0 +1,21 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +#nullable enable + +using System; + +namespace Datadog.Trace.FeatureFlags; + +/// +/// A source of flag configuration that the module starts on activation and disposes with itself. +/// +internal interface IFeatureFlagsDeliverySource : IDisposable +{ + /// + /// Starts requesting configuration. Idempotent. + /// + void Start(); +} diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs index 476640d42a80..7ac63f3941d0 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs @@ -153,12 +153,20 @@ public async Task InitializeAsync_WhenConfigurationArrivesWhileWaiting_Returns() var settings = CreateInitializationSettings("60000"); using var module = CreateModule(settings, new MockRcmSubscriptionManager()); + var stopwatch = Stopwatch.StartNew(); + var initialization = module.InitializeAsync(CancellationToken.None); initialization.IsCompleted.Should().BeFalse(); module.ApplyConfiguration(new ServerConfiguration()).Should().BeTrue(); await initialization; + + stopwatch.Stop(); + + // Bounded, because the wait also ends normally at the 60s timeout: without this, the test + // would pass even if the arriving configuration never released it. + stopwatch.Elapsed.Should().BeLessThan(TimeSpan.FromSeconds(5)); } [Fact] @@ -196,10 +204,18 @@ public async Task InitializeAsync_OnCancellation_ReturnsWithoutThrowing() using var module = CreateModule(settings, new MockRcmSubscriptionManager()); using var cancellation = new CancellationTokenSource(); + var stopwatch = Stopwatch.StartNew(); + var initialization = module.InitializeAsync(cancellation.Token); cancellation.Cancel(); await initialization; + + stopwatch.Stop(); + + // Bounded, because without the cancellation the wait would run to the 60s timeout and still + // return normally, which would make this test pass for the wrong reason. + stopwatch.Elapsed.Should().BeLessThan(TimeSpan.FromSeconds(5)); } [Fact] @@ -242,25 +258,89 @@ public async Task InitializeAsync_WhenRemoteConfigurationIsUnavailable_FailsWith } [Fact] - public void Activate_WhenCalledConcurrently_LeavesTheSingleStartupSubscription() + public void Create_WithTheAgentlessSource_DoesNotStartDeliveryUntilActivated() { - var rcmManager = new MockRcmSubscriptionManager(); - using var module = CreateModule(CreateSettings(), rcmManager); - - // Create() subscribed once. Activation claims its flag atomically, so no caller can add a - // second subscription, nor observe the module as activated while setup is still running. - const int callers = 16; - using var start = new Barrier(callers); - Parallel.For( - 0, - callers, + var source = new FakeDeliverySource(); + using var module = CreateModule(CreateAgentlessSettings(), new MockRcmSubscriptionManager(), _ => source); + + // Installing the tracer must not issue a billable request. Only application code that adopts + // the provider may start the poller. + source.Started.Should().Be(0); + + module.Activate(); + module.Activate(); + + source.Started.Should().Be(1); + source.Disposed.Should().Be(0); + } + + [Fact] + public void Dispose_WithTheAgentlessSource_DisposesTheStartedPoller() + { + var source = new FakeDeliverySource(); + var module = CreateModule(CreateAgentlessSettings(), new MockRcmSubscriptionManager(), _ => source); + module.Activate(); + + module.Dispose(); + + // A poller that survives disposal keeps issuing billable requests for the rest of the process. + source.Disposed.Should().Be(1); + } + + [Fact] + public void Activate_AfterDispose_DoesNotStartTheAgentlessPoller() + { + var source = new FakeDeliverySource(); + var module = CreateModule(CreateAgentlessSettings(), new MockRcmSubscriptionManager(), _ => source); + module.Dispose(); + + module.Activate(); + + // Disposal has already run, so nothing would ever dispose a poller started now. + source.Started.Should().Be(0); + } + + [Fact] + public void Activate_WhenCalledConcurrently_StartsExactlyOnePoller() + { + var created = 0; + var source = new FakeDeliverySource(); + + using var module = CreateModule( + CreateAgentlessSettings(), + new MockRcmSubscriptionManager(), _ => { - start.SignalAndWait(); - module.Activate(); + Interlocked.Increment(ref created); + return source; }); - rcmManager.ProductKeys.Should().ContainSingle().Which.Should().Be(RcmProducts.FfeFlags); + // Dedicated threads rather than Parallel.For: blocked pool items in a host that already runs + // collections in parallel wait on thread-pool injection instead of on each other. + const int callers = 8; + using var start = new ManualResetEventSlim(false); + var threads = new Thread[callers]; + for (var i = 0; i < callers; i++) + { + threads[i] = new Thread(() => + { + start.Wait(); + module.Activate(); + }) + { IsBackground = true }; + + threads[i].Start(); + } + + start.Set(); + + foreach (var thread in threads) + { + thread.Join(TimeSpan.FromSeconds(30)).Should().BeTrue("Activate must not block"); + } + + created.Should().Be(1); + source.Started.Should().Be(1); } [Fact] @@ -273,10 +353,8 @@ public void Activate_AfterDispose_DoesNotSubscribeAgain() module.Activate(); // Disposal has already run its unsubscribe, so a subscription registered afterwards would - // never be removed, leaving a delivery path active for the rest of the process. Only the one - // subscription Create() made is expected, and it is gone. + // never be removed, leaving a delivery path active for the rest of the process. rcmManager.HasAnySubscription.Should().BeFalse(); - rcmManager.ProductKeys.Should().ContainSingle().Which.Should().Be(RcmProducts.FfeFlags); } [Fact] @@ -309,8 +387,11 @@ public void GetExposureApi_AfterDispose_DoesNotCreateOne() // Creates the module for settings that enable Feature Flags, and returns it as non-nullable so // tests can use it directly. Throwing rather than asserting keeps the compiler's nullable analysis // satisfied without a null-forgiving operator. - private static FeatureFlagsModule CreateModule(TracerSettings settings, IRcmSubscriptionManager rcmSubscriptionManager) - => FeatureFlagsModule.Create(settings, rcmSubscriptionManager) + private static FeatureFlagsModule CreateModule( + TracerSettings settings, + IRcmSubscriptionManager rcmSubscriptionManager, + Func? agentlessSourceFactory = null) + => FeatureFlagsModule.Create(settings, rcmSubscriptionManager, agentlessSourceFactory) ?? throw new InvalidOperationException("Feature Flags are enabled, but no module was created."); private static TracerSettings CreateSettings(params (string Key, string Value)[] settings) @@ -335,4 +416,23 @@ private static TracerSettings CreateInitializationSettings(string timeoutMs) => CreateSettings( (ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSource, "remote_config"), (ConfigurationKeys.FeatureFlags.FlaggingProviderInitializationTimeoutMs, timeoutMs)); + + private static TracerSettings CreateAgentlessSettings() + => CreateSettings((ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSource, "agentless")); + + // Records what the module does with a delivery source, which the real one cannot report without + // issuing requests. + private sealed class FakeDeliverySource : IFeatureFlagsDeliverySource + { + private int _started; + private int _disposed; + + public int Started => Volatile.Read(ref _started); + + public int Disposed => Volatile.Read(ref _disposed); + + public void Start() => Interlocked.Increment(ref _started); + + public void Dispose() => Interlocked.Increment(ref _disposed); + } } From 05490c388baf5c36055538ef4697b82a40e16adb Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 10 Sep 2026 15:12:56 +0300 Subject: [PATCH 82/86] [FeatureFlags] Address review comments on naming, comments and test-only members --- .../Sdk/FeatureFlagsSdk.cs | 2 +- .../FeatureFlags/FeatureFlagsModule.cs | 58 +++++++++++-------- .../FeatureFlags/FeatureFlagsSettings.cs | 4 ++ .../FeatureFlags/FeatureFlagsModuleTests.cs | 5 +- 4 files changed, 41 insertions(+), 28 deletions(-) diff --git a/tracer/src/Datadog.FeatureFlags.OpenFeature/Sdk/FeatureFlagsSdk.cs b/tracer/src/Datadog.FeatureFlags.OpenFeature/Sdk/FeatureFlagsSdk.cs index 1fa4c8300f2e..66e1a45d7091 100644 --- a/tracer/src/Datadog.FeatureFlags.OpenFeature/Sdk/FeatureFlagsSdk.cs +++ b/tracer/src/Datadog.FeatureFlags.OpenFeature/Sdk/FeatureFlagsSdk.cs @@ -39,7 +39,7 @@ internal static class FeatureFlagsSdk /// Delivery only starts here, because requesting configuration is billable and installing the /// tracer alone must not do it. /// - /// Cancellation token supplied by OpenFeature + /// Cancellation token. OpenFeature 2.3.0 does not forward one through SetProviderAsync, so only a direct caller supplies it /// A task that completes once configuration has arrived or the initialization timeout has elapsed, and that faults when no source could start delivery at all [MethodImpl(MethodImplOptions.NoInlining)] public static Task InitializeAsync(CancellationToken cancellationToken) => Task.CompletedTask; diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs index db3c4d308369..c53db4d2e301 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs @@ -17,6 +17,7 @@ using Datadog.Trace.FeatureFlags.Rcm.Model; using Datadog.Trace.Logging; using Datadog.Trace.RemoteConfigurationManagement; +using Datadog.Trace.SourceGenerators; namespace Datadog.Trace.FeatureFlags { @@ -36,7 +37,9 @@ internal sealed class FeatureFlagsModule : IDisposable // after startup, so it needs the manager rather than a captured value. private readonly TracerSettings.SettingsManager _settingsManager; private readonly bool _isRemoteConfigurationAvailable; - private readonly Func _exposureApiFactory; + // ExposureApi reads only settings.Manager but takes TracerSettings. Held so the API can be + // built on the first exposure instead of at startup. + private readonly TracerSettings _tracerSettings; // A factory rather than the static Create, so a test can supply a source that records what the // module does with it: whether it is started before activation, and whether it is disposed. @@ -46,7 +49,7 @@ internal sealed class FeatureFlagsModule : IDisposable private readonly TaskCompletionSource _firstConfigReceived = new(TaskCreationOptions.RunContinuationsAsynchronously); private ISubscription? _rcmSubscription; - private Action? _onNewConfigEventHander; + private Action? _onNewConfigEventHandler; private FeatureFlagsEvaluator? _evaluator; private IFeatureFlagsDeliverySource? _agentlessSource; private ExposureApi? _exposureApi; @@ -64,7 +67,7 @@ internal FeatureFlagsModule( _settingsManager = settings.Manager; _isRemoteConfigurationAvailable = settings.IsRemoteConfigurationAvailable; _spanEnrichmentEnabled = settings.IsSpanEnrichmentEnabled; - _exposureApiFactory = () => new ExposureApi(settings); + _tracerSettings = settings; _agentlessSourceFactory = agentlessSourceFactory ?? (static module => AgentlessConfigurationSource.Create(module._settings, module._settingsManager, module.ApplyConfiguration)); _rcmSubscriptionManager = rcmSubscriptionManager; @@ -75,8 +78,10 @@ internal FeatureFlagsModule( /// /// Gets a task that completes once configuration has been applied for the first time. /// + [TestingAndPrivateOnly] internal Task FirstConfigReceived => _firstConfigReceived.Task; + [TestingAndPrivateOnly] internal FeatureFlagsSettings Settings => _settings; public static FeatureFlagsModule? Create( @@ -91,8 +96,8 @@ internal FeatureFlagsModule( var module = new FeatureFlagsModule(settings, rcmSubscriptionManager, agentlessSourceFactory); - // Subscribing here rather than in the constructor: SubscribeToChanges can invoke the - // callback, which must not reach a module that is still being constructed. + // Subscribing from here rather than the constructor, so the callback can only ever reach + // a fully constructed module. if (settings.FeatureFlags.Source == FeatureFlagsSource.RemoteConfig) { module.SubscribeToRemoteConfiguration(); @@ -186,10 +191,9 @@ internal void Activate() } } - // Start() issues the first request on the calling thread up to its first await, so it runs - // outside the lock: holding it across a network request would block Dispose(). A Dispose() - // that interleaves here has already cancelled the source's shutdown token, which makes the - // poll loop exit before its first request. + // Outside the lock, so that a source which does any work of its own before returning cannot + // hold up a Dispose(). A Dispose() that interleaves here has already signalled the source's + // shutdown, which makes its poll loop exit before the first request. sourceToStart?.Start(); } @@ -239,15 +243,22 @@ internal async Task InitializeAsync(CancellationToken cancellationToken) throw new FeatureFlagsDeliveryUnavailableException(deliveryUnavailableReason); } - // Cancellation is signalled by completing a task: cancelling a token source throws, and - // an exception on this path can crash buggy runtimes. + // The caller's cancellation is turned into a completed task rather than passed to anything + // that throws on it, because an exception on this path can crash buggy runtimes. var cancelled = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); using var registration = cancellationToken.Register(() => cancelled.TrySetResult(true)); - var timeout = Task.Delay(_settings.InitializationTimeout); + // The timeout is cancelled on the way out, so an initialization that completes in + // milliseconds does not leave a timer armed for the rest of the timeout. + using var timeoutCancellation = new CancellationTokenSource(); + var timeout = Task.Delay(_settings.InitializationTimeout, timeoutCancellation.Token); var completed = await Task.WhenAny(_firstConfigReceived.Task, timeout, cancelled.Task).ConfigureAwait(false); - if (completed == timeout) + if (completed != timeout) + { + timeoutCancellation.Cancel(); + } + else { // Evaluations keep returning the caller's default with PROVIDER_NOT_READY until // configuration lands, which promotes the provider then. @@ -259,7 +270,7 @@ internal async Task InitializeAsync(CancellationToken cancellationToken) internal void RegisterOnNewConfigEventHandler(Action? onNewConfig) { - _onNewConfigEventHander = onNewConfig; + _onNewConfigEventHandler = onNewConfig; } internal Evaluation Evaluate(string flagKey, ValueType resultType, object? defaultValue, string targetingKey, IDictionary? attributes) @@ -275,6 +286,7 @@ internal Evaluation Evaluate(string flagKey, ValueType resultType, object? defau return evaluator.Evaluate(flagKey, resultType, defaultValue, new EvaluationContext(targetingKey, attributes)); } + [TestingAndPrivateOnly] internal bool ApplyConfiguration(ServerConfiguration configuration) { try @@ -294,7 +306,7 @@ internal bool ApplyConfiguration(ServerConfiguration configuration) // the configuration is already applied by this point and the handler cannot change that. try { - _onNewConfigEventHander?.Invoke(); + _onNewConfigEventHandler?.Invoke(); } catch (Exception ex) { @@ -327,7 +339,7 @@ private void SubscribeToRemoteConfiguration() return; } - var ffeProduct = new FfeProduct(configs => ApplyConfigurations(configs)); + var ffeProduct = new FfeProduct(ApplyRemoteConfigurations); _rcmSubscription = new Subscription(ffeProduct.UpdateFromRcm, RcmProducts.FfeFlags); _rcmSubscriptionManager.SubscribeToChanges(_rcmSubscription); _rcmSubscriptionManager.SetCapability(RcmCapabilitiesIndices.FfeFlagConfigurationRules, true); @@ -336,9 +348,9 @@ private void SubscribeToRemoteConfiguration() } } - private void ApplyConfigurations(List> list) + private void ApplyRemoteConfigurations(List> list) { - Log.Debug("FeatureFlagsModule::ApplyConfigurations -> New config received. {Count}", list.Count); + Log.Debug("FeatureFlagsModule::ApplyRemoteConfigurations -> New config received. {Count}", list.Count); try { if (list.Count > 0) @@ -350,12 +362,12 @@ private void ApplyConfigurations(List> { // RC reset: clear evaluator so Evaluate() returns PROVIDER_NOT_READY Interlocked.Exchange(ref _evaluator, null); - _onNewConfigEventHander?.Invoke(); + _onNewConfigEventHandler?.Invoke(); } } catch (Exception ex) { - Log.Warning(ex, "FeatureFlagsModule::ApplyConfigurations -> Error processing new config"); + Log.Warning(ex, "FeatureFlagsModule::ApplyRemoteConfigurations -> Error processing new config"); } static ServerConfiguration MergeConfigs(List> list) @@ -384,8 +396,8 @@ private void ReportExposure(in ExposureEvent exposure) // Created on first use because most applications never evaluate a flag, and under the lock // because the evaluation path races disposal. Only the very first exposure takes the lock: - // afterwards the field is read directly, keeping the exposure path lock-free. Internal so - // tests can assert the disposal behaviour without starting a send loop. + // afterwards the field is read directly, keeping the exposure path lock-free. + [TestingAndPrivateOnly] internal ExposureApi? GetExposureApi() { var exposureApi = Volatile.Read(ref _exposureApi); @@ -404,7 +416,7 @@ private void ReportExposure(in ExposureEvent exposure) exposureApi = _exposureApi; if (exposureApi is null) { - exposureApi = _exposureApiFactory(); + exposureApi = new ExposureApi(_tracerSettings); Volatile.Write(ref _exposureApi, exposureApi); } diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs index 9bbb0aa7234b..86721c331c3b 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsSettings.cs @@ -88,6 +88,10 @@ public FeatureFlagsSettings(IConfigurationSource? source, IConfigurationTelemetr Enabled = enabled != false && Source is FeatureFlagsSource.Agentless or FeatureFlagsSource.RemoteConfig; + // Recorded explicitly: this is computed from two keys, so nothing reports it when neither is + // set, which is exactly the case where the product runs on its default. + telemetry.Record(ConfigurationKeys.FeatureFlags.FeatureFlagsEnabled, Enabled, ConfigurationOrigins.Calculated); + var agentlessBaseUrl = config .WithKeys(ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSourceAgentlessBaseUrl) .AsRedactedString(); diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs index 7ac63f3941d0..9a1d86a92ea5 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs @@ -198,7 +198,7 @@ public async Task InitializeAsync_OnTimeout_ReturnsWithoutThrowing() } [Fact] - public async Task InitializeAsync_OnCancellation_ReturnsWithoutThrowing() + public async Task InitializeAsync_WhenADirectCallerCancels_ReturnsWithoutThrowing() { var settings = CreateInitializationSettings("60000"); using var module = CreateModule(settings, new MockRcmSubscriptionManager()); @@ -399,9 +399,6 @@ private static TracerSettings CreateSettings(params (string Key, string Value)[] var collection = new NameValueCollection { { ConfigurationKeys.FeatureFlags.FeatureFlagsConfigurationSource, "remote_config" }, -#pragma warning disable 618 // superseded, but still honoured for existing adopters - { ConfigurationKeys.FeatureFlags.FlaggingProviderEnabled, "true" }, -#pragma warning restore 618 }; foreach (var (key, value) in settings) From d264e6428732203f7c9bb7571b90432b66c47783 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 10 Sep 2026 15:48:14 +0300 Subject: [PATCH 83/86] [FeatureFlags] Report withdrawn configuration as a provider error --- tracer/build/supported_calltargets.g.json | 22 +++++++++++ .../DatadogProvider.cs | 35 ++++++++++++++--- .../Sdk/FeatureFlagsSdk.cs | 8 ++++ ...enFeatureSdkHasConfigurationIntegration.cs | 39 +++++++++++++++++++ .../FeatureFlags/FeatureFlagsModule.cs | 11 +++++- .../InstrumentationDefinitions.g.cs | 1 + .../InstrumentationDefinitions.g.cs | 1 + .../InstrumentationDefinitions.g.cs | 1 + .../InstrumentationDefinitions.g.cs | 1 + .../Generated/generated_calltargets.g.cpp | 1 + .../FeatureFlags/FeatureFlagsModuleTests.cs | 35 +++++++++++++++++ 11 files changed, 149 insertions(+), 6 deletions(-) create mode 100644 tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/ManualInstrumentation/OpenFeature/OpenFeatureSdkHasConfigurationIntegration.cs diff --git a/tracer/build/supported_calltargets.g.json b/tracer/build/supported_calltargets.g.json index d8e49b7fdbed..85a13bb3c046 100644 --- a/tracer/build/supported_calltargets.g.json +++ b/tracer/build/supported_calltargets.g.json @@ -14164,6 +14164,28 @@ "IsAdoNetIntegration": false, "InstrumentationCategory": 1 }, + { + "IntegrationName": "OpenFeature", + "AssemblyName": "Datadog.FeatureFlags.OpenFeature", + "TargetTypeName": "Datadog.FeatureFlags.OpenFeature.FeatureFlagsSdk", + "TargetMethodName": "HasConfiguration", + "TargetReturnType": "System.Boolean", + "TargetParameterTypes": [], + "MinimumVersion": { + "Item1": 2, + "Item2": 0, + "Item3": 0 + }, + "MaximumVersion": { + "Item1": 2, + "Item2": 65535, + "Item3": 65535 + }, + "InstrumentationTypeName": "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkHasConfigurationIntegration", + "IntegrationKind": 0, + "IsAdoNetIntegration": false, + "InstrumentationCategory": 1 + }, { "IntegrationName": "OpenFeature", "AssemblyName": "Datadog.FeatureFlags.OpenFeature", diff --git a/tracer/src/Datadog.FeatureFlags.OpenFeature/DatadogProvider.cs b/tracer/src/Datadog.FeatureFlags.OpenFeature/DatadogProvider.cs index 62224f4d5ee9..de5115570357 100644 --- a/tracer/src/Datadog.FeatureFlags.OpenFeature/DatadogProvider.cs +++ b/tracer/src/Datadog.FeatureFlags.OpenFeature/DatadogProvider.cs @@ -65,12 +65,16 @@ private void SignalGeneralUpdate() // suppress it. try { - // The first configuration is what makes this provider usable, and only a ready event - // promotes it: initialization reports an error when no delivery source could start, and - // OpenFeature keeps that status until told otherwise. Later configurations are changes, - // which deliberately leave the status alone. - if (Interlocked.CompareExchange(ref _readySignalled, 1, 0) == 0) + if (!FeatureFlagsSdk.HasConfiguration()) { + SignalConfigurationUnavailable(); + } + else if (Interlocked.CompareExchange(ref _readySignalled, 1, 0) == 0) + { + // The first configuration is what makes this provider usable, and only a ready event + // promotes it: initialization reports an error when no delivery source could start, and + // OpenFeature keeps that status until told otherwise. This also promotes the provider + // again after a withdrawal, which resets the flag. SignalReady(); } else @@ -90,6 +94,27 @@ private void SignalGeneralUpdate() catch { } } + private void SignalConfigurationUnavailable() + { + // Configuration was withdrawn, so every evaluation now returns its default value. Leaving the + // status at READY would report a provider that resolves nothing, so an error is emitted and the + // ready flag is reset, which lets the next configuration promote the provider back. + if (Interlocked.Exchange(ref _readySignalled, 0) == 0) + { + // Never promoted, so there is no status to correct. + return; + } + + var payload = CreatePayload(ProviderEventTypes.ProviderError, "Feature flag configuration is unavailable."); + payload.ErrorType = ErrorType.ProviderNotReady; + + if (!EventChannel.Writer.TryWrite(payload)) + { + // A status transition cannot be dropped, for the same reason the ready event cannot. + _ = WriteWhenRoomAvailableAsync(payload); + } + } + private void SignalReady() { var payload = CreatePayload(ProviderEventTypes.ProviderReady, "Feature flag configuration was received."); diff --git a/tracer/src/Datadog.FeatureFlags.OpenFeature/Sdk/FeatureFlagsSdk.cs b/tracer/src/Datadog.FeatureFlags.OpenFeature/Sdk/FeatureFlagsSdk.cs index 66e1a45d7091..f25c825ddd44 100644 --- a/tracer/src/Datadog.FeatureFlags.OpenFeature/Sdk/FeatureFlagsSdk.cs +++ b/tracer/src/Datadog.FeatureFlags.OpenFeature/Sdk/FeatureFlagsSdk.cs @@ -34,6 +34,14 @@ internal static class FeatureFlagsSdk [MethodImpl(MethodImplOptions.NoInlining)] internal static bool IsSpanEnrichmentEnabled() => false; + /// + /// Gets a value indicating whether flag configuration is currently held, so the provider can + /// resolve flags. Goes back to false when configuration is withdrawn. + /// + /// True while configuration is held + [MethodImpl(MethodImplOptions.NoInlining)] + internal static bool HasConfiguration() => false; + /// /// Activates flag configuration delivery and waits for the first configuration to arrive. /// Delivery only starts here, because requesting configuration is billable and installing the diff --git a/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/ManualInstrumentation/OpenFeature/OpenFeatureSdkHasConfigurationIntegration.cs b/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/ManualInstrumentation/OpenFeature/OpenFeatureSdkHasConfigurationIntegration.cs new file mode 100644 index 000000000000..cb31fbff0069 --- /dev/null +++ b/tracer/src/Datadog.Trace/ClrProfiler/AutoInstrumentation/ManualInstrumentation/OpenFeature/OpenFeatureSdkHasConfigurationIntegration.cs @@ -0,0 +1,39 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// +#nullable enable + +using System; +using System.ComponentModel; +using Datadog.Trace.ClrProfiler.CallTarget; +using Datadog.Trace.Configuration; + +namespace Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature; + +/// +/// System.Boolean Datadog.FeatureFlags.OpenFeature.FeatureFlagsSdk::HasConfiguration() calltarget instrumentation +/// +[InstrumentMethod( + AssemblyName = "Datadog.FeatureFlags.OpenFeature", + TypeName = "Datadog.FeatureFlags.OpenFeature.FeatureFlagsSdk", + MethodName = "HasConfiguration", + ReturnTypeName = ClrNames.Bool, + ParameterTypeNames = [], + MinimumVersion = "2.0.0", + MaximumVersion = "2.*.*", + IntegrationName = nameof(IntegrationId.OpenFeature))] +[Browsable(false)] +[EditorBrowsable(EditorBrowsableState.Never)] +public sealed class OpenFeatureSdkHasConfigurationIntegration +{ + internal static CallTargetReturn OnMethodEnd(bool returnValue, Exception? exception, in CallTargetState state) + { + if (exception is not null) + { + return new CallTargetReturn(returnValue); + } + + return new CallTargetReturn(TracerManager.Instance.FeatureFlags?.HasConfiguration == true); + } +} diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs index c53db4d2e301..1e49686d5311 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs @@ -37,6 +37,7 @@ internal sealed class FeatureFlagsModule : IDisposable // after startup, so it needs the manager rather than a captured value. private readonly TracerSettings.SettingsManager _settingsManager; private readonly bool _isRemoteConfigurationAvailable; + // ExposureApi reads only settings.Manager but takes TracerSettings. Held so the API can be // built on the first exposure instead of at startup. private readonly TracerSettings _tracerSettings; @@ -84,6 +85,12 @@ internal FeatureFlagsModule( [TestingAndPrivateOnly] internal FeatureFlagsSettings Settings => _settings; + /// + /// Gets a value indicating whether configuration is currently held, so evaluations can resolve + /// flags. Goes back to false when Remote Configuration withdraws it. + /// + internal bool HasConfiguration => Volatile.Read(ref _evaluator) is not null; + public static FeatureFlagsModule? Create( TracerSettings settings, IRcmSubscriptionManager rcmSubscriptionManager, @@ -360,7 +367,9 @@ private void ApplyRemoteConfigurations(List Datadog.Trace.Configuration.IntegrationId.NUnit, "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkAccumulateSpanEnrichmentIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkEvaluateIntegration" + or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkHasConfigurationIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkInitializeAsyncIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkIsAvailableIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkIsSpanEnrichmentEnabledIntegration" diff --git a/tracer/src/Datadog.Trace/Generated/net6.0/Datadog.Trace.SourceGenerators/InstrumentationDefinitionsGenerator/InstrumentationDefinitions.g.cs b/tracer/src/Datadog.Trace/Generated/net6.0/Datadog.Trace.SourceGenerators/InstrumentationDefinitionsGenerator/InstrumentationDefinitions.g.cs index f60d4066a44d..9b9b60618ed9 100644 --- a/tracer/src/Datadog.Trace/Generated/net6.0/Datadog.Trace.SourceGenerators/InstrumentationDefinitionsGenerator/InstrumentationDefinitions.g.cs +++ b/tracer/src/Datadog.Trace/Generated/net6.0/Datadog.Trace.SourceGenerators/InstrumentationDefinitionsGenerator/InstrumentationDefinitions.g.cs @@ -586,6 +586,7 @@ internal static bool IsInstrumentedAssembly(string assemblyName) => Datadog.Trace.Configuration.IntegrationId.NUnit, "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkAccumulateSpanEnrichmentIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkEvaluateIntegration" + or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkHasConfigurationIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkInitializeAsyncIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkIsAvailableIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkIsSpanEnrichmentEnabledIntegration" diff --git a/tracer/src/Datadog.Trace/Generated/netcoreapp3.1/Datadog.Trace.SourceGenerators/InstrumentationDefinitionsGenerator/InstrumentationDefinitions.g.cs b/tracer/src/Datadog.Trace/Generated/netcoreapp3.1/Datadog.Trace.SourceGenerators/InstrumentationDefinitionsGenerator/InstrumentationDefinitions.g.cs index d1a8f9933225..f02acdd5cc3e 100644 --- a/tracer/src/Datadog.Trace/Generated/netcoreapp3.1/Datadog.Trace.SourceGenerators/InstrumentationDefinitionsGenerator/InstrumentationDefinitions.g.cs +++ b/tracer/src/Datadog.Trace/Generated/netcoreapp3.1/Datadog.Trace.SourceGenerators/InstrumentationDefinitionsGenerator/InstrumentationDefinitions.g.cs @@ -578,6 +578,7 @@ internal static bool IsInstrumentedAssembly(string assemblyName) => Datadog.Trace.Configuration.IntegrationId.NUnit, "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkAccumulateSpanEnrichmentIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkEvaluateIntegration" + or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkHasConfigurationIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkInitializeAsyncIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkIsAvailableIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkIsSpanEnrichmentEnabledIntegration" diff --git a/tracer/src/Datadog.Trace/Generated/netstandard2.0/Datadog.Trace.SourceGenerators/InstrumentationDefinitionsGenerator/InstrumentationDefinitions.g.cs b/tracer/src/Datadog.Trace/Generated/netstandard2.0/Datadog.Trace.SourceGenerators/InstrumentationDefinitionsGenerator/InstrumentationDefinitions.g.cs index d1a8f9933225..f02acdd5cc3e 100644 --- a/tracer/src/Datadog.Trace/Generated/netstandard2.0/Datadog.Trace.SourceGenerators/InstrumentationDefinitionsGenerator/InstrumentationDefinitions.g.cs +++ b/tracer/src/Datadog.Trace/Generated/netstandard2.0/Datadog.Trace.SourceGenerators/InstrumentationDefinitionsGenerator/InstrumentationDefinitions.g.cs @@ -578,6 +578,7 @@ internal static bool IsInstrumentedAssembly(string assemblyName) => Datadog.Trace.Configuration.IntegrationId.NUnit, "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkAccumulateSpanEnrichmentIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkEvaluateIntegration" + or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkHasConfigurationIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkInitializeAsyncIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkIsAvailableIntegration" or "Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkIsSpanEnrichmentEnabledIntegration" diff --git a/tracer/src/Datadog.Tracer.Native/Generated/generated_calltargets.g.cpp b/tracer/src/Datadog.Tracer.Native/Generated/generated_calltargets.g.cpp index 72bb69dd116f..88f381be9ffc 100644 --- a/tracer/src/Datadog.Tracer.Native/Generated/generated_calltargets.g.cpp +++ b/tracer/src/Datadog.Tracer.Native/Generated/generated_calltargets.g.cpp @@ -1027,6 +1027,7 @@ std::vector callTargets = {(WCHAR*)WStr("nunit.framework"),(WCHAR*)WStr("NUnit.Framework.Internal.Reflect"),(WCHAR*)WStr("InvokeMethod"),sig177,4,3,0,0,4,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.Testing.NUnit.NUnitReflectInvokeMethodIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.FeatureFlags.OpenFeature"),(WCHAR*)WStr("Datadog.FeatureFlags.OpenFeature.FeatureFlagsSdk"),(WCHAR*)WStr("AccumulateSpanEnrichment"),sig388,7,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkAccumulateSpanEnrichmentIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.FeatureFlags.OpenFeature"),(WCHAR*)WStr("Datadog.FeatureFlags.OpenFeature.FeatureFlagsSdk"),(WCHAR*)WStr("Evaluate"),sig061,6,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkEvaluateIntegration"),CallTargetKind::Default,1,15}, +{(WCHAR*)WStr("Datadog.FeatureFlags.OpenFeature"),(WCHAR*)WStr("Datadog.FeatureFlags.OpenFeature.FeatureFlagsSdk"),(WCHAR*)WStr("HasConfiguration"),sig130,1,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkHasConfigurationIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.FeatureFlags.OpenFeature"),(WCHAR*)WStr("Datadog.FeatureFlags.OpenFeature.FeatureFlagsSdk"),(WCHAR*)WStr("InitializeAsync"),sig219,2,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkInitializeAsyncIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.FeatureFlags.OpenFeature"),(WCHAR*)WStr("Datadog.FeatureFlags.OpenFeature.FeatureFlagsSdk"),(WCHAR*)WStr("IsAvailable"),sig130,1,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkIsAvailableIntegration"),CallTargetKind::Default,1,15}, {(WCHAR*)WStr("Datadog.FeatureFlags.OpenFeature"),(WCHAR*)WStr("Datadog.FeatureFlags.OpenFeature.FeatureFlagsSdk"),(WCHAR*)WStr("IsSpanEnrichmentEnabled"),sig130,1,2,0,0,2,65535,65535,assemblyName,(WCHAR*)WStr("Datadog.Trace.ClrProfiler.AutoInstrumentation.ManualInstrumentation.OpenFeature.OpenFeatureSdkIsSpanEnrichmentEnabledIntegration"),CallTargetKind::Default,1,15}, diff --git a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs index 9a1d86a92ea5..156cb960ee25 100644 --- a/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs +++ b/tracer/test/Datadog.Trace.Tests/FeatureFlags/FeatureFlagsModuleTests.cs @@ -169,6 +169,41 @@ public async Task InitializeAsync_WhenConfigurationArrivesWhileWaiting_Returns() stopwatch.Elapsed.Should().BeLessThan(TimeSpan.FromSeconds(5)); } + [Fact] + public void HasConfiguration_FollowsWhetherTheEvaluatorCanResolve() + { + var rcmManager = new MockRcmSubscriptionManager(); + using var module = CreateModule(CreateSettings(), rcmManager); + + module.HasConfiguration.Should().BeFalse(); + + var subscription = rcmManager.LastSubscription + ?? throw new InvalidOperationException("Create did not register a Remote Configuration subscription."); + + var configJson = JsonConvert.SerializeObject(new ServerConfiguration()); + var configPath = RemoteConfigurationPath.FromPath($"datadog/2/{RcmProducts.FfeFlags}/test-config/config"); + + subscription.Invoke( + new Dictionary> + { + [RcmProducts.FfeFlags] = [new RemoteConfiguration(configPath, System.Text.Encoding.UTF8.GetBytes(configJson), configJson.Length, new Dictionary { { "sha256", "dummy" } }, 1)] + }, + null); + + module.HasConfiguration.Should().BeTrue(); + + // A withdrawal from Remote Configuration, which the provider reads to emit an error status + // instead of leaving itself reported as ready while resolving nothing. + subscription.Invoke( + new Dictionary>(), + new Dictionary> + { + [RcmProducts.FfeFlags] = [configPath] + }); + + module.HasConfiguration.Should().BeFalse(); + } + [Fact] public void ApplyConfiguration_WhenTheEventHandlerThrows_ReportsTheConfigurationAsApplied() { From 94a9706e0f875be2e72d9407128bfaff8a4f4d68 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 10 Sep 2026 16:13:25 +0300 Subject: [PATCH 84/86] [FeatureFlags] Correct the initialization-timeout documentation --- .../Configuration/supported-configurations.yaml | 6 ++++-- .../Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs | 10 +++++----- .../ConfigurationKeys.FeatureFlags.g.cs | 6 ++++-- .../ConfigurationKeys.FeatureFlags.g.cs | 6 ++++-- .../ConfigurationKeys.FeatureFlags.g.cs | 6 ++++-- .../ConfigurationKeys.FeatureFlags.g.cs | 6 ++++-- 6 files changed, 25 insertions(+), 15 deletions(-) diff --git a/tracer/src/Datadog.Trace/Configuration/supported-configurations.yaml b/tracer/src/Datadog.Trace/Configuration/supported-configurations.yaml index 53f068d47c88..ca598e687779 100644 --- a/tracer/src/Datadog.Trace/Configuration/supported-configurations.yaml +++ b/tracer/src/Datadog.Trace/Configuration/supported-configurations.yaml @@ -3176,8 +3176,10 @@ supportedConfigurations: Configuration key for how long, in milliseconds, provider initialization waits for the first flag configuration to arrive before returning. Default value is 30000 (30 seconds), matching the other tracers. - Initialization does not fail when the timeout expires: the provider stays not-ready, evaluations - return the caller's default value, and the provider becomes ready when configuration arrives. + Initialization does not fail when the timeout expires: it returns, and evaluations return the + caller's default value until the configuration arrives. + The application is blocked for up to this long, because the OpenFeature SDK awaits provider + initialization, so keep it below the budget the application's readiness probe allows. DD_FEATURE_FLAGS_ENABLED: - implementation: A scope: managed diff --git a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs index 1e49686d5311..851915079563 100644 --- a/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs +++ b/tracer/src/Datadog.Trace/FeatureFlags/FeatureFlagsModule.cs @@ -208,10 +208,12 @@ internal void Activate() /// Activates delivery and waits for the first configuration, so that a provider reported as /// ready can resolve flags. /// - /// Returns without throwing when the wait times out, because delivery being slow is transient: - /// the configuration still arrives later and promotes the provider. Throws + /// Returns without throwing when the wait times out: delivery being slow is transient, and + /// OpenFeature marks the provider ready on a normal return, so evaluations return their + /// defaults with PROVIDER_NOT_READY until the configuration lands. Throws /// when no source could start at all, - /// which is permanent for the life of the process and must not be reported as a ready provider. + /// which OpenFeature turns into an error status: a provider that can never resolve a flag is + /// in error, not ready. /// /// /// The wait ends only when a configuration arrives, so a service with no flag configuration @@ -267,8 +269,6 @@ internal async Task InitializeAsync(CancellationToken cancellationToken) } else { - // Evaluations keep returning the caller's default with PROVIDER_NOT_READY until - // configuration lands, which promotes the provider then. Log.Warning( "Feature Flags configuration did not arrive within {TimeoutMs}ms. Evaluations use their default values until it does.", _settings.InitializationTimeout.TotalMilliseconds); diff --git a/tracer/src/Datadog.Trace/Generated/net461/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs b/tracer/src/Datadog.Trace/Generated/net461/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs index 288cd8f848eb..57e39c72c46c 100644 --- a/tracer/src/Datadog.Trace/Generated/net461/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs +++ b/tracer/src/Datadog.Trace/Generated/net461/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs @@ -27,8 +27,10 @@ internal static class FeatureFlags /// Configuration key for how long, in milliseconds, provider initialization waits for the first /// flag configuration to arrive before returning. /// Default value is 30000 (30 seconds), matching the other tracers. - /// Initialization does not fail when the timeout expires: the provider stays not-ready, evaluations - /// return the caller's default value, and the provider becomes ready when configuration arrives. + /// Initialization does not fail when the timeout expires: it returns, and evaluations return the + /// caller's default value until the configuration arrives. + /// The application is blocked for up to this long, because the OpenFeature SDK awaits provider + /// initialization, so keep it below the budget the application's readiness probe allows. /// public const string FlaggingProviderInitializationTimeoutMs = "DD_EXPERIMENTAL_FLAGGING_PROVIDER_INITIALIZATION_TIMEOUT_MS"; diff --git a/tracer/src/Datadog.Trace/Generated/net6.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs b/tracer/src/Datadog.Trace/Generated/net6.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs index 288cd8f848eb..57e39c72c46c 100644 --- a/tracer/src/Datadog.Trace/Generated/net6.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs +++ b/tracer/src/Datadog.Trace/Generated/net6.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs @@ -27,8 +27,10 @@ internal static class FeatureFlags /// Configuration key for how long, in milliseconds, provider initialization waits for the first /// flag configuration to arrive before returning. /// Default value is 30000 (30 seconds), matching the other tracers. - /// Initialization does not fail when the timeout expires: the provider stays not-ready, evaluations - /// return the caller's default value, and the provider becomes ready when configuration arrives. + /// Initialization does not fail when the timeout expires: it returns, and evaluations return the + /// caller's default value until the configuration arrives. + /// The application is blocked for up to this long, because the OpenFeature SDK awaits provider + /// initialization, so keep it below the budget the application's readiness probe allows. /// public const string FlaggingProviderInitializationTimeoutMs = "DD_EXPERIMENTAL_FLAGGING_PROVIDER_INITIALIZATION_TIMEOUT_MS"; diff --git a/tracer/src/Datadog.Trace/Generated/netcoreapp3.1/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs b/tracer/src/Datadog.Trace/Generated/netcoreapp3.1/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs index 288cd8f848eb..57e39c72c46c 100644 --- a/tracer/src/Datadog.Trace/Generated/netcoreapp3.1/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs +++ b/tracer/src/Datadog.Trace/Generated/netcoreapp3.1/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs @@ -27,8 +27,10 @@ internal static class FeatureFlags /// Configuration key for how long, in milliseconds, provider initialization waits for the first /// flag configuration to arrive before returning. /// Default value is 30000 (30 seconds), matching the other tracers. - /// Initialization does not fail when the timeout expires: the provider stays not-ready, evaluations - /// return the caller's default value, and the provider becomes ready when configuration arrives. + /// Initialization does not fail when the timeout expires: it returns, and evaluations return the + /// caller's default value until the configuration arrives. + /// The application is blocked for up to this long, because the OpenFeature SDK awaits provider + /// initialization, so keep it below the budget the application's readiness probe allows. /// public const string FlaggingProviderInitializationTimeoutMs = "DD_EXPERIMENTAL_FLAGGING_PROVIDER_INITIALIZATION_TIMEOUT_MS"; diff --git a/tracer/src/Datadog.Trace/Generated/netstandard2.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs b/tracer/src/Datadog.Trace/Generated/netstandard2.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs index 288cd8f848eb..57e39c72c46c 100644 --- a/tracer/src/Datadog.Trace/Generated/netstandard2.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs +++ b/tracer/src/Datadog.Trace/Generated/netstandard2.0/Datadog.Trace.SourceGenerators/ConfigurationKeysGenerator/ConfigurationKeys.FeatureFlags.g.cs @@ -27,8 +27,10 @@ internal static class FeatureFlags /// Configuration key for how long, in milliseconds, provider initialization waits for the first /// flag configuration to arrive before returning. /// Default value is 30000 (30 seconds), matching the other tracers. - /// Initialization does not fail when the timeout expires: the provider stays not-ready, evaluations - /// return the caller's default value, and the provider becomes ready when configuration arrives. + /// Initialization does not fail when the timeout expires: it returns, and evaluations return the + /// caller's default value until the configuration arrives. + /// The application is blocked for up to this long, because the OpenFeature SDK awaits provider + /// initialization, so keep it below the budget the application's readiness probe allows. /// public const string FlaggingProviderInitializationTimeoutMs = "DD_EXPERIMENTAL_FLAGGING_PROVIDER_INITIALIZATION_TIMEOUT_MS"; From 0a92d2a062ddfc0f91be0ce2920c0abfab752196 Mon Sep 17 00:00:00 2001 From: Pavel Date: Thu, 10 Sep 2026 16:33:02 +0300 Subject: [PATCH 85/86] [FeatureFlags] Emit provider status events from initialization --- .../DatadogProvider.cs | 51 ++++++++++++++++--- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/tracer/src/Datadog.FeatureFlags.OpenFeature/DatadogProvider.cs b/tracer/src/Datadog.FeatureFlags.OpenFeature/DatadogProvider.cs index de5115570357..c5ee56c7d486 100644 --- a/tracer/src/Datadog.FeatureFlags.OpenFeature/DatadogProvider.cs +++ b/tracer/src/Datadog.FeatureFlags.OpenFeature/DatadogProvider.cs @@ -14,6 +14,7 @@ using System.Threading.Tasks; using OpenFeature; using OpenFeature.Constant; +using OpenFeature.Error; using OpenFeature.Model; namespace Datadog.FeatureFlags.OpenFeature; @@ -115,6 +116,19 @@ private void SignalConfigurationUnavailable() } } + private void SignalInitializationFailed(string message) + { + // Emitted before the exception leaves this method, because the provider owns its status events + // rather than letting them be inferred from how initialization terminated. + var payload = CreatePayload(ProviderEventTypes.ProviderError, message); + payload.ErrorType = ErrorType.ProviderFatal; + + if (!EventChannel.Writer.TryWrite(payload)) + { + _ = WriteWhenRoomAvailableAsync(payload); + } + } + private void SignalReady() { var payload = CreatePayload(ProviderEventTypes.ProviderReady, "Feature flag configuration was received."); @@ -157,18 +171,41 @@ private ProviderEventPayload CreatePayload(ProviderEventTypes type, string messa /// provider can actually resolve flags. /// /// It returns normally when the wait times out, because slow delivery is transient and the - /// configuration still arrives afterwards. It faults when no source could start delivery at all, - /// which leaves the provider unable to resolve anything for the rest of the process: OpenFeature - /// then marks this provider as errored instead of ready, and evaluations keep returning their - /// default values. The exception does not reach the application, because OpenFeature handles it - /// while setting the provider. + /// configuration still arrives afterwards. It throws when no + /// source could start delivery at all, which leaves the provider unable to resolve anything for + /// the rest of the process: that is irrecoverable rather than merely not-ready. The exception does + /// not reach the application, because OpenFeature handles it while setting the provider. + /// + /// + /// This provider emits its own status event either way, rather than leaving the SDK to infer one + /// from how this method returns. /// /// /// Evaluation context /// Async cancellation token /// A task that completes when initialization is complete - public override Task InitializeAsync(EvaluationContext context, CancellationToken cancellationToken = default) - => FeatureFlagsSdk.InitializeAsync(cancellationToken); + public override async Task InitializeAsync(EvaluationContext context, CancellationToken cancellationToken = default) + { + try + { + await FeatureFlagsSdk.InitializeAsync(cancellationToken).ConfigureAwait(false); + } + catch (Exception exception) + { + SignalInitializationFailed(exception.Message); + + // Irrecoverable: no source can be started later in this process, so no configuration will + // ever arrive and every evaluation returns its default value. + throw new ProviderFatalException(exception.Message, exception); + } + + // Configuration that arrived before the application registered this provider leaves nothing to + // signal from the configuration callback, so the ready event is emitted here instead. + if (FeatureFlagsSdk.HasConfiguration() && Interlocked.CompareExchange(ref _readySignalled, 1, 0) == 0) + { + SignalReady(); + } + } /// Gets provider metadata /// Returns provider metadata From 1ba423fdacd4ad853776d83d65ab5f4b650f2b38 Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 11 Sep 2026 09:34:30 +0300 Subject: [PATCH 86/86] [FeatureFlags] Delegate the first provider ready event to the OpenFeature SDK --- .../DatadogProvider.cs | 72 +++++++++---------- 1 file changed, 32 insertions(+), 40 deletions(-) diff --git a/tracer/src/Datadog.FeatureFlags.OpenFeature/DatadogProvider.cs b/tracer/src/Datadog.FeatureFlags.OpenFeature/DatadogProvider.cs index c5ee56c7d486..1f1e2fdd70e4 100644 --- a/tracer/src/Datadog.FeatureFlags.OpenFeature/DatadogProvider.cs +++ b/tracer/src/Datadog.FeatureFlags.OpenFeature/DatadogProvider.cs @@ -24,6 +24,13 @@ namespace Datadog.FeatureFlags.OpenFeature; /// public sealed class DatadogProvider : global::OpenFeature.FeatureProvider, IDisposable { + // The status this provider last reported, which decides the transitions it owns. The first ready + // event is not one of them: OpenFeature synthesizes one as soon as InitializeAsync returns, so + // emitting it here as well would run every application handler twice. + private const int StatusInitializing = 0; + private const int StatusReady = 1; + private const int StatusError = 2; + private static Action? _onNewConfig = null; private readonly Metadata _metadata = new Metadata("datadog-openfeature-provider"); #if NET6_0_OR_GREATER @@ -34,7 +41,7 @@ public sealed class DatadogProvider : global::OpenFeature.FeatureProvider, IDisp // nothing is allocated/registered when the feature is disabled. private readonly SpanEnrichmentHook? _spanEnrichmentHook; - private int _readySignalled; + private int _status = StatusInitializing; /// Initializes a new instance of the class. public DatadogProvider() @@ -61,30 +68,30 @@ public static void RegisterOnNewConfigEventHandler(Action onNewConfig) private void SignalGeneralUpdate() { - // This provider is the only source of its own status events, so the notification is written - // before anything the application supplied runs: a handler that throws must not be able to - // suppress it. + // The status event is written before anything the application supplied runs: a handler that + // throws must not be able to suppress it. try { if (!FeatureFlagsSdk.HasConfiguration()) { SignalConfigurationUnavailable(); } - else if (Interlocked.CompareExchange(ref _readySignalled, 1, 0) == 0) + else if (Interlocked.CompareExchange(ref _status, StatusReady, StatusError) == StatusError) { - // The first configuration is what makes this provider usable, and only a ready event - // promotes it: initialization reports an error when no delivery source could start, and - // OpenFeature keeps that status until told otherwise. This also promotes the provider - // again after a withdrawal, which resets the flag. + // Configuration is back after a withdrawal, and nothing else promotes the provider: + // OpenFeature keeps the error status until a ready event replaces it. SignalReady(); } - else + else if (Volatile.Read(ref _status) == StatusReady) { // Specific flag keys are unknown, so this payload only reports that something changed. // An event already queued says exactly the same thing, which is why a full channel is // left alone: the notification is on its way regardless. EventChannel.Writer.TryWrite(CreatePayload(ProviderEventTypes.ProviderConfigurationChanged, "A backend update occurred, but specific changes are unknown.")); } + + // Otherwise initialization has not returned yet, and the ready event it produces already + // accounts for this configuration. } catch { } @@ -98,11 +105,11 @@ private void SignalGeneralUpdate() private void SignalConfigurationUnavailable() { // Configuration was withdrawn, so every evaluation now returns its default value. Leaving the - // status at READY would report a provider that resolves nothing, so an error is emitted and the - // ready flag is reset, which lets the next configuration promote the provider back. - if (Interlocked.Exchange(ref _readySignalled, 0) == 0) + // status at READY would report a provider that resolves nothing, so an error is emitted; the + // next configuration promotes the provider back. + if (Interlocked.CompareExchange(ref _status, StatusError, StatusReady) != StatusReady) { - // Never promoted, so there is no status to correct. + // Not reported as ready, so there is no status to correct. return; } @@ -116,19 +123,6 @@ private void SignalConfigurationUnavailable() } } - private void SignalInitializationFailed(string message) - { - // Emitted before the exception leaves this method, because the provider owns its status events - // rather than letting them be inferred from how initialization terminated. - var payload = CreatePayload(ProviderEventTypes.ProviderError, message); - payload.ErrorType = ErrorType.ProviderFatal; - - if (!EventChannel.Writer.TryWrite(payload)) - { - _ = WriteWhenRoomAvailableAsync(payload); - } - } - private void SignalReady() { var payload = CreatePayload(ProviderEventTypes.ProviderReady, "Feature flag configuration was received."); @@ -139,9 +133,9 @@ private void SignalReady() } // Unlike a change notification, this one cannot be dropped: losing it would leave the provider - // reported as errored for the rest of the process even though it can now resolve flags. The - // channel holds a single item, so waiting for room happens in the background rather than on the - // thread applying the configuration. Only ever one such write exists, because it is signalled once. + // reported as errored even though it can now resolve flags. The channel holds a single item, so + // waiting for room happens in the background rather than on the thread applying the + // configuration. _ = WriteWhenRoomAvailableAsync(payload); } @@ -177,8 +171,8 @@ private ProviderEventPayload CreatePayload(ProviderEventTypes type, string messa /// not reach the application, because OpenFeature handles it while setting the provider. /// /// - /// This provider emits its own status event either way, rather than leaving the SDK to infer one - /// from how this method returns. + /// No status event is emitted here. OpenFeature derives the provider's initial status from how + /// this method returns, so the provider only reports the transitions that happen afterwards. /// /// /// Evaluation context @@ -192,19 +186,17 @@ public override async Task InitializeAsync(EvaluationContext context, Cancellati } catch (Exception exception) { - SignalInitializationFailed(exception.Message); + Volatile.Write(ref _status, StatusError); // Irrecoverable: no source can be started later in this process, so no configuration will - // ever arrive and every evaluation returns its default value. + // ever arrive and every evaluation returns its default value. OpenFeature reports the error + // status from this exception. throw new ProviderFatalException(exception.Message, exception); } - // Configuration that arrived before the application registered this provider leaves nothing to - // signal from the configuration callback, so the ready event is emitted here instead. - if (FeatureFlagsSdk.HasConfiguration() && Interlocked.CompareExchange(ref _readySignalled, 1, 0) == 0) - { - SignalReady(); - } + // Recorded rather than signalled, because OpenFeature marks the provider ready as soon as this + // returns. It is what lets a later withdrawal be reported as a transition out of READY. + Volatile.Write(ref _status, StatusReady); } /// Gets provider metadata