-
Notifications
You must be signed in to change notification settings - Fork 167
Expand file tree
/
Copy pathFeatureFlagsSdkEvaluateIntegration.cs
More file actions
73 lines (63 loc) · 3.5 KB
/
Copy pathFeatureFlagsSdkEvaluateIntegration.cs
File metadata and controls
73 lines (63 loc) · 3.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// <copyright file="FeatureFlagsSdkEvaluateIntegration.cs" company="Datadog">
// 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.
// </copyright>
#nullable enable
using System;
using System.Collections.Generic;
using System.ComponentModel;
using Datadog.Trace.ClrProfiler.CallTarget;
using Datadog.Trace.Configuration;
using Datadog.Trace.DuckTyping;
using Datadog.Trace.FeatureFlags;
namespace Datadog.Trace.ClrProfiler.AutoInstrumentation.Datadog_Trace_Manual;
/// <summary>
/// Datadog.Trace.FeatureFlags.IEvaluation Datadog.Trace.FeatureFlags.FeatureFlagsSdk::Evaluate(System.String,System.Type,System.Object,Datadog.Trace.FeatureFlags.IEvaluationContext) calltarget instrumentation
/// </summary>
[InstrumentMethod(
AssemblyName = "Datadog.Trace.Manual",
TypeName = "Datadog.Trace.FeatureFlags.FeatureFlagsSdk",
MethodName = "Evaluate",
ReturnTypeName = "Datadog.Trace.FeatureFlags.IEvaluation",
ParameterTypeNames = [ClrNames.String, "Datadog.Trace.FeatureFlags.ValueType", ClrNames.Object, ClrNames.String, "System.Collections.Generic.IDictionary`2[System.String,System.Object]"],
MinimumVersion = "3.31.0",
MaximumVersion = "3.*.*",
IntegrationName = nameof(IntegrationId.DatadogTraceManual))]
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public sealed class FeatureFlagsSdkEvaluateIntegration
{
internal static CallTargetState OnMethodBegin<TTarget>(ref string flagKey, FeatureFlags.ValueType targetType, ref object? defaultValue, ref string? targetingKey, ref IDictionary<string, object?>? attributes)
{
return new CallTargetState(null, new State(flagKey, targetType, defaultValue, targetingKey, attributes));
}
internal static CallTargetReturn<TReturn?> OnMethodEnd<TTarget, TReturn>(TReturn? returnValue, Exception? exception, in CallTargetState state)
{
if (exception is not null)
{
// invalid call to the API e.g. non-null args were null. Just let it bubble up.
return new CallTargetReturn<TReturn?>(returnValue);
}
var tracer = Datadog.Trace.Tracer.Instance;
if (tracer.TracerManager.FeatureFlags is not { } flags)
{
// Feature flags disabled: don't touch async-local scope state for a no-op.
return new CallTargetReturn<TReturn?>(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;
// Skip creating per-trace state for evaluations that would record nothing.
if (traceContext is not null && SpanEnrichmentState.IsRecordable(res))
{
traceContext.GetOrCreateFeatureFlagEnrichment()?.AccumulateEvaluation(res, parameters.TargetingKey);
}
return new CallTargetReturn<TReturn?>(res.DuckCast<TReturn>());
}
private sealed record State(string FlagKey, FeatureFlags.ValueType TargetType, object? DefaultValue, string? TargetingKey, IDictionary<string, object?>? Attributes)
{
}
}