@@ -9,90 +9,91 @@ namespace System.Diagnostics.Tracing
9
9
/// <summary>Simple event listener than invokes a callback for each event received.</summary>
10
10
internal sealed class TestEventListener : EventListener
11
11
{
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
+
15
21
private readonly double ? _eventCounterInterval ;
16
22
17
23
private Action < EventWrittenEventArgs > _eventWritten ;
18
- private List < EventSource > _tmpEventSourceList = new List < EventSource > ( ) ;
24
+ private readonly List < EventSource > _eventSourceList = new List < EventSource > ( ) ;
19
25
20
26
public TestEventListener ( string targetSourceName , EventLevel level , double ? eventCounterInterval = null )
21
27
{
22
- // Store the arguments
23
- _targetSourceName = targetSourceName ;
24
- _level = level ;
25
28
_eventCounterInterval = eventCounterInterval ;
26
-
27
- LoadSourceList ( ) ;
29
+ AddSource ( targetSourceName , level ) ;
28
30
}
29
31
30
32
public TestEventListener ( Guid targetSourceGuid , EventLevel level , double ? eventCounterInterval = null )
31
33
{
32
- // Store the arguments
33
- _targetSourceGuid = targetSourceGuid ;
34
- _level = level ;
35
34
_eventCounterInterval = eventCounterInterval ;
36
-
37
- LoadSourceList ( ) ;
35
+ AddSource ( targetSourceGuid , level ) ;
38
36
}
39
37
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 )
41
45
{
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 )
53
47
{
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
+ }
60
67
}
61
68
}
62
69
70
+ public void AddActivityTracking ( ) =>
71
+ AddSource ( "System.Threading.Tasks.TplEventSource" , EventLevel . Informational , ( EventKeywords ) 0x80 /* TasksFlowActivityIds */ ) ;
72
+
63
73
protected override void OnEventSourceCreated ( EventSource eventSource )
64
74
{
65
- List < EventSource > tmp = _tmpEventSourceList ;
66
- if ( tmp != null )
75
+ lock ( _eventSourceList )
67
76
{
68
- lock ( tmp )
77
+ _eventSourceList . Add ( eventSource ) ;
78
+
79
+ if ( _names . TryGetValue ( eventSource . Name , out Settings settings ) ||
80
+ _guids . TryGetValue ( eventSource . Guid , out settings ) )
69
81
{
70
- if ( _tmpEventSourceList != null )
71
- {
72
- _tmpEventSourceList . Add ( eventSource ) ;
73
- return ;
74
- }
82
+ EnableEventSource ( eventSource , settings . Level , settings . Keywords ) ;
75
83
}
76
84
}
77
-
78
- EnableSourceIfMatch ( eventSource ) ;
79
85
}
80
86
81
- private void EnableSourceIfMatch ( EventSource source )
87
+ private void EnableEventSource ( EventSource source , EventLevel level , EventKeywords keywords )
82
88
{
83
- if ( source . Name . Equals ( _targetSourceName ) ||
84
- source . Guid . Equals ( _targetSourceGuid ) )
89
+ var args = new Dictionary < string , string > ( ) ;
90
+
91
+ if ( _eventCounterInterval != null )
85
92
{
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 ( ) ) ;
95
94
}
95
+
96
+ EnableEvents ( source , level , keywords , args ) ;
96
97
}
97
98
98
99
public void RunWithCallback ( Action < EventWrittenEventArgs > handler , Action body )
0 commit comments