| File: System\Diagnostics\ActivityCreationOptions.cs | Web Access |
| Project: src\runtime\src\libraries\System.Diagnostics.DiagnosticSource\src\System.Diagnostics.DiagnosticSource.csproj (System.Diagnostics.DiagnosticSource) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; using System.Runtime.CompilerServices; namespace System.Diagnostics { /// <summary> /// ActivityCreationOptions is encapsulating all needed information which will be sent to the ActivityListener to decide about creating the Activity object and with what state. /// The possible generic type parameters is <see cref="ActivityContext"/> or <see cref="string"/> /// </summary> public readonly struct ActivityCreationOptions<T> { private readonly ActivityTagsCollection? _samplerTags; private readonly ActivityContext _context; private readonly string? _traceState; /// <summary> /// Construct a new <see cref="ActivityCreationOptions{T}"/> object. /// </summary> /// <param name="source">The trace Activity source<see cref="ActivitySource"/> used to request creating the Activity object.</param> /// <param name="name">The operation name of the Activity.</param> /// <param name="parent">The requested parent to create the Activity object with. The parent either be a parent Id represented as string or it can be a parent context <see cref="ActivityContext"/>.</param> /// <param name="kind"><see cref="ActivityKind"/> to create the Activity object with.</param> /// <param name="tags">Key-value pairs list for the tags to create the Activity object with.<see cref="ActivityContext"/></param> /// <param name="links"><see cref="ActivityLink"/> list to create the Activity object with.</param> /// <param name="idFormat">The default Id format to use.</param> internal ActivityCreationOptions(ActivitySource source, string name, T parent, ActivityKind kind, IEnumerable<KeyValuePair<string, object?>>? tags, IEnumerable<ActivityLink>? links, ActivityIdFormat idFormat) { Source = source; Name = name; Kind = kind; Parent = parent; Tags = tags; Links = links; IdFormat = idFormat; if (IdFormat == ActivityIdFormat.Unknown && Activity.ForceDefaultIdFormat) { IdFormat = Activity.DefaultIdFormat; } _samplerTags = null; _traceState = null; if (parent is ActivityContext ac && ac != default) { _context = ac; if (IdFormat == ActivityIdFormat.Unknown) { IdFormat = ActivityIdFormat.W3C; } _traceState = ac.TraceState; } else if (parent is string p) { if (IdFormat != ActivityIdFormat.Hierarchical) { if (ActivityContext.TryParse(p, null, out _context)) { IdFormat = ActivityIdFormat.W3C; } if (IdFormat == ActivityIdFormat.Unknown) { IdFormat = ActivityIdFormat.Hierarchical; } } else { _context = default; } } else { _context = default; if (IdFormat == ActivityIdFormat.Unknown) { IdFormat = Activity.Current != null ? Activity.Current.IdFormat : Activity.DefaultIdFormat; } } } /// <summary> /// Retrieve the <see cref="ActivitySource"/> object. /// </summary> public ActivitySource Source { get; } /// <summary> /// Retrieve the name which requested to create the Activity object with. /// </summary> public string Name { get; } /// <summary> /// Retrieve the <see cref="ActivityKind"/> which requested to create the Activity object with. /// </summary> public ActivityKind Kind { get; } /// <summary> /// Retrieve the parent which requested to create the Activity object with. Parent will be either in form of string or <see cref="ActivityContext"/>. /// </summary> public T Parent { get; } /// <summary> /// Retrieve the tags which requested to create the Activity object with. /// </summary> public IEnumerable<KeyValuePair<string, object?>>? Tags { get; } /// <summary> /// Retrieve the list of <see cref="ActivityLink"/> which requested to create the Activity object with. /// </summary> public IEnumerable<ActivityLink>? Links { get; } public ActivityTagsCollection SamplingTags { get { if (_samplerTags == null) { // Because the struct is readonly, we cannot directly assign _samplerTags. We have to workaround it by calling Unsafe.AsRef Unsafe.AsRef(in _samplerTags) = new ActivityTagsCollection(); } return _samplerTags!; } } public ActivityTraceId TraceId { get { if (Parent is ActivityContext && IdFormat == ActivityIdFormat.W3C && _context == default) { Func<ActivityTraceId>? traceIdGenerator = Activity.TraceIdGenerator; ActivityTraceId id; ActivityTraceFlags activityTraceFlags = ActivityTraceFlags.None; if (traceIdGenerator is null) { id = ActivityTraceId.CreateRandom(); activityTraceFlags = ActivityTraceFlags.RandomTraceId; } else { id = traceIdGenerator(); } // Because the struct is readonly, we cannot directly assign _context. We have to workaround it by calling Unsafe.AsRef Unsafe.AsRef(in _context) = new ActivityContext(id, default, activityTraceFlags); } return _context.TraceId; } } /// <summary> /// Retrieve or initialize the trace state to use for the Activity we may create. /// </summary> public string? TraceState { get => _traceState; init { _traceState = value; } } // SetTraceState is to set the _traceState without the need of copying the whole structure. internal void SetTraceState(string? traceState) => Unsafe.AsRef(in _traceState) = traceState; /// <summary> /// Retrieve Id format of to use for the Activity we may create. /// </summary> internal ActivityIdFormat IdFormat { get; } // Helper to access the sampling tags. The SamplingTags Getter can allocate when not necessary. internal ActivityTagsCollection? GetSamplingTags() => _samplerTags; internal ActivityContext GetContext() => _context; } }