diff --git a/pkgs/telemetry/src/TracingHook.cs b/pkgs/telemetry/src/TracingHook.cs
index 81323cf0..61d19f8d 100644
--- a/pkgs/telemetry/src/TracingHook.cs
+++ b/pkgs/telemetry/src/TracingHook.cs
@@ -15,13 +15,13 @@ namespace LaunchDarkly.Sdk.Server.Telemetry
public class TracingHookBuilder
{
private bool _createActivities;
- private bool _includeVariant;
+ private bool _includeValue;
private string _environmentId;
internal TracingHookBuilder()
{
_createActivities = false;
- _includeVariant = false;
+ _includeValue = false;
_environmentId = null;
}
@@ -41,15 +41,28 @@ public TracingHookBuilder CreateActivities(bool createActivities = true)
return this;
}
+ ///
+ /// The TracingHook will include the flag value in the current activity, if one exists.
+ /// The value representation is a JSON string. Disabled by default.
+ ///
+ /// true to include value, false otherwise
+ /// this builder
+ public TracingHookBuilder IncludeValue(bool includeValue = true)
+ {
+ _includeValue = includeValue;
+ return this;
+ }
+
///
/// The TracingHook will include the flag variant in the current activity, if one exists.
/// The variant representation is a JSON string. Disabled by default.
///
/// true to include variants, false otherwise
/// this builder
+ [System.Obsolete("IncludeVariant is deprecated. Use IncludeValue instead.")]
public TracingHookBuilder IncludeVariant(bool includeVariant = true)
{
- _includeVariant = includeVariant;
+ _includeValue = includeVariant;
return this;
}
@@ -77,7 +90,7 @@ public TracingHookBuilder EnvironmentId(string environmentId)
/// the new hook
public TracingHook Build()
{
- return new TracingHook(new TracingHook.Options(_createActivities, _includeVariant, _environmentId));
+ return new TracingHook(new TracingHook.Options(_createActivities, _includeValue, _environmentId));
}
}
@@ -107,23 +120,25 @@ private static class SemanticAttributes
{
public const string EventName = "feature_flag";
public const string FeatureFlagKey = "feature_flag.key";
- public const string FeatureFlagProviderName = "feature_flag.provider_name";
- public const string FeatureFlagVariant = "feature_flag.variant";
- public const string FeatureFlagContextKeyAttributeName = "feature_flag.context.key";
+ public const string FeatureFlagProviderName = "feature_flag.provider.name";
+ public const string FeatureFlagValue = "feature_flag.result.value";
+ public const string FeatureFlagVariationIndex = "feature_flag.result.variationIndex";
+ public const string FeatureFlagInExperiment = "feature_flag.result.reason.inExperiment";
+ public const string FeatureFlagContextKeyAttributeName = "feature_flag.context.id";
public const string FeatureFlagSetId = "feature_flag.set.id";
}
internal struct Options
{
public bool CreateActivities { get; }
- public bool IncludeVariant { get; }
+ public bool IncludeValue { get; }
public string EnvironmentId { get; }
- public Options(bool createActivities, bool includeVariant, string environmentId = null)
+ public Options(bool createActivities, bool includeValue, string environmentId = null)
{
CreateActivities = createActivities;
- IncludeVariant = includeVariant;
+ IncludeValue = includeValue;
EnvironmentId = environmentId;
}
}
@@ -179,7 +194,7 @@ public override SeriesData BeforeEvaluation(EvaluationSeriesContext context, Ser
///
/// Ends the activity created in BeforeEvaluation, if it exists. Adds the feature flag key, provider name, and context key
- /// to the existing activity. If IncludeVariant is enabled, also adds the variant.
+ /// to the existing activity. If includeValue is enabled, also adds the variant.
///
/// the evaluation parameters
/// the series data
@@ -216,9 +231,19 @@ public override SeriesData AfterEvaluation(EvaluationSeriesContext context, Seri
attributes[SemanticAttributes.FeatureFlagSetId] = context.EnvironmentId;
}
- if (_options.IncludeVariant)
+ if (_options.IncludeValue)
+ {
+ attributes.Add(SemanticAttributes.FeatureFlagValue, detail.Value.ToJsonString());
+ }
+
+ if (detail.Reason.InExperiment)
+ {
+ attributes.Add(SemanticAttributes.FeatureFlagInExperiment, detail.Reason.InExperiment);
+ }
+
+ if (detail.VariationIndex.HasValue)
{
- attributes.Add(SemanticAttributes.FeatureFlagVariant, detail.Value.ToJsonString());
+ attributes.Add(SemanticAttributes.FeatureFlagVariationIndex, detail.VariationIndex.Value);
}
Activity.Current?.AddEvent(new ActivityEvent(name: SemanticAttributes.EventName, tags: attributes));
diff --git a/pkgs/telemetry/test/TracingHookTests.cs b/pkgs/telemetry/test/TracingHookTests.cs
index 70c2402c..d2d48305 100644
--- a/pkgs/telemetry/test/TracingHookTests.cs
+++ b/pkgs/telemetry/test/TracingHookTests.cs
@@ -37,10 +37,10 @@ public void CanRetrieveActivitySourceName()
[InlineData(false, true)]
[InlineData(true, false)]
[InlineData(true, true)]
- public void ConfigurationOptionsDoNotThrowExceptions(bool includeVariant, bool createSpans)
+ public void ConfigurationOptionsDoNotThrowExceptions(bool includeValue, bool createSpans)
{
var hook = TracingHook.Builder()
- .IncludeVariant(includeVariant)
+ .IncludeValue(includeValue)
.CreateActivities(createSpans)
.Build();
var context = new EvaluationSeriesContext("foo", Context.New("bar"), LdValue.Null, "testMethod");
@@ -164,7 +164,7 @@ public void TracingHookCreatesChildSpans(bool createSpans)
[Theory]
[InlineData(true)]
[InlineData(false)]
- public void TracingHookIncludesVariant(bool includeVariant)
+ public void TracingHookIncludesVariant(bool includeValue)
{
ICollection exportedItems = new Collection();
@@ -178,7 +178,7 @@ public void TracingHookIncludesVariant(bool includeVariant)
var testSource = new ActivitySource("test-source", "1.0.0");
- var hookUnderTest = TracingHook.Builder().IncludeVariant(includeVariant).Build();
+ var hookUnderTest = TracingHook.Builder().IncludeValue(includeValue).Build();
var featureKey = "feature-key";
var context = Context.New("foo");
@@ -203,21 +203,21 @@ public void TracingHookIncludesVariant(bool includeVariant)
Assert.Single(items);
Assert.Equal("root-activity", items[0].OperationName);
- if (includeVariant)
+ if (includeValue)
{
// The idea is to check that the span has two events attached to it, and those events contain the feature
// flag variants. It's awkward to check because we don't know the exact order of the events or those
// events' tags.
var events = items[0].Events;
Assert.Single(events.Where(e =>
- e.Tags.Contains(new KeyValuePair("feature_flag.variant", "true"))));
+ e.Tags.Contains(new KeyValuePair("feature_flag.result.value", "true"))));
Assert.Single(events.Where(e =>
- e.Tags.Contains(new KeyValuePair("feature_flag.variant", "\"default\""))));
+ e.Tags.Contains(new KeyValuePair("feature_flag.result.value", "\"default\""))));
}
else
{
// If not including the variant, then we shouldn't see any variant tag on any events.
- Assert.All(items, i => i.Events.All(e => e.Tags.All(kvp => kvp.Key != "feature_flag.variant")));
+ Assert.All(items, i => i.Events.All(e => e.Tags.All(kvp => kvp.Key != "feature_flag.result.value")));
}
}