Decompiled source of System Diagnostics DiagnosticSource v8.0.100
BepInEx/core/System.Diagnostics.DiagnosticSource/netstandard2.0/System.Diagnostics.DiagnosticSource.dll
Decompiled 8 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Buffers.Binary; using System.Buffers.Text; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Tracing; using System.Globalization; using System.Net; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using FxResources.System.Diagnostics.DiagnosticSource; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyMetadata("Serviceable", "True")] [assembly: AssemblyMetadata("PreferInbox", "True")] [assembly: AssemblyDefaultAlias("System.Diagnostics.DiagnosticSource")] [assembly: NeutralResourcesLanguage("en-US")] [assembly: CLSCompliant(true)] [assembly: AssemblyMetadata("IsTrimmable", "True")] [assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)] [assembly: AssemblyCompany("Microsoft Corporation")] [assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] [assembly: AssemblyDescription("Provides Classes that allow you to decouple code logging rich (unserializable) diagnostics/telemetry (e.g. framework) from code that consumes it (e.g. tools)\r\n\r\nCommonly Used Types:\r\nSystem.Diagnostics.DiagnosticListener\r\nSystem.Diagnostics.DiagnosticSource")] [assembly: AssemblyFileVersion("8.0.424.16909")] [assembly: AssemblyInformationalVersion("8.0.4+2d7eea252964e69be94cb9c847b371b23e4dd470")] [assembly: AssemblyProduct("Microsoft® .NET")] [assembly: AssemblyTitle("System.Diagnostics.DiagnosticSource")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/dotnet/runtime")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("8.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: System.Runtime.CompilerServices.NullablePublicOnly(false)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsByRefLikeAttribute : Attribute { } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class NullablePublicOnlyAttribute : Attribute { public readonly bool IncludesInternals; public NullablePublicOnlyAttribute(bool P_0) { IncludesInternals = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace FxResources.System.Diagnostics.DiagnosticSource { internal static class SR { } } namespace System { internal static class HexConverter { public enum Casing : uint { Upper = 0u, Lower = 8224u } public static ReadOnlySpan<byte> CharToHexLookup => new byte[256] { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255, 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ToBytesBuffer(byte value, Span<byte> buffer, int startingIndex = 0, Casing casing = Casing.Upper) { uint num = (uint)(((value & 0xF0) << 4) + (value & 0xF) - 35209); uint num2 = ((((0 - num) & 0x7070) >> 4) + num + 47545) | (uint)casing; buffer[startingIndex + 1] = (byte)num2; buffer[startingIndex] = (byte)(num2 >> 8); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ToCharsBuffer(byte value, Span<char> buffer, int startingIndex = 0, Casing casing = Casing.Upper) { uint num = (uint)(((value & 0xF0) << 4) + (value & 0xF) - 35209); uint num2 = ((((0 - num) & 0x7070) >> 4) + num + 47545) | (uint)casing; buffer[startingIndex + 1] = (char)(num2 & 0xFFu); buffer[startingIndex] = (char)(num2 >> 8); } public static void EncodeToUtf16(ReadOnlySpan<byte> bytes, Span<char> chars, Casing casing = Casing.Upper) { for (int i = 0; i < bytes.Length; i++) { ToCharsBuffer(bytes[i], chars, i * 2, casing); } } public static string ToString(ReadOnlySpan<byte> bytes, Casing casing = Casing.Upper) { Span<char> span = ((bytes.Length <= 16) ? stackalloc char[bytes.Length * 2] : new char[bytes.Length * 2].AsSpan()); Span<char> buffer = span; int num = 0; ReadOnlySpan<byte> readOnlySpan = bytes; for (int i = 0; i < readOnlySpan.Length; i++) { byte value = readOnlySpan[i]; ToCharsBuffer(value, buffer, num, casing); num += 2; } return buffer.ToString(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static char ToCharUpper(int value) { value &= 0xF; value += 48; if (value > 57) { value += 7; } return (char)value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static char ToCharLower(int value) { value &= 0xF; value += 48; if (value > 57) { value += 39; } return (char)value; } public static bool TryDecodeFromUtf16(ReadOnlySpan<char> chars, Span<byte> bytes) { int charsProcessed; return TryDecodeFromUtf16(chars, bytes, out charsProcessed); } public static bool TryDecodeFromUtf16(ReadOnlySpan<char> chars, Span<byte> bytes, out int charsProcessed) { int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; while (num2 < bytes.Length) { num3 = FromChar(chars[num + 1]); num4 = FromChar(chars[num]); if ((num3 | num4) == 255) { break; } bytes[num2++] = (byte)((num4 << 4) | num3); num += 2; } if (num3 == 255) { num++; } charsProcessed = num; return (num3 | num4) != 255; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int FromChar(int c) { if (c < CharToHexLookup.Length) { return CharToHexLookup[c]; } return 255; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int FromUpperChar(int c) { if (c <= 71) { return CharToHexLookup[c]; } return 255; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int FromLowerChar(int c) { switch (c) { case 48: case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: return c - 48; case 97: case 98: case 99: case 100: case 101: case 102: return c - 97 + 10; default: return 255; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsHexChar(int c) { if (IntPtr.Size == 8) { ulong num = (uint)(c - 48); ulong num2 = (ulong)(-17875860044349952L << (int)num); ulong num3 = num - 64; return (long)(num2 & num3) < 0L; } return FromChar(c) != 255; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsHexUpperChar(int c) { if ((uint)(c - 48) > 9u) { return (uint)(c - 65) <= 5u; } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsHexLowerChar(int c) { if ((uint)(c - 48) > 9u) { return (uint)(c - 97) <= 5u; } return true; } } internal static class SR { private static readonly bool s_usingResourceKeys = AppContext.TryGetSwitch("System.Resources.UseSystemResourceKeys", out var isEnabled) && isEnabled; private static ResourceManager s_resourceManager; internal static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(typeof(SR))); internal static string ActivityIdFormatInvalid => GetResourceString("ActivityIdFormatInvalid"); internal static string ActivityNotRunning => GetResourceString("ActivityNotRunning"); internal static string ActivityNotStarted => GetResourceString("ActivityNotStarted"); internal static string ActivityStartAlreadyStarted => GetResourceString("ActivityStartAlreadyStarted"); internal static string ActivitySetParentAlreadyStarted => GetResourceString("ActivitySetParentAlreadyStarted"); internal static string EndTimeNotUtc => GetResourceString("EndTimeNotUtc"); internal static string OperationNameInvalid => GetResourceString("OperationNameInvalid"); internal static string ParentIdAlreadySet => GetResourceString("ParentIdAlreadySet"); internal static string ParentIdInvalid => GetResourceString("ParentIdInvalid"); internal static string SetFormatOnStartedActivity => GetResourceString("SetFormatOnStartedActivity"); internal static string SetParentIdOnActivityWithParent => GetResourceString("SetParentIdOnActivityWithParent"); internal static string StartTimeNotUtc => GetResourceString("StartTimeNotUtc"); internal static string KeyAlreadyExist => GetResourceString("KeyAlreadyExist"); internal static string InvalidTraceParent => GetResourceString("InvalidTraceParent"); internal static string UnableAccessServicePointTable => GetResourceString("UnableAccessServicePointTable"); internal static string UnableToInitialize => GetResourceString("UnableToInitialize"); internal static string UnsupportedType => GetResourceString("UnsupportedType"); internal static string Arg_BufferTooSmall => GetResourceString("Arg_BufferTooSmall"); internal static string InvalidInstrumentType => GetResourceString("InvalidInstrumentType"); internal static bool UsingResourceKeys() { return s_usingResourceKeys; } private static string GetResourceString(string resourceKey) { if (UsingResourceKeys()) { return resourceKey; } string result = null; try { result = ResourceManager.GetString(resourceKey); } catch (MissingManifestResourceException) { } return result; } private static string GetResourceString(string resourceKey, string defaultString) { string resourceString = GetResourceString(resourceKey); if (!(resourceKey == resourceString) && resourceString != null) { return resourceString; } return defaultString; } internal static string Format(string resourceFormat, object p1) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1); } return string.Format(resourceFormat, p1); } internal static string Format(string resourceFormat, object p1, object p2) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1, p2); } return string.Format(resourceFormat, p1, p2); } internal static string Format(string resourceFormat, object p1, object p2, object p3) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1, p2, p3); } return string.Format(resourceFormat, p1, p2, p3); } internal static string Format(string resourceFormat, params object[] args) { if (args != null) { if (UsingResourceKeys()) { return resourceFormat + ", " + string.Join(", ", args); } return string.Format(resourceFormat, args); } return resourceFormat; } internal static string Format(IFormatProvider provider, string resourceFormat, object p1) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1); } return string.Format(provider, resourceFormat, p1); } internal static string Format(IFormatProvider provider, string resourceFormat, object p1, object p2) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1, p2); } return string.Format(provider, resourceFormat, p1, p2); } internal static string Format(IFormatProvider provider, string resourceFormat, object p1, object p2, object p3) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1, p2, p3); } return string.Format(provider, resourceFormat, p1, p2, p3); } internal static string Format(IFormatProvider provider, string resourceFormat, params object[] args) { if (args != null) { if (UsingResourceKeys()) { return resourceFormat + ", " + string.Join(", ", args); } return string.Format(provider, resourceFormat, args); } return resourceFormat; } } } namespace System.Runtime.Versioning { internal abstract class OSPlatformAttribute : Attribute { public string PlatformName { get; } private protected OSPlatformAttribute(string platformName) { PlatformName = platformName; } } [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false, Inherited = false)] internal sealed class TargetPlatformAttribute : OSPlatformAttribute { public TargetPlatformAttribute(string platformName) : base(platformName) { } } [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface, AllowMultiple = true, Inherited = false)] internal sealed class SupportedOSPlatformAttribute : OSPlatformAttribute { public SupportedOSPlatformAttribute(string platformName) : base(platformName) { } } [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface, AllowMultiple = true, Inherited = false)] internal sealed class UnsupportedOSPlatformAttribute : OSPlatformAttribute { public string Message { get; } public UnsupportedOSPlatformAttribute(string platformName) : base(platformName) { } public UnsupportedOSPlatformAttribute(string platformName, string message) : base(platformName) { Message = message; } } [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface, AllowMultiple = true, Inherited = false)] internal sealed class ObsoletedOSPlatformAttribute : OSPlatformAttribute { public string Message { get; } public string Url { get; set; } public ObsoletedOSPlatformAttribute(string platformName) : base(platformName) { } public ObsoletedOSPlatformAttribute(string platformName, string message) : base(platformName) { Message = message; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true, Inherited = false)] internal sealed class SupportedOSPlatformGuardAttribute : OSPlatformAttribute { public SupportedOSPlatformGuardAttribute(string platformName) : base(platformName) { } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true, Inherited = false)] internal sealed class UnsupportedOSPlatformGuardAttribute : OSPlatformAttribute { public UnsupportedOSPlatformGuardAttribute(string platformName) : base(platformName) { } } } namespace System.Runtime.InteropServices { [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class LibraryImportAttribute : Attribute { public string LibraryName { get; } public string EntryPoint { get; set; } public StringMarshalling StringMarshalling { get; set; } public Type StringMarshallingCustomType { get; set; } public bool SetLastError { get; set; } public LibraryImportAttribute(string libraryName) { LibraryName = libraryName; } } internal enum StringMarshalling { Custom, Utf8, Utf16 } } namespace System.Runtime.CompilerServices { [EditorBrowsable(EditorBrowsableState.Never)] internal static class IsExternalInit { } } namespace System.Diagnostics { public readonly struct ActivityChangedEventArgs { public Activity? Previous { get; init; } public Activity? Current { get; init; } internal ActivityChangedEventArgs(Activity previous, Activity current) { Previous = previous; Current = current; } } public class Activity : IDisposable { public struct Enumerator<T> { private static readonly DiagNode<T> s_Empty = new DiagNode<T>(default(T)); private DiagNode<T> _nextNode; private DiagNode<T> _currentNode; public readonly ref T Current => ref _currentNode.Value; internal Enumerator(DiagNode<T> head) { _nextNode = head; _currentNode = s_Empty; } [EditorBrowsable(EditorBrowsableState.Never)] public readonly Enumerator<T> GetEnumerator() { return this; } public bool MoveNext() { if (_nextNode == null) { _currentNode = s_Empty; return false; } _currentNode = _nextNode; _nextNode = _nextNode.Next; return true; } } private sealed class BaggageLinkedList : IEnumerable<KeyValuePair<string, string>>, IEnumerable { private DiagNode<KeyValuePair<string, string>> _first; public DiagNode<KeyValuePair<string, string>> First => _first; public BaggageLinkedList(KeyValuePair<string, string> firstValue, bool set = false) { _first = ((set && firstValue.Value == null) ? null : new DiagNode<KeyValuePair<string, string>>(firstValue)); } public void Add(KeyValuePair<string, string> value) { DiagNode<KeyValuePair<string, string>> diagNode = new DiagNode<KeyValuePair<string, string>>(value); lock (this) { diagNode.Next = _first; _first = diagNode; } } public void Set(KeyValuePair<string, string> value) { if (value.Value == null) { Remove(value.Key); return; } lock (this) { for (DiagNode<KeyValuePair<string, string>> diagNode = _first; diagNode != null; diagNode = diagNode.Next) { if (diagNode.Value.Key == value.Key) { diagNode.Value = value; return; } } DiagNode<KeyValuePair<string, string>> diagNode2 = new DiagNode<KeyValuePair<string, string>>(value); diagNode2.Next = _first; _first = diagNode2; } } public void Remove(string key) { lock (this) { if (_first == null) { return; } if (_first.Value.Key == key) { _first = _first.Next; return; } DiagNode<KeyValuePair<string, string>> diagNode = _first; while (diagNode.Next != null) { if (diagNode.Next.Value.Key == key) { diagNode.Next = diagNode.Next.Next; break; } diagNode = diagNode.Next; } } } public DiagEnumerator<KeyValuePair<string, string>> GetEnumerator() { return new DiagEnumerator<KeyValuePair<string, string>>(_first); } IEnumerator<KeyValuePair<string, string>> IEnumerable<KeyValuePair<string, string>>.GetEnumerator() { return GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } internal sealed class TagsLinkedList : IEnumerable<KeyValuePair<string, object>>, IEnumerable { private DiagNode<KeyValuePair<string, object>> _first; private DiagNode<KeyValuePair<string, object>> _last; private StringBuilder _stringBuilder; public DiagNode<KeyValuePair<string, object>> First => _first; public TagsLinkedList(KeyValuePair<string, object> firstValue, bool set = false) { _last = (_first = ((set && firstValue.Value == null) ? null : new DiagNode<KeyValuePair<string, object>>(firstValue))); } public TagsLinkedList(IEnumerator<KeyValuePair<string, object>> e) { _last = (_first = new DiagNode<KeyValuePair<string, object>>(e.Current)); while (e.MoveNext()) { _last.Next = new DiagNode<KeyValuePair<string, object>>(e.Current); _last = _last.Next; } } public TagsLinkedList(IEnumerable<KeyValuePair<string, object>> list) { Add(list); } public void Add(IEnumerable<KeyValuePair<string, object>> list) { IEnumerator<KeyValuePair<string, object>> enumerator = list.GetEnumerator(); if (enumerator.MoveNext()) { if (_first == null) { _last = (_first = new DiagNode<KeyValuePair<string, object>>(enumerator.Current)); } else { _last.Next = new DiagNode<KeyValuePair<string, object>>(enumerator.Current); _last = _last.Next; } while (enumerator.MoveNext()) { _last.Next = new DiagNode<KeyValuePair<string, object>>(enumerator.Current); _last = _last.Next; } } } public void Add(KeyValuePair<string, object> value) { DiagNode<KeyValuePair<string, object>> diagNode = new DiagNode<KeyValuePair<string, object>>(value); lock (this) { if (_first == null) { _first = (_last = diagNode); return; } _last.Next = diagNode; _last = diagNode; } } public object Get(string key) { for (DiagNode<KeyValuePair<string, object>> diagNode = _first; diagNode != null; diagNode = diagNode.Next) { if (diagNode.Value.Key == key) { return diagNode.Value.Value; } } return null; } public void Remove(string key) { lock (this) { if (_first == null) { return; } if (_first.Value.Key == key) { _first = _first.Next; if (_first == null) { _last = null; } return; } DiagNode<KeyValuePair<string, object>> diagNode = _first; while (diagNode.Next != null) { if (diagNode.Next.Value.Key == key) { if (_last == diagNode.Next) { _last = diagNode; } diagNode.Next = diagNode.Next.Next; break; } diagNode = diagNode.Next; } } } public void Set(KeyValuePair<string, object> value) { if (value.Value == null) { Remove(value.Key); return; } lock (this) { for (DiagNode<KeyValuePair<string, object>> diagNode = _first; diagNode != null; diagNode = diagNode.Next) { if (diagNode.Value.Key == value.Key) { diagNode.Value = value; return; } } DiagNode<KeyValuePair<string, object>> diagNode2 = new DiagNode<KeyValuePair<string, object>>(value); if (_first == null) { _first = (_last = diagNode2); return; } _last.Next = diagNode2; _last = diagNode2; } } public DiagEnumerator<KeyValuePair<string, object>> GetEnumerator() { return new DiagEnumerator<KeyValuePair<string, object>>(_first); } IEnumerator<KeyValuePair<string, object>> IEnumerable<KeyValuePair<string, object>>.GetEnumerator() { return GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public IEnumerable<KeyValuePair<string, string>> EnumerateStringValues() { for (DiagNode<KeyValuePair<string, object>> current = _first; current != null; current = current.Next) { if (current.Value.Value is string || current.Value.Value == null) { yield return new KeyValuePair<string, string>(current.Value.Key, (string)current.Value.Value); } } } public override string ToString() { lock (this) { if (_first == null) { return string.Empty; } if (_stringBuilder == null) { _stringBuilder = new StringBuilder(); } _stringBuilder.Append(_first.Value.Key); _stringBuilder.Append(':'); _stringBuilder.Append(_first.Value.Value); for (DiagNode<KeyValuePair<string, object>> next = _first.Next; next != null; next = next.Next) { _stringBuilder.Append(", "); _stringBuilder.Append(next.Value.Key); _stringBuilder.Append(':'); _stringBuilder.Append(next.Value.Value); } string result = _stringBuilder.ToString(); _stringBuilder.Clear(); return result; } } } [Flags] private enum State : byte { None = 0, FormatUnknown = 0, FormatHierarchical = 1, FormatW3C = 2, FormatFlags = 3, IsStopped = 0x80 } private static readonly IEnumerable<KeyValuePair<string, string>> s_emptyBaggageTags = new KeyValuePair<string, string>[0]; private static readonly IEnumerable<KeyValuePair<string, object>> s_emptyTagObjects = new KeyValuePair<string, object>[0]; private static readonly IEnumerable<ActivityLink> s_emptyLinks = new ActivityLink[0]; private static readonly IEnumerable<ActivityEvent> s_emptyEvents = new ActivityEvent[0]; private static readonly ActivitySource s_defaultSource = new ActivitySource(string.Empty); private const byte ActivityTraceFlagsIsSet = 128; private const int RequestIdMaxLength = 1024; private static readonly string s_uniqSuffix = $"-{GetRandomNumber():x}."; private static long s_currentRootId = (uint)GetRandomNumber(); private static ActivityIdFormat s_defaultIdFormat; private string _traceState; private State _state; private int _currentChildId; private string _id; private string _rootId; private string _parentId; private string _parentSpanId; private string _traceId; private string _spanId; private byte _w3CIdFlags; private byte _parentTraceFlags; private TagsLinkedList _tags; private BaggageLinkedList _baggage; private DiagLinkedList<ActivityLink> _links; private DiagLinkedList<ActivityEvent> _events; private Dictionary<string, object> _customProperties; private string _displayName; private ActivityStatusCode _statusCode; private string _statusDescription; private Activity _previousActiveActivity; private static readonly AsyncLocal<Activity> s_current = new AsyncLocal<Activity>(); public static bool ForceDefaultIdFormat { get; set; } public ActivityStatusCode Status => _statusCode; public string? StatusDescription => _statusDescription; public bool HasRemoteParent { get; private set; } public ActivityKind Kind { get; private set; } public string OperationName { get; } public string DisplayName { get { return _displayName ?? OperationName; } set { _displayName = value ?? throw new ArgumentNullException("value"); } } public ActivitySource Source { get; private set; } public Activity? Parent { get; private set; } public TimeSpan Duration { get; private set; } public DateTime StartTimeUtc { get; private set; } public string? Id { get { if (_id == null && _spanId != null) { Span<char> buffer = stackalloc char[2]; System.HexConverter.ToCharsBuffer((byte)(0xFFFFFF7Fu & _w3CIdFlags), buffer, 0, System.HexConverter.Casing.Lower); string value = "00-" + _traceId + "-" + _spanId + "-" + buffer; Interlocked.CompareExchange(ref _id, value, null); } return _id; } } public string? ParentId { get { if (_parentId == null) { if (_parentSpanId != null) { Span<char> buffer = stackalloc char[2]; System.HexConverter.ToCharsBuffer((byte)(0xFFFFFF7Fu & _parentTraceFlags), buffer, 0, System.HexConverter.Casing.Lower); string value = "00-" + _traceId + "-" + _parentSpanId + "-" + buffer; Interlocked.CompareExchange(ref _parentId, value, null); } else if (Parent != null) { Interlocked.CompareExchange(ref _parentId, Parent.Id, null); } } return _parentId; } } public string? RootId { get { if (_rootId == null) { string text = null; if (Id != null) { text = GetRootId(Id); } else if (ParentId != null) { text = GetRootId(ParentId); } if (text != null) { Interlocked.CompareExchange(ref _rootId, text, null); } } return _rootId; } } public IEnumerable<KeyValuePair<string, string?>> Tags => _tags?.EnumerateStringValues() ?? s_emptyBaggageTags; public IEnumerable<KeyValuePair<string, object?>> TagObjects { get { IEnumerable<KeyValuePair<string, object>> tags = _tags; return tags ?? s_emptyTagObjects; } } public IEnumerable<ActivityEvent> Events { get { IEnumerable<ActivityEvent> events = _events; return events ?? s_emptyEvents; } } public IEnumerable<ActivityLink> Links { get { IEnumerable<ActivityLink> links = _links; return links ?? s_emptyLinks; } } public IEnumerable<KeyValuePair<string, string?>> Baggage { get { for (Activity activity2 = this; activity2 != null; activity2 = activity2.Parent) { if (activity2._baggage != null) { return Iterate(activity2); } } return s_emptyBaggageTags; static IEnumerable<KeyValuePair<string, string>> Iterate(Activity activity) { do { if (activity._baggage != null) { for (DiagNode<KeyValuePair<string, string>> current = activity._baggage.First; current != null; current = current.Next) { yield return current.Value; } } activity = activity.Parent; } while (activity != null); } } } public ActivityContext Context => new ActivityContext(TraceId, SpanId, ActivityTraceFlags, TraceStateString); public string? TraceStateString { get { for (Activity activity = this; activity != null; activity = activity.Parent) { string traceState = activity._traceState; if (traceState != null) { return traceState; } } return null; } set { _traceState = value; } } public ActivitySpanId SpanId { get { if (_spanId == null && _id != null && IdFormat == ActivityIdFormat.W3C) { string value = ActivitySpanId.CreateFromString(_id.AsSpan(36, 16)).ToHexString(); Interlocked.CompareExchange(ref _spanId, value, null); } return new ActivitySpanId(_spanId); } } public ActivityTraceId TraceId { get { if (_traceId == null) { TrySetTraceIdFromParent(); } return new ActivityTraceId(_traceId); } } public bool Recorded => (ActivityTraceFlags & ActivityTraceFlags.Recorded) != 0; public bool IsAllDataRequested { get; set; } public ActivityTraceFlags ActivityTraceFlags { get { if (!W3CIdFlagsSet) { TrySetTraceFlagsFromParent(); } return (ActivityTraceFlags)(-129 & (int)_w3CIdFlags); } set { _w3CIdFlags = (byte)(0x80u | (byte)value); } } public ActivitySpanId ParentSpanId { get { if (_parentSpanId == null) { string text = null; if (_parentId != null && IsW3CId(_parentId)) { try { text = ActivitySpanId.CreateFromString(_parentId.AsSpan(36, 16)).ToHexString(); } catch { } } else if (Parent != null && Parent.IdFormat == ActivityIdFormat.W3C) { text = Parent.SpanId.ToHexString(); } if (text != null) { Interlocked.CompareExchange(ref _parentSpanId, text, null); } } return new ActivitySpanId(_parentSpanId); } } public static Func<ActivityTraceId>? TraceIdGenerator { get; set; } public static ActivityIdFormat DefaultIdFormat { get { if (s_defaultIdFormat == ActivityIdFormat.Unknown) { s_defaultIdFormat = ActivityIdFormat.Hierarchical; } return s_defaultIdFormat; } set { if (ActivityIdFormat.Hierarchical > value || value > ActivityIdFormat.W3C) { throw new ArgumentException(System.SR.ActivityIdFormatInvalid); } s_defaultIdFormat = value; } } private bool W3CIdFlagsSet => (_w3CIdFlags & 0x80) != 0; public bool IsStopped { get { return (_state & State.IsStopped) != 0; } private set { if (value) { _state |= State.IsStopped; } else { _state &= ~State.IsStopped; } } } public ActivityIdFormat IdFormat { get { return (ActivityIdFormat)(_state & State.FormatFlags); } private set { _state = (_state & ~State.FormatFlags) | (State)((byte)value & 3u); } } public static Activity? Current { get { return s_current.Value; } set { if (ValidateSetCurrent(value)) { SetCurrent(value); } } } public static event EventHandler<ActivityChangedEventArgs>? CurrentChanged; public Activity SetStatus(ActivityStatusCode code, string? description = null) { _statusCode = code; _statusDescription = ((code == ActivityStatusCode.Error) ? description : null); return this; } public Enumerator<KeyValuePair<string, object?>> EnumerateTagObjects() { return new Enumerator<KeyValuePair<string, object>>(_tags?.First); } public Enumerator<ActivityEvent> EnumerateEvents() { return new Enumerator<ActivityEvent>(_events?.First); } public Enumerator<ActivityLink> EnumerateLinks() { return new Enumerator<ActivityLink>(_links?.First); } public string? GetBaggageItem(string key) { foreach (KeyValuePair<string, string> item in Baggage) { if (key == item.Key) { return item.Value; } } return null; } public object? GetTagItem(string key) { return _tags?.Get(key) ?? null; } public Activity(string operationName) { Source = s_defaultSource; IsAllDataRequested = true; if (string.IsNullOrEmpty(operationName)) { NotifyError(new ArgumentException(System.SR.OperationNameInvalid)); } OperationName = operationName ?? string.Empty; } public Activity AddTag(string key, string? value) { return AddTag(key, (object?)value); } public Activity AddTag(string key, object? value) { KeyValuePair<string, object> keyValuePair = new KeyValuePair<string, object>(key, value); if (_tags != null || Interlocked.CompareExchange(ref _tags, new TagsLinkedList(keyValuePair), null) != null) { _tags.Add(keyValuePair); } return this; } public Activity SetTag(string key, object? value) { KeyValuePair<string, object> keyValuePair = new KeyValuePair<string, object>(key, value); if (_tags != null || Interlocked.CompareExchange(ref _tags, new TagsLinkedList(keyValuePair, set: true), null) != null) { _tags.Set(keyValuePair); } return this; } public Activity AddEvent(ActivityEvent e) { if (_events != null || Interlocked.CompareExchange(ref _events, new DiagLinkedList<ActivityEvent>(e), null) != null) { _events.Add(e); } return this; } public Activity AddBaggage(string key, string? value) { KeyValuePair<string, string> keyValuePair = new KeyValuePair<string, string>(key, value); if (_baggage != null || Interlocked.CompareExchange(ref _baggage, new BaggageLinkedList(keyValuePair), null) != null) { _baggage.Add(keyValuePair); } return this; } public Activity SetBaggage(string key, string? value) { KeyValuePair<string, string> keyValuePair = new KeyValuePair<string, string>(key, value); if (_baggage != null || Interlocked.CompareExchange(ref _baggage, new BaggageLinkedList(keyValuePair, set: true), null) != null) { _baggage.Set(keyValuePair); } return this; } public Activity SetParentId(string parentId) { if (_id != null || _spanId != null) { NotifyError(new InvalidOperationException(System.SR.ActivitySetParentAlreadyStarted)); } else if (Parent != null) { NotifyError(new InvalidOperationException(System.SR.SetParentIdOnActivityWithParent)); } else if (ParentId != null || _parentSpanId != null) { NotifyError(new InvalidOperationException(System.SR.ParentIdAlreadySet)); } else if (string.IsNullOrEmpty(parentId)) { NotifyError(new ArgumentException(System.SR.ParentIdInvalid)); } else { _parentId = parentId; } return this; } public Activity SetParentId(ActivityTraceId traceId, ActivitySpanId spanId, ActivityTraceFlags activityTraceFlags = ActivityTraceFlags.None) { if (_id != null || _spanId != null) { NotifyError(new InvalidOperationException(System.SR.ActivitySetParentAlreadyStarted)); } else if (Parent != null) { NotifyError(new InvalidOperationException(System.SR.SetParentIdOnActivityWithParent)); } else if (ParentId != null || _parentSpanId != null) { NotifyError(new InvalidOperationException(System.SR.ParentIdAlreadySet)); } else { _traceId = traceId.ToHexString(); _parentSpanId = spanId.ToHexString(); ActivityTraceFlags = activityTraceFlags; _parentTraceFlags = (byte)activityTraceFlags; } return this; } public Activity SetStartTime(DateTime startTimeUtc) { if (startTimeUtc.Kind != DateTimeKind.Utc) { NotifyError(new InvalidOperationException(System.SR.StartTimeNotUtc)); } else { StartTimeUtc = startTimeUtc; } return this; } public Activity SetEndTime(DateTime endTimeUtc) { if (endTimeUtc.Kind != DateTimeKind.Utc) { NotifyError(new InvalidOperationException(System.SR.EndTimeNotUtc)); } else { Duration = endTimeUtc - StartTimeUtc; if (Duration.Ticks <= 0) { Duration = new TimeSpan(1L); } } return this; } public Activity Start() { if (_id != null || _spanId != null) { NotifyError(new InvalidOperationException(System.SR.ActivityStartAlreadyStarted)); } else { _previousActiveActivity = Current; if (_parentId == null && _parentSpanId == null && _previousActiveActivity != null) { Parent = _previousActiveActivity; } if (StartTimeUtc == default(DateTime)) { StartTimeUtc = GetUtcNow(); } if (IdFormat == ActivityIdFormat.Unknown) { IdFormat = (ForceDefaultIdFormat ? DefaultIdFormat : ((Parent != null) ? Parent.IdFormat : ((_parentSpanId != null) ? ActivityIdFormat.W3C : ((_parentId == null) ? DefaultIdFormat : ((!IsW3CId(_parentId)) ? ActivityIdFormat.Hierarchical : ActivityIdFormat.W3C))))); } if (IdFormat == ActivityIdFormat.W3C) { GenerateW3CId(); } else { _id = GenerateHierarchicalId(); } SetCurrent(this); Source.NotifyActivityStart(this); } return this; } public void Stop() { if (_id == null && _spanId == null) { NotifyError(new InvalidOperationException(System.SR.ActivityNotStarted)); } else if (!IsStopped) { IsStopped = true; if (Duration == TimeSpan.Zero) { SetEndTime(GetUtcNow()); } Source.NotifyActivityStop(this); SetCurrent(_previousActiveActivity); } } public Activity SetIdFormat(ActivityIdFormat format) { if (_id != null || _spanId != null) { NotifyError(new InvalidOperationException(System.SR.SetFormatOnStartedActivity)); } else { IdFormat = format; } return this; } private static bool IsW3CId(string id) { if (id.Length == 55 && (('0' <= id[0] && id[0] <= '9') || ('a' <= id[0] && id[0] <= 'f')) && (('0' <= id[1] && id[1] <= '9') || ('a' <= id[1] && id[1] <= 'f'))) { if (id[0] == 'f') { return id[1] != 'f'; } return true; } return false; } internal static bool TryConvertIdToContext(string traceParent, string traceState, bool isRemote, out ActivityContext context) { context = default(ActivityContext); if (!IsW3CId(traceParent)) { return false; } ReadOnlySpan<char> idData = traceParent.AsSpan(3, 32); ReadOnlySpan<char> idData2 = traceParent.AsSpan(36, 16); if (!ActivityTraceId.IsLowerCaseHexAndNotAllZeros(idData) || !ActivityTraceId.IsLowerCaseHexAndNotAllZeros(idData2) || !System.HexConverter.IsHexLowerChar(traceParent[53]) || !System.HexConverter.IsHexLowerChar(traceParent[54])) { return false; } context = new ActivityContext(new ActivityTraceId(idData.ToString()), new ActivitySpanId(idData2.ToString()), (ActivityTraceFlags)ActivityTraceId.HexByteFromChars(traceParent[53], traceParent[54]), traceState, isRemote); return true; } public void Dispose() { if (!IsStopped) { Stop(); } Dispose(disposing: true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { } public void SetCustomProperty(string propertyName, object? propertyValue) { if (_customProperties == null) { Interlocked.CompareExchange(ref _customProperties, new Dictionary<string, object>(), null); } lock (_customProperties) { if (propertyValue == null) { _customProperties.Remove(propertyName); } else { _customProperties[propertyName] = propertyValue; } } } public object? GetCustomProperty(string propertyName) { if (_customProperties == null) { return null; } lock (_customProperties) { object value; return _customProperties.TryGetValue(propertyName, out value) ? value : null; } } internal static Activity Create(ActivitySource source, string name, ActivityKind kind, string parentId, ActivityContext parentContext, IEnumerable<KeyValuePair<string, object>> tags, IEnumerable<ActivityLink> links, DateTimeOffset startTime, ActivityTagsCollection samplerTags, ActivitySamplingResult request, bool startIt, ActivityIdFormat idFormat, string traceState) { Activity activity = new Activity(name); activity.Source = source; activity.Kind = kind; activity.IdFormat = idFormat; activity._traceState = traceState; if (links != null) { using IEnumerator<ActivityLink> enumerator = links.GetEnumerator(); if (enumerator.MoveNext()) { activity._links = new DiagLinkedList<ActivityLink>(enumerator); } } if (tags != null) { using IEnumerator<KeyValuePair<string, object>> enumerator2 = tags.GetEnumerator(); if (enumerator2.MoveNext()) { activity._tags = new TagsLinkedList(enumerator2); } } if (samplerTags != null) { if (activity._tags == null) { activity._tags = new TagsLinkedList(samplerTags); } else { activity._tags.Add(samplerTags); } } if (parentId != null) { activity._parentId = parentId; } else if (parentContext != default(ActivityContext)) { activity._traceId = parentContext.TraceId.ToString(); if (parentContext.SpanId != default(ActivitySpanId)) { activity._parentSpanId = parentContext.SpanId.ToString(); } activity.ActivityTraceFlags = parentContext.TraceFlags; activity._parentTraceFlags = (byte)parentContext.TraceFlags; activity.HasRemoteParent = parentContext.IsRemote; } activity.IsAllDataRequested = request == ActivitySamplingResult.AllData || request == ActivitySamplingResult.AllDataAndRecorded; if (request == ActivitySamplingResult.AllDataAndRecorded) { activity.ActivityTraceFlags |= ActivityTraceFlags.Recorded; } if (startTime != default(DateTimeOffset)) { activity.StartTimeUtc = startTime.UtcDateTime; } if (startIt) { activity.Start(); } return activity; } private void GenerateW3CId() { if (_traceId == null && !TrySetTraceIdFromParent()) { _traceId = (TraceIdGenerator?.Invoke() ?? ActivityTraceId.CreateRandom()).ToHexString(); } if (!W3CIdFlagsSet) { TrySetTraceFlagsFromParent(); } _spanId = ActivitySpanId.CreateRandom().ToHexString(); } private static void NotifyError(Exception exception) { try { throw exception; } catch { } } private string GenerateHierarchicalId() { if (Parent != null) { return AppendSuffix(Parent.Id, Interlocked.Increment(ref Parent._currentChildId).ToString(), '.'); } if (ParentId != null) { string text = ((ParentId[0] == '|') ? ParentId : ("|" + ParentId)); char c = text[text.Length - 1]; if (c != '.' && c != '_') { text += "."; } return AppendSuffix(text, Interlocked.Increment(ref s_currentRootId).ToString("x"), '_'); } return GenerateRootId(); } private string GetRootId(string id) { if (IdFormat == ActivityIdFormat.W3C) { return id.Substring(3, 32); } int num = id.IndexOf('.'); if (num < 0) { num = id.Length; } int num2 = ((id[0] == '|') ? 1 : 0); return id.Substring(num2, num - num2); } private string AppendSuffix(string parentId, string suffix, char delimiter) { if (parentId.Length + suffix.Length < 1024) { return parentId + suffix + delimiter; } int num = 1015; while (num > 1 && parentId[num - 1] != '.' && parentId[num - 1] != '_') { num--; } if (num == 1) { return GenerateRootId(); } string text = ((int)GetRandomNumber()).ToString("x8"); return parentId.Substring(0, num) + text + "#"; } private unsafe static long GetRandomNumber() { Guid guid = Guid.NewGuid(); return *(long*)(&guid); } private static bool ValidateSetCurrent(Activity activity) { bool flag = activity == null || (activity.Id != null && !activity.IsStopped); if (!flag) { NotifyError(new InvalidOperationException(System.SR.ActivityNotRunning)); } return flag; } private bool TrySetTraceIdFromParent() { if (Parent != null && Parent.IdFormat == ActivityIdFormat.W3C) { _traceId = Parent.TraceId.ToHexString(); } else if (_parentId != null && IsW3CId(_parentId)) { try { _traceId = ActivityTraceId.CreateFromString(_parentId.AsSpan(3, 32)).ToHexString(); } catch { } } return _traceId != null; } private void TrySetTraceFlagsFromParent() { if (W3CIdFlagsSet) { return; } if (Parent != null) { ActivityTraceFlags = Parent.ActivityTraceFlags; } else if (_parentId != null && IsW3CId(_parentId)) { if (System.HexConverter.IsHexLowerChar(_parentId[53]) && System.HexConverter.IsHexLowerChar(_parentId[54])) { _w3CIdFlags = (byte)(ActivityTraceId.HexByteFromChars(_parentId[53], _parentId[54]) | 0x80u); } else { _w3CIdFlags = 128; } } } private static void SetCurrent(Activity activity) { EventHandler<ActivityChangedEventArgs> currentChanged = Activity.CurrentChanged; if (currentChanged == null) { s_current.Value = activity; return; } Activity value = s_current.Value; s_current.Value = activity; currentChanged(null, new ActivityChangedEventArgs(value, activity)); } private static string GenerateRootId() { return $"|{Interlocked.Increment(ref s_currentRootId):x}{s_uniqSuffix}"; } internal static DateTime GetUtcNow() { return DateTime.UtcNow; } } [Flags] public enum ActivityTraceFlags { None = 0, Recorded = 1 } public enum ActivityIdFormat { Unknown, Hierarchical, W3C } public readonly struct ActivityTraceId : IEquatable<ActivityTraceId> { private readonly string _hexString; internal ActivityTraceId(string hexString) { _hexString = hexString; } public static ActivityTraceId CreateRandom() { Span<byte> span = stackalloc byte[16]; SetToRandomBytes(span); return CreateFromBytes(span); } public static ActivityTraceId CreateFromBytes(ReadOnlySpan<byte> idData) { if (idData.Length != 16) { throw new ArgumentOutOfRangeException("idData"); } return new ActivityTraceId(System.HexConverter.ToString(idData, System.HexConverter.Casing.Lower)); } public static ActivityTraceId CreateFromUtf8String(ReadOnlySpan<byte> idData) { return new ActivityTraceId(idData); } public static ActivityTraceId CreateFromString(ReadOnlySpan<char> idData) { if (idData.Length != 32 || !IsLowerCaseHexAndNotAllZeros(idData)) { throw new ArgumentOutOfRangeException("idData"); } return new ActivityTraceId(idData.ToString()); } public string ToHexString() { return _hexString ?? "00000000000000000000000000000000"; } public override string ToString() { return ToHexString(); } public static bool operator ==(ActivityTraceId traceId1, ActivityTraceId traceId2) { return traceId1._hexString == traceId2._hexString; } public static bool operator !=(ActivityTraceId traceId1, ActivityTraceId traceId2) { return traceId1._hexString != traceId2._hexString; } public bool Equals(ActivityTraceId traceId) { return _hexString == traceId._hexString; } public override bool Equals([NotNullWhen(true)] object? obj) { if (obj is ActivityTraceId activityTraceId) { return _hexString == activityTraceId._hexString; } return false; } public override int GetHashCode() { return ToHexString().GetHashCode(); } private ActivityTraceId(ReadOnlySpan<byte> idData) { if (idData.Length != 32) { throw new ArgumentOutOfRangeException("idData"); } Span<ulong> span = stackalloc ulong[2]; if (!Utf8Parser.TryParse(idData.Slice(0, 16), out span[0], out int bytesConsumed, 'x')) { _hexString = CreateRandom()._hexString; return; } if (!Utf8Parser.TryParse(idData.Slice(16, 16), out span[1], out bytesConsumed, 'x')) { _hexString = CreateRandom()._hexString; return; } if (BitConverter.IsLittleEndian) { span[0] = BinaryPrimitives.ReverseEndianness(span[0]); span[1] = BinaryPrimitives.ReverseEndianness(span[1]); } _hexString = System.HexConverter.ToString(MemoryMarshal.AsBytes(span), System.HexConverter.Casing.Lower); } public void CopyTo(Span<byte> destination) { SetSpanFromHexChars(ToHexString().AsSpan(), destination); } internal static void SetToRandomBytes(Span<byte> outBytes) { RandomNumberGenerator current = RandomNumberGenerator.Current; Unsafe.WriteUnaligned(ref outBytes[0], current.Next()); if (outBytes.Length == 16) { Unsafe.WriteUnaligned(ref outBytes[8], current.Next()); } } internal static void SetSpanFromHexChars(ReadOnlySpan<char> charData, Span<byte> outBytes) { for (int i = 0; i < outBytes.Length; i++) { outBytes[i] = HexByteFromChars(charData[i * 2], charData[i * 2 + 1]); } } internal static byte HexByteFromChars(char char1, char char2) { int num = System.HexConverter.FromLowerChar(char1); int num2 = System.HexConverter.FromLowerChar(char2); if ((num | num2) == 255) { throw new ArgumentOutOfRangeException("idData"); } return (byte)((num << 4) | num2); } internal static bool IsLowerCaseHexAndNotAllZeros(ReadOnlySpan<char> idData) { bool result = false; for (int i = 0; i < idData.Length; i++) { char c = idData[i]; if (!System.HexConverter.IsHexLowerChar(c)) { return false; } if (c != '0') { result = true; } } return result; } } public readonly struct ActivitySpanId : IEquatable<ActivitySpanId> { private readonly string _hexString; internal ActivitySpanId(string hexString) { _hexString = hexString; } public unsafe static ActivitySpanId CreateRandom() { ulong num = default(ulong); ActivityTraceId.SetToRandomBytes(new Span<byte>(&num, 8)); return new ActivitySpanId(System.HexConverter.ToString(new ReadOnlySpan<byte>(&num, 8), System.HexConverter.Casing.Lower)); } public static ActivitySpanId CreateFromBytes(ReadOnlySpan<byte> idData) { if (idData.Length != 8) { throw new ArgumentOutOfRangeException("idData"); } return new ActivitySpanId(System.HexConverter.ToString(idData, System.HexConverter.Casing.Lower)); } public static ActivitySpanId CreateFromUtf8String(ReadOnlySpan<byte> idData) { return new ActivitySpanId(idData); } public static ActivitySpanId CreateFromString(ReadOnlySpan<char> idData) { if (idData.Length != 16 || !ActivityTraceId.IsLowerCaseHexAndNotAllZeros(idData)) { throw new ArgumentOutOfRangeException("idData"); } return new ActivitySpanId(idData.ToString()); } public string ToHexString() { return _hexString ?? "0000000000000000"; } public override string ToString() { return ToHexString(); } public static bool operator ==(ActivitySpanId spanId1, ActivitySpanId spandId2) { return spanId1._hexString == spandId2._hexString; } public static bool operator !=(ActivitySpanId spanId1, ActivitySpanId spandId2) { return spanId1._hexString != spandId2._hexString; } public bool Equals(ActivitySpanId spanId) { return _hexString == spanId._hexString; } public override bool Equals([NotNullWhen(true)] object? obj) { if (obj is ActivitySpanId activitySpanId) { return _hexString == activitySpanId._hexString; } return false; } public override int GetHashCode() { return ToHexString().GetHashCode(); } private unsafe ActivitySpanId(ReadOnlySpan<byte> idData) { if (idData.Length != 16) { throw new ArgumentOutOfRangeException("idData"); } if (!Utf8Parser.TryParse(idData, out ulong value, out int _, 'x')) { _hexString = CreateRandom()._hexString; return; } if (BitConverter.IsLittleEndian) { value = BinaryPrimitives.ReverseEndianness(value); } _hexString = System.HexConverter.ToString(new ReadOnlySpan<byte>(&value, 8), System.HexConverter.Casing.Lower); } public void CopyTo(Span<byte> destination) { ActivityTraceId.SetSpanFromHexChars(ToHexString().AsSpan(), destination); } } public enum ActivityStatusCode { Unset, Ok, Error } public class ActivityTagsCollection : IDictionary<string, object?>, ICollection<KeyValuePair<string, object?>>, IEnumerable<KeyValuePair<string, object?>>, IEnumerable { public struct Enumerator : IEnumerator<KeyValuePair<string, object?>>, IEnumerator, IDisposable { private List<KeyValuePair<string, object>>.Enumerator _enumerator; public KeyValuePair<string, object?> Current => _enumerator.Current; object IEnumerator.Current => ((IEnumerator)_enumerator).Current; internal Enumerator(List<KeyValuePair<string, object>> list) { _enumerator = list.GetEnumerator(); } public void Dispose() { _enumerator.Dispose(); } public bool MoveNext() { return _enumerator.MoveNext(); } void IEnumerator.Reset() { ((IEnumerator)_enumerator).Reset(); } } private readonly List<KeyValuePair<string, object>> _list = new List<KeyValuePair<string, object>>(); public object? this[string key] { get { int num = FindIndex(key); if (num >= 0) { return _list[num].Value; } return null; } set { if (key == null) { throw new ArgumentNullException("key"); } int num = FindIndex(key); if (value == null) { if (num >= 0) { _list.RemoveAt(num); } } else if (num >= 0) { _list[num] = new KeyValuePair<string, object>(key, value); } else { _list.Add(new KeyValuePair<string, object>(key, value)); } } } public ICollection<string> Keys { get { List<string> list = new List<string>(_list.Count); foreach (KeyValuePair<string, object> item in _list) { list.Add(item.Key); } return list; } } public ICollection<object?> Values { get { List<object> list = new List<object>(_list.Count); foreach (KeyValuePair<string, object> item in _list) { list.Add(item.Value); } return list; } } public bool IsReadOnly => false; public int Count => _list.Count; public ActivityTagsCollection() { } public ActivityTagsCollection(IEnumerable<KeyValuePair<string, object?>> list) { if (list == null) { throw new ArgumentNullException("list"); } foreach (KeyValuePair<string, object> item in list) { if (item.Key != null) { this[item.Key] = item.Value; } } } public void Add(string key, object? value) { if (key == null) { throw new ArgumentNullException("key"); } int num = FindIndex(key); if (num >= 0) { throw new InvalidOperationException(System.SR.Format(System.SR.KeyAlreadyExist, key)); } _list.Add(new KeyValuePair<string, object>(key, value)); } public void Add(KeyValuePair<string, object?> item) { if (item.Key == null) { throw new ArgumentNullException("item"); } int num = FindIndex(item.Key); if (num >= 0) { throw new InvalidOperationException(System.SR.Format(System.SR.KeyAlreadyExist, item.Key)); } _list.Add(item); } public void Clear() { _list.Clear(); } public bool Contains(KeyValuePair<string, object?> item) { return _list.Contains(item); } public bool ContainsKey(string key) { return FindIndex(key) >= 0; } public void CopyTo(KeyValuePair<string, object?>[] array, int arrayIndex) { _list.CopyTo(array, arrayIndex); } IEnumerator<KeyValuePair<string, object>> IEnumerable<KeyValuePair<string, object>>.GetEnumerator() { return new Enumerator(_list); } public Enumerator GetEnumerator() { return new Enumerator(_list); } IEnumerator IEnumerable.GetEnumerator() { return new Enumerator(_list); } public bool Remove(string key) { if (key == null) { throw new ArgumentNullException("key"); } int num = FindIndex(key); if (num >= 0) { _list.RemoveAt(num); return true; } return false; } public bool Remove(KeyValuePair<string, object?> item) { return _list.Remove(item); } public bool TryGetValue(string key, out object? value) { int num = FindIndex(key); if (num >= 0) { value = _list[num].Value; return true; } value = null; return false; } private int FindIndex(string key) { for (int i = 0; i < _list.Count; i++) { if (_list[i].Key == key) { return i; } } return -1; } } public readonly struct ActivityContext : IEquatable<ActivityContext> { public ActivityTraceId TraceId { get; } public ActivitySpanId SpanId { get; } public ActivityTraceFlags TraceFlags { get; } public string? TraceState { get; } public bool IsRemote { get; } public ActivityContext(ActivityTraceId traceId, ActivitySpanId spanId, ActivityTraceFlags traceFlags, string? traceState = null, bool isRemote = false) { TraceId = traceId; SpanId = spanId; TraceFlags = traceFlags; TraceState = traceState; IsRemote = isRemote; } public static bool TryParse(string? traceParent, string? traceState, bool isRemote, out ActivityContext context) { if (traceParent == null) { context = default(ActivityContext); return false; } return Activity.TryConvertIdToContext(traceParent, traceState, isRemote, out context); } public static bool TryParse(string? traceParent, string? traceState, out ActivityContext context) { return TryParse(traceParent, traceState, isRemote: false, out context); } public static ActivityContext Parse(string traceParent, string? traceState) { if (traceParent == null) { throw new ArgumentNullException("traceParent"); } if (!Activity.TryConvertIdToContext(traceParent, traceState, isRemote: false, out var context)) { throw new ArgumentException(System.SR.InvalidTraceParent); } return context; } public bool Equals(ActivityContext value) { if (SpanId.Equals(value.SpanId) && TraceId.Equals(value.TraceId) && TraceFlags == value.TraceFlags && TraceState == value.TraceState) { return IsRemote == value.IsRemote; } return false; } public override bool Equals([NotNullWhen(true)] object? obj) { if (!(obj is ActivityContext value)) { return false; } return Equals(value); } public static bool operator ==(ActivityContext left, ActivityContext right) { return left.Equals(right); } public static bool operator !=(ActivityContext left, ActivityContext right) { return !(left == right); } public override int GetHashCode() { if (this == default(ActivityContext)) { return 0; } int num = 5381; num = (num << 5) + num + TraceId.GetHashCode(); num = (num << 5) + num + SpanId.GetHashCode(); num = (int)((num << 5) + num + TraceFlags); return (num << 5) + num + ((TraceState != null) ? TraceState.GetHashCode() : 0); } } public readonly struct ActivityCreationOptions<T> { private readonly ActivityTagsCollection _samplerTags; private readonly ActivityContext _context; private readonly string _traceState; public ActivitySource Source { get; } public string Name { get; } public ActivityKind Kind { get; } public T Parent { get; } public IEnumerable<KeyValuePair<string, object?>>? Tags { get; } public IEnumerable<ActivityLink>? Links { get; } public ActivityTagsCollection SamplingTags { get { if (_samplerTags == null) { Unsafe.AsRef(in _samplerTags) = new ActivityTagsCollection(); } return _samplerTags; } } public ActivityTraceId TraceId { get { if (Parent is ActivityContext && IdFormat == ActivityIdFormat.W3C && _context == default(ActivityContext)) { ActivityTraceId traceId = Activity.TraceIdGenerator?.Invoke() ?? ActivityTraceId.CreateRandom(); Unsafe.AsRef(in _context) = new ActivityContext(traceId, default(ActivitySpanId), ActivityTraceFlags.None); } return _context.TraceId; } } public string? TraceState { get { return _traceState; } init { _traceState = value; } } internal ActivityIdFormat IdFormat { get; } 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) { object obj = parent; ActivityContext activityContext = (ActivityContext)((obj is ActivityContext) ? obj : null); if (activityContext != default(ActivityContext)) { _context = activityContext; if (IdFormat == ActivityIdFormat.Unknown) { IdFormat = ActivityIdFormat.W3C; } _traceState = activityContext.TraceState; return; } } if ((object)parent is string traceParent) { if (IdFormat != ActivityIdFormat.Hierarchical) { if (ActivityContext.TryParse(traceParent, null, out _context)) { IdFormat = ActivityIdFormat.W3C; } if (IdFormat == ActivityIdFormat.Unknown) { IdFormat = ActivityIdFormat.Hierarchical; } } else { _context = default(ActivityContext); } } else { _context = default(ActivityContext); if (IdFormat == ActivityIdFormat.Unknown) { IdFormat = ((Activity.Current != null) ? Activity.Current.IdFormat : Activity.DefaultIdFormat); } } } internal void SetTraceState(string traceState) { Unsafe.AsRef(in _traceState) = traceState; } internal ActivityTagsCollection GetSamplingTags() { return _samplerTags; } internal ActivityContext GetContext() { return _context; } } public enum ActivitySamplingResult { None, PropagationData, AllData, AllDataAndRecorded } public readonly struct ActivityEvent { private static readonly IEnumerable<KeyValuePair<string, object>> s_emptyTags = Array.Empty<KeyValuePair<string, object>>(); private readonly Activity.TagsLinkedList _tags; public string Name { get; } public DateTimeOffset Timestamp { get; } public IEnumerable<KeyValuePair<string, object?>> Tags { get { IEnumerable<KeyValuePair<string, object>> tags = _tags; return tags ?? s_emptyTags; } } public ActivityEvent(string name) : this(name, DateTimeOffset.UtcNow) { } public ActivityEvent(string name, DateTimeOffset timestamp = default(DateTimeOffset), ActivityTagsCollection? tags = null) { Name = name ?? string.Empty; Timestamp = ((timestamp != default(DateTimeOffset)) ? timestamp : DateTimeOffset.UtcNow); _tags = ((tags != null && tags.Count > 0) ? new Activity.TagsLinkedList(tags) : null); } public Activity.Enumerator<KeyValuePair<string, object?>> EnumerateTagObjects() { return new Activity.Enumerator<KeyValuePair<string, object>>(_tags?.First); } } public enum ActivityKind { Internal, Server, Client, Producer, Consumer } public readonly struct ActivityLink : IEquatable<ActivityLink> { private readonly Activity.TagsLinkedList _tags; public ActivityContext Context { get; } public IEnumerable<KeyValuePair<string, object?>>? Tags => _tags; public ActivityLink(ActivityContext context, ActivityTagsCollection? tags = null) { Context = context; _tags = ((tags != null && tags.Count > 0) ? new Activity.TagsLinkedList(tags) : null); } public override bool Equals([NotNullWhen(true)] object? obj) { if (obj is ActivityLink value) { return Equals(value); } return false; } public bool Equals(ActivityLink value) { if (Context == value.Context) { return value.Tags == Tags; } return false; } public static bool operator ==(ActivityLink left, ActivityLink right) { return left.Equals(right); } public static bool operator !=(ActivityLink left, ActivityLink right) { return !left.Equals(right); } public Activity.Enumerator<KeyValuePair<string, object?>> EnumerateTagObjects() { return new Activity.Enumerator<KeyValuePair<string, object>>(_tags?.First); } public override int GetHashCode() { if (this == default(ActivityLink)) { return 0; } int num = 5381; num = (num << 5) + num + Context.GetHashCode(); if (Tags != null) { foreach (KeyValuePair<string, object> tag in Tags) { num = (num << 5) + num + tag.Key.GetHashCode(); if (tag.Value != null) { num = (num << 5) + num + tag.Value.GetHashCode(); } } } return num; } } public delegate ActivitySamplingResult SampleActivity<T>(ref ActivityCreationOptions<T> options); public sealed class ActivityListener : IDisposable { public Action<Activity>? ActivityStarted { get; set; } public Action<Activity>? ActivityStopped { get; set; } public Func<ActivitySource, bool>? ShouldListenTo { get; set; } public SampleActivity<string>? SampleUsingParentId { get; set; } public SampleActivity<ActivityContext>? Sample { get; set; } public void Dispose() { ActivitySource.DetachListener(this); } } public sealed class ActivitySource : IDisposable { internal delegate void Function<T, TParent>(T item, ref ActivityCreationOptions<TParent> data, ref ActivitySamplingResult samplingResult, ref ActivityCreationOptions<ActivityContext> dataWithContext); private static readonly SynchronizedList<ActivitySource> s_activeSources = new SynchronizedList<ActivitySource>(); private static readonly SynchronizedList<ActivityListener> s_allListeners = new SynchronizedList<ActivityListener>(); private SynchronizedList<ActivityListener> _listeners; public string Name { get; } public string? Version { get; } public ActivitySource(string name, string? version = "") { Name = name ?? throw new ArgumentNullException("name"); Version = version; s_activeSources.Add(this); if (s_allListeners.Count > 0) { s_allListeners.EnumWithAction(delegate(ActivityListener listener, object source) { Func<ActivitySource, bool> shouldListenTo = listener.ShouldListenTo; if (shouldListenTo != null) { ActivitySource activitySource = (ActivitySource)source; if (shouldListenTo(activitySource)) { activitySource.AddListener(listener); } } }, this); } GC.KeepAlive(DiagnosticSourceEventSource.Log); } public bool HasListeners() { SynchronizedList<ActivityListener> listeners = _listeners; if (listeners != null) { return listeners.Count > 0; } return false; } public Activity? CreateActivity(string name, ActivityKind kind) { return CreateActivity(name, kind, default(ActivityContext), null, null, null, default(DateTimeOffset), startIt: false); } public Activity? CreateActivity(string name, ActivityKind kind, ActivityContext parentContext, IEnumerable<KeyValuePair<string, object?>>? tags = null, IEnumerable<ActivityLink>? links = null, ActivityIdFormat idFormat = ActivityIdFormat.Unknown) { return CreateActivity(name, kind, parentContext, null, tags, links, default(DateTimeOffset), startIt: false, idFormat); } public Activity? CreateActivity(string name, ActivityKind kind, string? parentId, IEnumerable<KeyValuePair<string, object?>>? tags = null, IEnumerable<ActivityLink>? links = null, ActivityIdFormat idFormat = ActivityIdFormat.Unknown) { return CreateActivity(name, kind, default(ActivityContext), parentId, tags, links, default(DateTimeOffset), startIt: false, idFormat); } public Activity? StartActivity([CallerMemberName] string name = "", ActivityKind kind = ActivityKind.Internal) { return CreateActivity(name, kind, default(ActivityContext), null, null, null, default(DateTimeOffset)); } public Activity? StartActivity(string name, ActivityKind kind, ActivityContext parentContext, IEnumerable<KeyValuePair<string, object?>>? tags = null, IEnumerable<ActivityLink>? links = null, DateTimeOffset startTime = default(DateTimeOffset)) { return CreateActivity(name, kind, parentContext, null, tags, links, startTime); } public Activity? StartActivity(string name, ActivityKind kind, string? parentId, IEnumerable<KeyValuePair<string, object?>>? tags = null, IEnumerable<ActivityLink>? links = null, DateTimeOffset startTime = default(DateTimeOffset)) { return CreateActivity(name, kind, default(ActivityContext), parentId, tags, links, startTime); } public Activity? StartActivity(ActivityKind kind, ActivityContext parentContext = default(ActivityContext), IEnumerable<KeyValuePair<string, object?>>? tags = null, IEnumerable<ActivityLink>? links = null, DateTimeOffset startTime = default(DateTimeOffset), [CallerMemberName] string name = "") { return CreateActivity(name, kind, parentContext, null, tags, links, startTime); } private Activity CreateActivity(string name, ActivityKind kind, ActivityContext context, string parentId, IEnumerable<KeyValuePair<string, object>> tags, IEnumerable<ActivityLink> links, DateTimeOffset startTime, bool startIt = true, ActivityIdFormat idFormat = ActivityIdFormat.Unknown) { SynchronizedList<ActivityListener> listeners = _listeners; if (listeners == null || listeners.Count == 0) { return null; } Activity result2 = null; ActivitySamplingResult samplingResult = ActivitySamplingResult.None; ActivityTagsCollection activityTagsCollection; string traceState; if (parentId != null) { ActivityCreationOptions<string> activityCreationOptions = default(ActivityCreationOptions<string>); ActivityCreationOptions<ActivityContext> dataWithContext2 = default(ActivityCreationOptions<ActivityContext>); activityCreationOptions = new ActivityCreationOptions<string>(this, name, parentId, kind, tags, links, idFormat); if (activityCreationOptions.IdFormat == ActivityIdFormat.W3C) { dataWithContext2 = new ActivityCreationOptions<ActivityContext>(this, name, activityCreationOptions.GetContext(), kind, tags, links, ActivityIdFormat.W3C); } listeners.EnumWithFunc(delegate(ActivityListener listener, ref ActivityCreationOptions<string> data, ref ActivitySamplingResult result, ref ActivityCreationOptions<ActivityContext> dataWithContext) { SampleActivity<string> sampleUsingParentId = listener.SampleUsingParentId; if (sampleUsingParentId != null) { ActivitySamplingResult activitySamplingResult2 = sampleUsingParentId(ref data); dataWithContext.SetTraceState(data.TraceState); if (activitySamplingResult2 > result) { result = activitySamplingResult2; } } else if (data.IdFormat == ActivityIdFormat.W3C) { SampleActivity<ActivityContext> sample2 = listener.Sample; if (sample2 != null) { ActivitySamplingResult activitySamplingResult3 = sample2(ref dataWithContext); data.SetTraceState(dataWithContext.TraceState); if (activitySamplingResult3 > result) { result = activitySamplingResult3; } } } }, ref activityCreationOptions, ref samplingResult, ref dataWithContext2); if (context == default(ActivityContext)) { if (activityCreationOptions.GetContext() != default(ActivityContext)) { context = activityCreationOptions.GetContext(); parentId = null; } else if (dataWithContext2.GetContext() != default(ActivityContext)) { context = dataWithContext2.GetContext(); parentId = null; } } activityTagsCollection = activityCreationOptions.GetSamplingTags(); ActivityTagsCollection samplingTags = dataWithContext2.GetSamplingTags(); if (samplingTags != null) { if (activityTagsCollection == null) { activityTagsCollection = samplingTags; } else { foreach (KeyValuePair<string, object?> item in samplingTags) { activityTagsCollection.Add(item); } } } idFormat = activityCreationOptions.IdFormat; traceState = activityCreationOptions.TraceState; } else { bool flag = context == default(ActivityContext) && Activity.Current != null; ActivityCreationOptions<ActivityContext> data2 = new ActivityCreationOptions<ActivityContext>(this, name, flag ? Activity.Current.Context : context, kind, tags, links, idFormat); listeners.EnumWithFunc(delegate(ActivityListener listener, ref ActivityCreationOptions<ActivityContext> data, ref ActivitySamplingResult result, ref ActivityCreationOptions<ActivityContext> unused) { SampleActivity<ActivityContext> sample = listener.Sample; if (sample != null) { ActivitySamplingResult activitySamplingResult = sample(ref data); if (activitySamplingResult > result) { result = activitySamplingResult; } } }, ref data2, ref samplingResult, ref data2); if (!flag) { context = data2.GetContext(); } activityTagsCollection = data2.GetSamplingTags(); idFormat = data2.IdFormat; traceState = data2.TraceState; } if (samplingResult != 0) { result2 = Activity.Create(this, name, kind, parentId, context, tags, links, startTime, activityTagsCollection, samplingResult, startIt, idFormat, traceState); } return result2; } public void Dispose() { _listeners = null; s_activeSources.Remove(this); } public static void AddActivityListener(ActivityListener listener) { if (listener == null) { throw new ArgumentNullException("listener"); } if (!s_allListeners.AddIfNotExist(listener)) { return; } s_activeSources.EnumWithAction(delegate(ActivitySource source, object obj) { Func<ActivitySource, bool> shouldListenTo = ((ActivityListener)obj).ShouldListenTo; if (shouldListenTo != null && shouldListenTo(source)) { source.AddListener((ActivityListener)obj); } }, listener); } internal void AddListener(ActivityListener listener) { if (_listeners == null) { Interlocked.CompareExchange(ref _listeners, new SynchronizedList<ActivityListener>(), null); } _listeners.AddIfNotExist(listener); } internal static void DetachListener(ActivityListener listener) { s_allListeners.Remove(listener); s_activeSources.EnumWithAction(delegate(ActivitySource source, object obj) { source._listeners?.Remove((ActivityListener)obj); }, listener); } internal void NotifyActivityStart(Activity activity) { SynchronizedList<ActivityListener> listeners = _listeners; if (listeners != null && listeners.Count > 0) { listeners.EnumWithAction(delegate(ActivityListener listener, object obj) { listener.ActivityStarted?.Invoke((Activity)obj); }, activity); } } internal void NotifyActivityStop(Activity activity) { SynchronizedList<ActivityListener> listeners = _listeners; if (listeners != null && listeners.Count > 0) { listeners.EnumWithAction(delegate(ActivityListener listener, object obj) { listener.ActivityStopped?.Invoke((Activity)obj); }, activity); } } } internal sealed class SynchronizedList<T> { private readonly List<T> _list; private uint _version; public int Count => _list.Count; public SynchronizedList() { _list = new List<T>(); } public void Add(T item) { lock (_list) { _list.Add(item); _version++; } } public bool AddIfNotExist(T item) { lock (_list) { if (!_list.Contains(item)) { _list.Add(item); _version++; return true; } return false; } } public bool Remove(T item) { lock (_list) { if (_list.Remove(item)) { _version++; return true; } return false; } } public void EnumWithFunc<TParent>(ActivitySource.Function<T, TParent> func, ref ActivityCreationOptions<TParent> data, ref ActivitySamplingResult samplingResult, ref ActivityCreationOptions<ActivityContext> dataWithContext) { uint version = _version; int num = 0; while (num < _list.Count) { T item; lock (_list) { if (version != _version) { version = _version; num = 0; continue; } item = _list[num]; num++; goto IL_004f; } IL_004f: func(item, ref data, ref samplingResult, ref dataWithContext); } } public void EnumWithAction(Action<T, object> action, object arg) { uint version = _version; int num = 0; while (num < _list.Count) { T arg2; lock (_list) { if (version != _version) { version = _version; num = 0; continue; } arg2 = _list[num]; num++; goto IL_004f; } IL_004f: action(arg2, arg); } } } public abstract class DiagnosticSource { internal const string WriteRequiresUnreferencedCode = "The type of object being written to DiagnosticSource cannot be discovered statically."; internal const string WriteOfTRequiresUnreferencedCode = "Only the properties of the T type will be preserved. Properties of referenced types and properties of derived types may be trimmed."; [RequiresUnreferencedCode("The type of object being written to DiagnosticSource cannot be discovered statically.")] public abstract void Write(string name, object? value); [RequiresUnreferencedCode("Only the properties of the T type will be preserved. Properties of referenced types and properties of derived types may be trimmed.")] public void Write<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T>(string name, T value) { Write(name, (object?)value); } public abstract bool IsEnabled(string name); public virtual bool IsEnabled(string name, object? arg1, object? arg2 = null) { return IsEnabled(name); } [RequiresUnreferencedCode("The type of object being written to DiagnosticSource cannot be discovered statically.")] public Activity StartActivity(Activity activity, object? args) { activity.Start(); Write(activity.OperationName + ".Start", args); return activity; } [RequiresUnreferencedCode("Only the properties of the T type will be preserved. Properties of referenced types and properties of derived types may be trimmed.")] public Activity StartActivity<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T>(Activity activity, T args) { return StartActivity(activity, (object?)args); } [RequiresUnreferencedCode("The type of object being written to DiagnosticSource cannot be discovered statically.")] public void StopActivity(Activity activity, object? args) { if (activity.Duration == TimeSpan.Zero) { activity.SetEndTime(Activity.GetUtcNow()); } Write(activity.OperationName + ".Stop", args); activity.Stop(); } [RequiresUnreferencedCode("Only the properties of the T type will be preserved. Properties of referenced types and properties of derived types may be trimmed.")] public void StopActivity<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T>(Activity activity, T args) { StopActivity(activity, (object?)args); } public virtual void OnActivityImport(Activity activity, object? payload) { } public virtual void OnActivityExport(Activity activity, object? payload) { } } public class DiagnosticListener : DiagnosticSource, IObservable<KeyValuePair<string, object?>>, IDisposable { private sealed class DiagnosticSubscription : IDisposable { internal IObserver<KeyValuePair<string, object>> Observer; internal Predicate<string> IsEnabled1Arg; internal Func<string, object, object, bool> IsEnabled3Arg; internal Action<Activity, object> OnActivityImport; internal Action<Activity, object> OnActivityExport; internal DiagnosticListener Owner; internal DiagnosticSubscription Next; public void Dispose() { DiagnosticSubscription subscriptions; DiagnosticSubscription value; do { subscriptions = Owner._subscriptions; value = Remove(subscriptions, this); } while (Interlocked.CompareExchange(ref Owner._subscriptions, value, subscriptions) != subscriptions); } private static DiagnosticSubscription Remove(DiagnosticSubscription subscriptions, DiagnosticSubscription subscription) { if (subscriptions == null) { return null; } if (subscriptions.Observer == subscription.Observer && subscriptions.IsEnabled1Arg == subscription.IsEnabled1Arg && subscriptions.IsEnabled3Arg == subscription.IsEnabled3Arg) { return subscriptions.Next; } return new DiagnosticSubscription { Observer = subscriptions.Observer, Owner = subscriptions.Owner, IsEnabled1Arg = subscriptions.IsEnabled1Arg, IsEnabled3Arg = subscriptions.IsEnabled3Arg, Next = Remove(subscriptions.Next, subscription) }; } } private sealed class AllListenerObservable : IObservable<DiagnosticListener> { internal sealed class AllListenerSubscription : IDisposable { private readonly AllListenerObservable _owner; internal readonly IObserver<DiagnosticListener> Subscriber; internal AllListenerSubscription Next; internal AllListenerSubscription(AllListenerObservable owner, IObserver<DiagnosticListener> subscriber, AllListenerSubscription next) { _owner = owner; Subscriber = subscriber; Next = next; } public void Dispose() { if (_owner.Remove(this)) { Subscriber.OnCompleted(); } } } private AllListenerSubscription _subscriptions; public IDisposable Subscribe(IObserver<DiagnosticListener> observer) { lock (s_allListenersLock) { for (DiagnosticListener diagnosticListener = s_allListeners; diagnosticListener != null; diagnosticListener = diagnosticListener._next) { observer.OnNext(diagnosticListener); } _subscriptions = new AllListenerSubscription(this, observer, _subscriptions); return _subscriptions; } } internal void OnNewDiagnosticListener(DiagnosticListener diagnosticListener) { for (AllListenerSubscription allListenerSubscription = _subscriptions; allListenerSubscription != null; allListenerSubscription = allListenerSubscription.Next) { allListenerSubscription.Subscriber.OnNext(diagnosticListener); } } private bool Remove(AllListenerSubscription subscription) { lock (s_allListenersLock) { if (_subscriptions == subscription) { _subscriptions = subscription.Next; return true; } if (_subscriptions != null) { AllListenerSubscription allListenerSubscription = _subscriptions; while (allListenerSubscription.Next != null) { if (allListenerSubscription.Next == subscription) { allListenerSubscription.Next = allListenerSubscription.Next.Next; return true; } allListenerSubscription = allListenerSubscription.Next; } } return false; } } } private volatile DiagnosticSubscription _subscriptions; private DiagnosticListener _next; private bool _disposed; private static DiagnosticListener s_allListeners; private static volatile AllListenerObservable s_allListenerObservable; private static readonly object s_allListenersLock = new object(); public static IObservable<DiagnosticListener> AllListeners => s_allListenerObservable ?? Interlocked.CompareExchange(ref s_allListenerObservable, new AllListenerObservable(), null) ?? s_allListenerObservable; public string Name { get; private set; } public override void OnActivityImport(Activity activity, object? payload) { for (DiagnosticSubscription diagnosticSubscription = _subscriptions; diagnosticSubscription != null; diagnosticSubscription = diagnosticSubscription.Next) { diagnosticSubscription.OnActivityImport?.Invoke(activity, payload); } } public override void OnActivityExport(Activity activity, object? payload) { for (DiagnosticSubscription diagnosticSubscription = _subscriptions; diagnosticSubscription != null; diagnosticSubscription = diagnosticSubscription.Next) { diagnosticSubscription.OnActivityExport?.Invoke(activity, payload); } } public virtual IDisposable Subscribe(IObserver<KeyValuePair<string, object?>> observer, Func<string, object?, object?, bool>? isEnabled, Action<Activity, object?>? onActivityImport = null, Action<Activity, object?>? onActivityExport = null) { if (isEnabled != null) { return SubscribeInternal(observer, (string name) => IsEnabled(name, null), isEnabled, onActivityImport, onActivityExport); } return SubscribeInternal(observer, null, null, onActivityImport, onActivityExport); } public virtual IDisposable Subscribe(IObserver<KeyValuePair<string, object?>> observer, Predicate<string>? isEnabled) { if (isEnabled == null) { return SubscribeInternal(observer, null, null, null, null); } Predicate<string> localIsEnabled = isEnabled; return SubscribeInternal(observer, isEnabled, (string name, object arg1, object arg2) => localIsEnabled(name), null, null); } public virtual IDisposable Subscribe(IObserver<KeyValuePair<string, object?>> observer, Func<string, object?, object?, bool>? isEnabled) { if (isEnabled != null) { return SubscribeInternal(observer, (string name) => IsEnabled(name, null), isEnabled, null, null); } return SubscribeInternal(observer, null, null, null, null); } public virtual IDisposable Subscribe(IObserver<KeyValuePair<string, object?>> observer) { return SubscribeInternal(observer, null, null, null, null); } public DiagnosticListener(string name) { Name = name; lock (s_allListenersLock) { s_allListenerObservable?.OnNewDiagnosticListener(this); _next = s_allListeners; s_allListeners = this; } GC.KeepAlive(DiagnosticSourceEventSource.Log); } public virtual void Dispose() { lock (s_allListenersLock) { if (_disposed) { return; } _disposed = true; if (s_allListeners == this) { s_allListeners = s_allListeners._next; } else { for (DiagnosticListener next = s_allListeners; next != null; next = next._next) { if (next._next == this) { next._next = _next; break; } } } _next = null; } DiagnosticSubscription location = null; Interlocked.Exchange(ref location, _subscriptions); while (location != null) { location.Observer.OnCompleted(); location = location.Next; } } public override string ToString() { return Name ?? string.Empty; } public bool IsEnabled() { return _subscriptions != null; } public override bool IsEnabled(string name) { for (DiagnosticSubscription diagnosticSubscription = _subscriptions; diagnosticSubscription != null; diagnosticSubscription = diagnosticSubscription.Next) { if (diagnosticSubscription.IsEnabled1Arg == null || diagnosticSubscription.IsEnabled1Arg(name)) { return true; } } return false; } public override bool IsEnabled(string name, object? arg1, object? arg2 = null) { for (DiagnosticSubscription diagnosticSubscription = _subscriptions; diagnosticSubscription != null; diagnosticSubscription = diagnosticSubscription.Next) { if (diagnosticSubscription.IsEnabled3Arg == null || diagnosticSubscription.IsEnabled3Arg(name, arg1, arg2)) { return true; } } return false; } [RequiresUnreferencedCode("The type of object being written to DiagnosticSource cannot be discovered statically.")] public override void Write(string name, object? value) { for (DiagnosticSubscription diagnosticSubscription = _subscriptions; diagnosticSubscription != null; diagnosticSubscription = diagnosticSubscription.Next) { diagnosticSubscription.Observer.OnNext(new KeyValuePair<string, object>(name, value)); } } private DiagnosticSubscription SubscribeInternal(IObserver<KeyValuePair<string, object>> observer, Predicate<string> isEnabled1Arg, Func<string, object, object, bool> isEnabled3Arg, Action<Activity, object> onActivityImport, Action<Activity, object> onActivityExport) { if (_disposed) { return new DiagnosticSubscription { Owner = this }; } DiagnosticSubscription diagnosticSubscription = new DiagnosticSubscription { Observer = observer, IsEnabled1Arg = isEnabled1Arg, IsEnabled3Arg = isEnabled3Arg, OnActivityImport = onActivityImport, OnActivityExport = onActivityExport, Owner = this, Next = _subscriptions }; while (Interlocked.CompareExchange(ref _subscriptions, diagnosticSubscription, diagnosticSubscription.Next) != diagnosticSubscription.Next) { diagnosticSubscription.Next = _subscriptions; } return diagnosticSubscription; } } [EventSource(Name = "Microsoft-Diagnostics-DiagnosticSource")] [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2113:ReflectionToRequiresUnreferencedCode", Justification = "In EventSource, EnsureDescriptorsInitialized's use of GetType preserves methods on Delegate and MulticastDelegate because the nested type OverrideEventProvider's base type EventProvider defines a delegate. This includes Delegate and MulticastDelegate methods which require unreferenced code, but EnsureDescriptorsInitialized does not access these members and is safe to call.")] [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2115:ReflectionToDynamicallyAccessedMembers", Justification = "In EventSource, EnsureDescriptorsInitialized's use of GetType preserves methods on Delegate and MulticastDelegate because the nested type OverrideEventProvider's base type EventProvider defines a delegate. This includes Delegate and MulticastDelegate methods which have dynamically accessed members requirements, but EnsureDescriptorsInitialized does not access these members and is safe to call.")] internal sealed class DiagnosticSourceEventSource : EventSource { public static class Keywords { public const EventKeywords Messages = (EventKeywords)1L; public const EventKeywords Events = (EventKeywords)2L; public const EventKeywords IgnoreShortCutKeywords = (EventKeywords)2048L; public const EventKeywords AspNetCoreHosting = (EventKeywords)4096L; public const EventKeywords EntityFrameworkCoreCommands = (EventKeywords)8192L; } [Flags] internal enum ActivityEvents { None = 0, ActivityStart = 1, ActivityStop = 2, All = 3 } internal sealed class FilterAndTransform { public FilterAndTransform Next; internal const string c_ActivitySourcePrefix = "[AS]"; private IDisposable _diagnosticsListenersSubscription; private Subscriptions _liveSubscriptions; private readonly bool _noImplicitTransforms; private ImplicitTransformEntry _firstImplicitTransformsEntry; private ConcurrentDictionary<Type, TransformSpec> _implicitTransformsTable; private readonly TransformSpec _explicitTransforms; private readonly DiagnosticSourceEventSource _eventSource; internal string SourceName { get; set; } internal string ActivityName { get; set; } internal ActivityEvents Events { get; set; } internal ActivitySamplingResult SamplingResult { get; set; } public static void CreateFilterAndTransformList(ref FilterAndTransform specList, string filterAndPayloadSpecs, DiagnosticSourceEventSource eventSource) { DestroyFilterAndTransformList(ref specList, eventSource); if (filterAndPayloadSpecs == null) { filterAndPayloadSpecs = ""; } int num = filterAndPayloadSpecs.Length; while (true) { if (0 < num && char.IsWhiteSpace(filterAndPayloadSpecs[num - 1])) { num--; continue; } int num2 = filterAndPayloadSpecs.LastIndexOf('\n', num - 1, num); int i = 0; if (0 <= num2) { i = num2 + 1; } for (; i < num && char.IsWhiteSpace(filterAndPayloadSpecs[i]); i++) { } if (IsActivitySourceEntry(filterAndPayloadSpecs, i, num)) { AddNewActivitySourceTransform(filterAndPayloadSpecs, i, num, eventSource); } else { specList = new FilterAndTransform(filterAndPayloadSpecs, i, num, eventSource, specList); } num = num2; if (num < 0) { break; } } if (eventSource._activitySourceSpecs != null) { NormalizeActivitySourceSpecsList(eventSource); CreateActivityListener(eventSource); } } public static void DestroyFilterAndTransformList(ref FilterAndTransform specList, DiagnosticSourceEventSource eventSource) { eventSource._activityListener?.Dispose(); eventSource._activityListener = null; eventSource._activitySourceSpecs = null; FilterAndTransform filterAndTransform = specList; specList = null; while (filterAndTransform != null) { filterAndTransform.Dispose(); filterAndTransform = filterAndTransform.Next; } } public FilterAndTransform(string filterAndPayloadSpec, int startIdx, int endIdx, DiagnosticSourceEventSource eventSource, FilterAndTransform next) { FilterAndTransform filterAndTransform = this; Next = next; _eventSource = eventSource; string listenerNameFilter = null; string eventNameFilter = null; string text = null; int num = startIdx; int num2 = endIdx; int num3 = filterAndPayloadSpec.IndexOf(':', startIdx, endIdx - startIdx); if (0 <= num3) { num2 = num3; num = num3 + 1; } int num4 = filterAndPayloadSpec.IndexOf('/', startIdx, num2 - startIdx); if (0 <= num4) { listenerNameFilter = filterAndPayloadSpec.Substring(startIdx, num4 - startIdx); int num5 = filterAndPayloadSpec.IndexOf('@', num4 + 1, num2 - num4 - 1); if (0 <= num5) { text = filterAndPayloadSpec.Substring(num5 + 1, num2 - num5 - 1); eventNameFilter = filterAndPayloadSpec.Substring(num4 + 1, num5 - num4 - 1); } else { eventNameFilter = filterAndPayloadSpec.Substring(num4 + 1, num2 - num4 - 1); } } else if (startIdx < num2) { listenerNameFilter = filterAndPayloadSpec.Substring(startIdx, num2 - startIdx); } _eventSource.Message("DiagnosticSource: Enabling '" + (listenerNameFilter ?? "*") + "/" + (eventNameFilter ?? "*") + "'"); if (num < endIdx && filterAndPayloadSpec[num] == '-') { _eventSource.Message("DiagnosticSource: suppressing implicit transforms."); _noImplicitTransforms = true; num++; } if (num < endIdx) { while (true) { int num6 = num; int num7 = filterAndPayloadSpec.LastIndexOf(';', endIdx - 1, endIdx - num); if (0 <= num7) { num6 = num7 + 1; } if (num6 < endIdx) { if (_eventSource.IsEnabled(EventLevel.Informational, (EventKeywords)1L)) { _eventSource.Message("DiagnosticSource: Parsing Explicit Transform '" + filterAndPayloadSpec.Substring(num6, endIdx - num6) + "'"); } _explicitTransforms = new TransformSpec(filterAndPayloadSpec, num6, endIdx, _explicitTransforms); } if (num == num6) { break; } endIdx = num7; } } Action<string, string, IEnumerable<KeyValuePair<string, string>>> writeEvent = null; if (text != null && text.Contains("Activity")) { writeEvent = text switch { "Activity1Start" => _eventSource.Activity1Start, "Activity1Stop" => _eventSource.Activity1Stop, "Activity2Start" => _eventSource.Activity2Start, "Activity2Stop" => _eventSource.Activity2Stop, "RecursiveActivity1Start" => _eventSource.RecursiveActivity1Start, "RecursiveActivity1Stop" => _eventSource.RecursiveActivity1Stop, _ => null, }; if (writeEvent == null) { _eventSource.Message("DiagnosticSource: Could not find Event to log Activity " + text); } } if (writeEvent == null) { writeEvent = _eventSource.Event; } _diagnosticsListenersSubscription = DiagnosticListener.AllListeners.Subscribe(new CallbackObserver<DiagnosticListener>(delegate(DiagnosticListener newListener) { if (listenerNameFilter == null || listenerNameFilter == newListener.Name) { filterAndTransform._eventSource.NewDiagnosticListener(newListener.Name); Predicate<string> isEnabled = null; if (eventNameFilter != null) { isEnabled = (string eventName) => eventNameFilter == eventName; } IDisposable subscription = newListener.Subscribe(new CallbackObserver<KeyValuePair<string, object>>(OnEventWritten), isEnabled); filterAndTransform._liveSubscriptions = new Subscriptions(subscription, filterAndTransform._liveSubscriptions); } [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "DiagnosticSource.Write is marked with RequiresUnreferencedCode.")] [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2119", Justification = "DAM on EventSource references this compiler-generated local function which calls a method that requires unreferenced code. EventSource will not access this local function.")] void OnEventWritten(KeyValuePair<string, object> evnt) { if (eventNameFilter == null || !(eventNameFilter != evnt.Key)) { List<KeyValuePair<string, string>> arg = filterAndTransform.Morph(evnt.Value); string key = evnt.Key; writeEvent(newListener.Name, key, arg); } } })); } internal FilterAndTransform(string filterAndPayloadSpec, int endIdx, int colonIdx, string activitySourceName, string activityName, ActivityEvents events, ActivitySamplingResult samplingResult, DiagnosticSourceEventSource eventSource) { _eventSource =