Skip to content

Commit c5a3f49

Browse files
authored
Fix System.Net.Sockets telemetry (#42726)
1 parent e79a543 commit c5a3f49

File tree

7 files changed

+723
-222
lines changed

7 files changed

+723
-222
lines changed

src/libraries/Common/tests/System/Diagnostics/Tracing/TestEventListener.cs

+55-54
Original file line numberDiff line numberDiff line change
@@ -9,90 +9,91 @@ namespace System.Diagnostics.Tracing
99
/// <summary>Simple event listener than invokes a callback for each event received.</summary>
1010
internal sealed class TestEventListener : EventListener
1111
{
12-
private readonly string _targetSourceName;
13-
private readonly Guid _targetSourceGuid;
14-
private readonly EventLevel _level;
12+
private class Settings
13+
{
14+
public EventLevel Level;
15+
public EventKeywords Keywords;
16+
}
17+
18+
private readonly Dictionary<string, Settings> _names = new Dictionary<string, Settings>();
19+
private readonly Dictionary<Guid, Settings> _guids = new Dictionary<Guid, Settings>();
20+
1521
private readonly double? _eventCounterInterval;
1622

1723
private Action<EventWrittenEventArgs> _eventWritten;
18-
private List<EventSource> _tmpEventSourceList = new List<EventSource>();
24+
private readonly List<EventSource> _eventSourceList = new List<EventSource>();
1925

2026
public TestEventListener(string targetSourceName, EventLevel level, double? eventCounterInterval = null)
2127
{
22-
// Store the arguments
23-
_targetSourceName = targetSourceName;
24-
_level = level;
2528
_eventCounterInterval = eventCounterInterval;
26-
27-
LoadSourceList();
29+
AddSource(targetSourceName, level);
2830
}
2931

3032
public TestEventListener(Guid targetSourceGuid, EventLevel level, double? eventCounterInterval = null)
3133
{
32-
// Store the arguments
33-
_targetSourceGuid = targetSourceGuid;
34-
_level = level;
3534
_eventCounterInterval = eventCounterInterval;
36-
37-
LoadSourceList();
35+
AddSource(targetSourceGuid, level);
3836
}
3937

40-
private void LoadSourceList()
38+
public void AddSource(string name, EventLevel level, EventKeywords keywords = EventKeywords.All) =>
39+
AddSource(name, null, level, keywords);
40+
41+
public void AddSource(Guid guid, EventLevel level, EventKeywords keywords = EventKeywords.All) =>
42+
AddSource(null, guid, level, keywords);
43+
44+
private void AddSource(string name, Guid? guid, EventLevel level, EventKeywords keywords)
4145
{
42-
// The base constructor, which is called before this constructor,
43-
// will invoke the virtual OnEventSourceCreated method for each
44-
// existing EventSource, which means OnEventSourceCreated will be
45-
// called before _targetSourceGuid and _level have been set. As such,
46-
// we store a temporary list that just exists from the moment this instance
47-
// is created (instance field initializers run before the base constructor)
48-
// and until we finish construction... in that window, OnEventSourceCreated
49-
// will store the sources into the list rather than try to enable them directly,
50-
// and then here we can enumerate that list, then clear it out.
51-
List<EventSource> sources;
52-
lock (_tmpEventSourceList)
46+
lock (_eventSourceList)
5347
{
54-
sources = _tmpEventSourceList;
55-
_tmpEventSourceList = null;
56-
}
57-
foreach (EventSource source in sources)
58-
{
59-
EnableSourceIfMatch(source);
48+
var settings = new Settings()
49+
{
50+
Level = level,
51+
Keywords = keywords
52+
};
53+
54+
if (name is not null)
55+
_names.Add(name, settings);
56+
57+
if (guid.HasValue)
58+
_guids.Add(guid.Value, settings);
59+
60+
foreach (EventSource source in _eventSourceList)
61+
{
62+
if (name == source.Name || guid == source.Guid)
63+
{
64+
EnableEventSource(source, level, keywords);
65+
}
66+
}
6067
}
6168
}
6269

70+
public void AddActivityTracking() =>
71+
AddSource("System.Threading.Tasks.TplEventSource", EventLevel.Informational, (EventKeywords)0x80 /* TasksFlowActivityIds */);
72+
6373
protected override void OnEventSourceCreated(EventSource eventSource)
6474
{
65-
List<EventSource> tmp = _tmpEventSourceList;
66-
if (tmp != null)
75+
lock (_eventSourceList)
6776
{
68-
lock (tmp)
77+
_eventSourceList.Add(eventSource);
78+
79+
if (_names.TryGetValue(eventSource.Name, out Settings settings) ||
80+
_guids.TryGetValue(eventSource.Guid, out settings))
6981
{
70-
if (_tmpEventSourceList != null)
71-
{
72-
_tmpEventSourceList.Add(eventSource);
73-
return;
74-
}
82+
EnableEventSource(eventSource, settings.Level, settings.Keywords);
7583
}
7684
}
77-
78-
EnableSourceIfMatch(eventSource);
7985
}
8086

81-
private void EnableSourceIfMatch(EventSource source)
87+
private void EnableEventSource(EventSource source, EventLevel level, EventKeywords keywords)
8288
{
83-
if (source.Name.Equals(_targetSourceName) ||
84-
source.Guid.Equals(_targetSourceGuid))
89+
var args = new Dictionary<string, string>();
90+
91+
if (_eventCounterInterval != null)
8592
{
86-
if (_eventCounterInterval != null)
87-
{
88-
var args = new Dictionary<string, string> { { "EventCounterIntervalSec", _eventCounterInterval?.ToString() } };
89-
EnableEvents(source, _level, EventKeywords.All, args);
90-
}
91-
else
92-
{
93-
EnableEvents(source, _level);
94-
}
93+
args.Add("EventCounterIntervalSec", _eventCounterInterval.ToString());
9594
}
95+
96+
EnableEvents(source, level, keywords, args);
9697
}
9798

9899
public void RunWithCallback(Action<EventWrittenEventArgs> handler, Action body)

src/libraries/System.Net.NameResolution/src/System/Net/Dns.cs

+20-28
Original file line numberDiff line numberDiff line change
@@ -466,34 +466,9 @@ private static Task GetHostEntryOrAddressesCoreAsync(string hostName, bool justR
466466

467467
if (NameResolutionTelemetry.Log.IsEnabled())
468468
{
469-
ValueStopwatch stopwatch = NameResolutionTelemetry.Log.BeforeResolution(hostName);
470-
471-
Task coreTask;
472-
try
473-
{
474-
coreTask = NameResolutionPal.GetAddrInfoAsync(hostName, justAddresses);
475-
}
476-
catch when (LogFailure(stopwatch))
477-
{
478-
Debug.Fail("LogFailure should return false");
479-
throw;
480-
}
481-
482-
coreTask.ContinueWith(
483-
(task, state) =>
484-
{
485-
NameResolutionTelemetry.Log.AfterResolution(
486-
stopwatch: (ValueStopwatch)state!,
487-
successful: task.IsCompletedSuccessfully);
488-
},
489-
state: stopwatch,
490-
cancellationToken: default,
491-
TaskContinuationOptions.ExecuteSynchronously,
492-
TaskScheduler.Default);
493-
494-
// coreTask is not actually a base Task, but Task<IPHostEntry> / Task<IPAddress[]>
495-
// We have to return it and not the continuation
496-
return coreTask;
469+
return justAddresses
470+
? (Task)GetAddrInfoWithTelemetryAsync<IPAddress[]>(hostName, justAddresses)
471+
: (Task)GetAddrInfoWithTelemetryAsync<IPHostEntry>(hostName, justAddresses);
497472
}
498473
else
499474
{
@@ -506,6 +481,23 @@ private static Task GetHostEntryOrAddressesCoreAsync(string hostName, bool justR
506481
RunAsync(s => GetHostEntryCore((string)s), hostName);
507482
}
508483

484+
private static async Task<T> GetAddrInfoWithTelemetryAsync<T>(string hostName, bool justAddresses)
485+
where T : class
486+
{
487+
ValueStopwatch stopwatch = NameResolutionTelemetry.Log.BeforeResolution(hostName);
488+
489+
T? result = null;
490+
try
491+
{
492+
result = await ((Task<T>)NameResolutionPal.GetAddrInfoAsync(hostName, justAddresses)).ConfigureAwait(false);
493+
return result;
494+
}
495+
finally
496+
{
497+
NameResolutionTelemetry.Log.AfterResolution(stopwatch, successful: result is not null);
498+
}
499+
}
500+
509501
private static Task<TResult> RunAsync<TResult>(Func<object, TResult> func, object arg) =>
510502
Task.Factory.StartNew(func!, arg, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
511503

0 commit comments

Comments
 (0)