< Summary

Information
Class: OpenAiIntegration.LangfuseActivityPropagation
Assembly: OpenAiIntegration
File(s): /home/runner/work/KicktippAi/KicktippAi/src/OpenAiIntegration/LangfuseActivityPropagation.cs
Line coverage
93%
Covered lines: 45
Uncovered lines: 3
Coverable lines: 48
Total lines: 122
Line coverage: 93.7%
Branch coverage
100%
Covered branches: 20
Total branches: 20
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
SetEnvironment(...)100%11100%
SetSessionId(...)100%11100%
SetTraceTags(...)100%1180%
SetExperimentName(...)100%11100%
SetExperimentDescription(...)100%11100%
SetExperimentItemId(...)100%11100%
SetExperimentItemRootObservationId(...)100%11100%
SetExperimentRunId(...)100%11100%
SetTraceMetadata(...)100%88100%
GetObservationMetadata(...)100%66100%
ClearTraceMetadata(...)100%1175%
RegisterTraceMetadata(...)100%2283.33%
SetTagAndBaggage(...)100%44100%

File(s)

/home/runner/work/KicktippAi/KicktippAi/src/OpenAiIntegration/LangfuseActivityPropagation.cs

#LineLine coverage
 1using System.Diagnostics;
 2using System.Collections.Concurrent;
 3using System.Text.Json;
 4
 5namespace OpenAiIntegration;
 6
 7/// <summary>
 8/// Utilities for propagating shared Langfuse trace context from a root activity to child observations.
 9/// </summary>
 10public static class LangfuseActivityPropagation
 11{
 112    private static readonly ConcurrentDictionary<string, ConcurrentDictionary<string, string>> TraceMetadataByTraceId = 
 13
 14    public static void SetEnvironment(Activity? activity, string? environment)
 15    {
 116        SetTagAndBaggage(activity, "langfuse.environment", environment);
 117    }
 18
 19    public static void SetSessionId(Activity? activity, string? sessionId)
 20    {
 121        SetTagAndBaggage(activity, "langfuse.session.id", sessionId);
 122    }
 23
 24    public static void SetTraceTags(Activity? activity, IReadOnlyCollection<string> tags)
 25    {
 126        if (activity is null || tags.Count == 0)
 27        {
 028            return;
 29        }
 30
 131        var serializedTags = JsonSerializer.Serialize(tags);
 132        SetTagAndBaggage(activity, "langfuse.trace.tags", serializedTags);
 133    }
 34
 35    public static void SetExperimentName(Activity? activity, string? experimentName)
 36    {
 137        SetTagAndBaggage(activity, "langfuse.experiment.name", experimentName);
 138    }
 39
 40    public static void SetExperimentDescription(Activity? activity, string? description)
 41    {
 142        SetTagAndBaggage(activity, "langfuse.experiment.description", description);
 143    }
 44
 45    public static void SetExperimentItemId(Activity? activity, string? itemId)
 46    {
 147        SetTagAndBaggage(activity, "langfuse.experiment.item.id", itemId);
 148    }
 49
 50    public static void SetExperimentItemRootObservationId(Activity? activity, string? rootObservationId)
 51    {
 152        SetTagAndBaggage(activity, "langfuse.experiment.item.root_observation_id", rootObservationId);
 153    }
 54
 55    public static void SetExperimentRunId(Activity? activity, string? datasetRunId)
 56    {
 157        SetTagAndBaggage(activity, "langfuse.experiment.id", datasetRunId);
 158    }
 59
 60    public static void SetTraceMetadata(Activity? activity, string metadataKey, string? value, bool propagateToObservati
 61    {
 162        if (activity is null || string.IsNullOrWhiteSpace(metadataKey) || string.IsNullOrWhiteSpace(value))
 63        {
 164            return;
 65        }
 66
 167        activity.SetTag($"langfuse.trace.metadata.{metadataKey}", value);
 68
 169        if (propagateToObservations)
 70        {
 171            activity.AddBaggage($"langfuse.observation.metadata.{metadataKey}", value);
 172            RegisterTraceMetadata(activity, metadataKey, value);
 73        }
 174    }
 75
 76    public static IEnumerable<KeyValuePair<string, string>> GetObservationMetadata(Activity activity)
 77    {
 178        if (activity.TraceId == default)
 79        {
 180            return [];
 81        }
 82
 183        return TraceMetadataByTraceId.TryGetValue(activity.TraceId.ToString(), out var metadata)
 184            ? metadata.Select(pair => new KeyValuePair<string, string>($"langfuse.observation.metadata.{pair.Key}", pair
 185            : [];
 86    }
 87
 88    public static void ClearTraceMetadata(Activity activity)
 89    {
 190        if (activity.TraceId == default)
 91        {
 092            return;
 93        }
 94
 195        TraceMetadataByTraceId.TryRemove(activity.TraceId.ToString(), out _);
 196    }
 97
 98    private static void RegisterTraceMetadata(Activity activity, string metadataKey, string value)
 99    {
 1100        if (activity.TraceId == default)
 101        {
 0102            return;
 103        }
 104
 1105        var traceMetadata = TraceMetadataByTraceId.GetOrAdd(
 1106            activity.TraceId.ToString(),
 1107            _ => new ConcurrentDictionary<string, string>(StringComparer.Ordinal));
 108
 1109        traceMetadata[metadataKey] = value;
 1110    }
 111
 112    private static void SetTagAndBaggage(Activity? activity, string attributeName, string? value)
 113    {
 1114        if (activity is null || string.IsNullOrWhiteSpace(value))
 115        {
 1116            return;
 117        }
 118
 1119        activity.SetTag(attributeName, value);
 1120        activity.AddBaggage(attributeName, value);
 1121    }
 122}