Skip to content

Instantly share code, notes, and snippets.

@samsp-msft
Last active January 31, 2023 18:41
Show Gist options
  • Save samsp-msft/cb4ba1e5bb4de0c6bb3aae5ecbeac162 to your computer and use it in GitHub Desktop.
Save samsp-msft/cb4ba1e5bb4de0c6bb3aae5ecbeac162 to your computer and use it in GitHub Desktop.
using Microsoft.Extensions.Options;
using System.Collections.ObjectModel;
using System.Diagnostics.Tracing;
using System.Runtime.CompilerServices;
using System.Text.Json;
using System.Text.Json.Serialization;
public class EventEnumerator : EventListener
{
private Dictionary<EventSource, List<string>> _counters = new Dictionary<EventSource, List<string>>();
private Dictionary<EventSource, Dictionary<int, EventDetails>> _events = new Dictionary<EventSource, Dictionary<int, EventDetails>>();
private bool _shouldLog = false;
private EventLevel _level;
public EventEnumerator(bool ShouldLog, EventLevel level)
{
_shouldLog = ShouldLog;
}
public EventEnumerator() : this(false, EventLevel.Verbose) { }
protected override void OnEventSourceCreated(EventSource eventSource)
{
base.OnEventSourceCreated(eventSource);
_counters.Add(eventSource, new List<string>());
_events.Add(eventSource, new Dictionary<int, EventDetails>());
EnableEvents(eventSource, _level, EventKeywords.All, new Dictionary<string, string?> { { "EventCounterIntervalSec", "1" } });
}
protected override void OnEventWritten(EventWrittenEventArgs eventData)
{
base.OnEventWritten(eventData);
lock (this)
{
if (eventData.EventId == -1)
{
if ((eventData.EventName == "EventCounters" && eventData.Payload?.Count == 1))
{
AddCounter(eventData);
}
}
else
{
AddEvent(eventData);
}
}
}
private void AddEvent(EventWrittenEventArgs eventData)
{
string eventName = eventData.EventName ?? "unknown";
var eventNames = _events[eventData.EventSource];
if (!eventNames.ContainsKey(eventData.EventId))
{
eventNames.Add(eventData.EventId, new EventDetails()
{
Id = eventData.EventId,
Name = eventName,
Opcode = eventData.Opcode,
Keywords = eventData.Keywords,
Level = eventData.Level,
Message = eventData.Message,
PayloadFields = eventData.PayloadNames,
Tags = eventData.Tags
});
if (_shouldLog) Console.WriteLine($"Event Found:- EventSource: {eventData.EventSource.Name}, Opcode: {eventData.Opcode}, Event: {eventName}, Level: {eventData.Level}, Message: `{eventData.Message}`");
}
}
private void AddCounter(EventWrittenEventArgs eventData)
{
var payload = eventData.Payload[0] as IDictionary<string, object>;
var counterName = (payload?["Name"] as string) ?? "unknown";
var counternames = _counters[eventData.EventSource];
if (!counternames.Contains(counterName))
{
counternames.Add(counterName);
if (_shouldLog) Console.WriteLine($"Event Counter Found:- EventSource: {eventData.EventSource.Name}, Counter: {counterName}");
}
}
public string DumpEvents()
{
var data = new
{
Events = (from e in _events
where e.Value.Count !=0
select new
{
Source = e.Key.Name,
Events = (from e2 in e.Value
orderby e2.Value.Id
select new { k = e2.Value.Name, v = e2.Value })
.ToDictionary(i => i.k, i => i.v)
}).ToDictionary(j => j.Source, j=> j.Events),
Counters = (from c in _counters
where c.Value.Count != 0
select new
{
Source = c.Key.Name,
Counters = c.Value
}
).ToDictionary(i=>i.Source, i=>i.Counters)
};
var options = new JsonSerializerOptions { WriteIndented = true, IncludeFields = true };
return JsonSerializer.Serialize(data, options);
}
[Serializable]
public class EventDetails
{
public int Id;
[JsonIgnore]
public string Name;
public EventOpcode Opcode;
public EventLevel Level;
public EventKeywords Keywords;
public ReadOnlyCollection<string>? PayloadFields;
public EventTags Tags;
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Message;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment