Skip to content

Commit

Permalink
[Instrumentation.EventCounters] Avoid race condition and performance …
Browse files Browse the repository at this point in the history
…trap in EventCountersMetrics (#703)
  • Loading branch information
MihaZupan authored Oct 18, 2022
1 parent 926386e commit 018e124
Showing 1 changed file with 26 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ internal sealed class EventCountersMetrics : EventListener
internal static readonly Meter MeterInstance = new(typeof(EventCountersMetrics).Assembly.GetName().Name, typeof(EventCountersMetrics).Assembly.GetName().Version.ToString());

private readonly EventCountersInstrumentationOptions options;
private readonly ConcurrentQueue<EventSource> preInitEventSources = new();
private readonly List<EventSource> preInitEventSources = new();
private readonly ConcurrentDictionary<(string, string), Instrument> instruments = new();
private readonly ConcurrentDictionary<(string, string), double> values = new();

Expand All @@ -40,27 +40,35 @@ internal sealed class EventCountersMetrics : EventListener
/// <param name="options">The options to define the metrics.</param>
public EventCountersMetrics(EventCountersInstrumentationOptions options)
{
this.options = options;

while (this.preInitEventSources.TryDequeue(out EventSource eventSource))
lock (this.preInitEventSources)
{
if (this.options.ShouldListenToSource(eventSource.Name))
this.options = options;

foreach (EventSource eventSource in this.preInitEventSources)
{
this.EnableEvents(eventSource, EventLevel.LogAlways, EventKeywords.None, GetEnableEventsArguments(this.options));
if (this.options.ShouldListenToSource(eventSource.Name))
{
this.EnableEvents(eventSource);
}
}

this.preInitEventSources.Clear();
}
}

/// <inheritdoc />
protected override void OnEventSourceCreated(EventSource source)
protected override void OnEventSourceCreated(EventSource eventSource)
{
if (this.options == null)
lock (this.preInitEventSources)
{
this.preInitEventSources.Enqueue(source);
}
else if (this.options.ShouldListenToSource(source.Name))
{
this.EnableEvents(source, EventLevel.LogAlways, EventKeywords.None, GetEnableEventsArguments(this.options));
if (this.options == null)
{
this.preInitEventSources.Add(eventSource);
}
else if (this.options.ShouldListenToSource(eventSource.Name))
{
this.EnableEvents(eventSource);
}
}
}

Expand Down Expand Up @@ -112,6 +120,11 @@ protected override void OnEventWritten(EventWrittenEventArgs eventData)
private static Dictionary<string, string> GetEnableEventsArguments(EventCountersInstrumentationOptions options) =>
new() { { "EventCounterIntervalSec", options.RefreshIntervalSecs.ToString() } };

private void EnableEvents(EventSource eventSource)
{
this.EnableEvents(eventSource, EventLevel.Critical, EventKeywords.None, GetEnableEventsArguments(this.options));
}

private void UpdateInstrumentWithEvent(bool isGauge, string eventSourceName, string name, double value)
{
try
Expand Down

0 comments on commit 018e124

Please sign in to comment.