< Summary

Class:Azure.Core.Pipeline.DiagnosticScope
Assembly:Azure.AI.TextAnalytics
File(s):C:\Git\azure-sdk-for-net\sdk\core\Azure.Core\src\Shared\DiagnosticScope.cs
Covered lines:19
Uncovered lines:24
Coverable lines:43
Total lines:167
Line coverage:44.1% (19 of 43)
Covered branches:11
Total branches:38
Branch coverage:28.9% (11 of 38)

Metrics

MethodCyclomatic complexity Line coverage Branch coverage
.ctor(...)-100%50%
get_IsEnabled()-0%100%
AddAttribute(...)-100%50%
AddAttribute(...)-0%0%
AddAttribute(...)-0%0%
AddLink(...)-0%0%
Start()-100%100%
SetStartTime(...)-0%0%
Dispose()-50%33.33%
Failed(...)-75%50%
get_Links()-100%100%
.ctor(...)-100%100%
AddLink(...)-0%0%

File(s)

C:\Git\azure-sdk-for-net\sdk\core\Azure.Core\src\Shared\DiagnosticScope.cs

#LineLine coverage
 1// Copyright (c) Microsoft Corporation. All rights reserved.
 2// Licensed under the MIT License.
 3
 4#nullable enable
 5
 6using System;
 7using System.Collections.Generic;
 8using System.Diagnostics;
 9using System.Reflection;
 10
 11namespace Azure.Core.Pipeline
 12{
 13    internal readonly struct DiagnosticScope : IDisposable
 14    {
 15        private readonly DiagnosticActivity? _activity;
 16
 17        private readonly string _name;
 18
 19        private readonly DiagnosticListener _source;
 20
 21        internal DiagnosticScope(string name, DiagnosticListener source)
 22        {
 18823            _name = name;
 18824            _source = source;
 18825            _activity = _source.IsEnabled(_name) ? new DiagnosticActivity(_name) : null;
 18826            _activity?.SetW3CFormat();
 18827        }
 28
 029        public bool IsEnabled => _activity != null;
 30
 31        public void AddAttribute(string name, string value)
 32        {
 26033            _activity?.AddTag(name, value);
 26034        }
 35
 36        public void AddAttribute<T>(string name, T value)
 37        {
 038            if (_activity != null && value != null)
 39            {
 040                AddAttribute(name, value.ToString() ?? string.Empty);
 41            }
 042        }
 43
 44        public void AddAttribute<T>(string name, T value, Func<T, string> format)
 45        {
 046            if (_activity != null)
 47            {
 048                AddAttribute(name, format(value));
 49            }
 050        }
 51
 52        public void AddLink(string id, IDictionary<string, string>? attributes = null)
 53        {
 054            if (_activity != null)
 55            {
 056                var linkedActivity = new Activity("LinkedActivity");
 057                linkedActivity.SetW3CFormat();
 058                linkedActivity.SetParentId(id);
 59
 060                if (attributes != null)
 61                {
 062                    foreach (var kvp in attributes)
 63                    {
 064                        linkedActivity.AddTag(kvp.Key, kvp.Value);
 65                    }
 66                }
 67
 068                _activity.AddLink(linkedActivity);
 69            }
 070        }
 71
 72        public void Start()
 73        {
 18874            if (_activity != null)
 75            {
 18876                _source.StartActivity(_activity, _activity);
 77            }
 18878        }
 79
 080        public void SetStartTime(DateTime dateTime) => _activity?.SetStartTime(dateTime);
 81
 82        public void Dispose()
 83        {
 18884            if (_activity == null)
 85            {
 086                return;
 87            }
 88
 18889            if (_source != null)
 90            {
 18891                _source.StopActivity(_activity, null);
 92            }
 93            else
 94            {
 095                _activity?.Stop();
 96            }
 097        }
 98
 99        public void Failed(Exception e)
 100        {
 16101            if (_activity == null)
 102            {
 0103                return;
 104            }
 105
 16106            _source?.Write(_activity.OperationName + ".Exception", e);
 107
 16108        }
 109
 110        private class DiagnosticActivity : Activity
 111        {
 112            private List<Activity>? _links;
 113
 188114            public IEnumerable<Activity> Links => (IEnumerable<Activity>?)_links ?? Array.Empty<Activity>();
 115
 188116            public DiagnosticActivity(string operationName) : base(operationName)
 117            {
 188118            }
 119
 120            public void AddLink(Activity activity)
 121            {
 0122                _links ??= new List<Activity>();
 0123                _links.Add(activity);
 0124            }
 125        }
 126    }
 127
 128    /// <summary>
 129    /// HACK HACK HACK. Some runtime environments like Azure.Functions downgrade System.Diagnostic.DiagnosticSource pack
 130    /// This type is a temporary workaround to avoid the issue.
 131    /// </summary>
 132    internal static class ActivityExtensions
 133    {
 134        private static readonly MethodInfo? s_setIdFormatMethod = typeof(Activity).GetMethod("SetIdFormat");
 135        private static readonly MethodInfo? s_getIdFormatMethod = typeof(Activity).GetProperty("IdFormat")?.GetMethod;
 136        private static readonly MethodInfo? s_getTraceStateStringMethod = typeof(Activity).GetProperty("TraceStateString
 137
 138        public static bool SetW3CFormat(this Activity activity)
 139        {
 140            if (s_setIdFormatMethod == null) return false;
 141
 142            s_setIdFormatMethod.Invoke(activity, new object[]{ 2 /* ActivityIdFormat.W3C */});
 143
 144            return true;
 145        }
 146
 147        public static bool IsW3CFormat(this Activity activity)
 148        {
 149            if (s_getIdFormatMethod == null) return false;
 150
 151            object? result = s_getIdFormatMethod.Invoke(activity, Array.Empty<object>());
 152
 153            return result != null && (int)result == 2 /* ActivityIdFormat.W3C */;
 154        }
 155
 156        public static bool TryGetTraceState(this Activity activity, out string? traceState)
 157        {
 158            traceState = null;
 159
 160            if (s_getTraceStateStringMethod == null) return false;
 161
 162            traceState = s_getTraceStateStringMethod.Invoke(activity, Array.Empty<object>()) as string;
 163
 164            return true;
 165        }
 166    }
 167}