1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
5 using System.Collections.Generic;
7 using Microsoft.Diagnostics.Monitoring.EventPipe.Triggers.Shared;
9 namespace Microsoft.Diagnostics.Monitoring.EventPipe.Triggers.SystemDiagnosticsMetrics
11 // The core implementation of the SystemDiagnosticsMetrics trigger that processes
12 // the trigger settings and evaluates the counter payload. Primary motivation
13 // for the implementation is for unit testability separate from TraceEvent.
14 internal sealed class SystemDiagnosticsMetricsTriggerImpl
16 private readonly long _intervalTicks;
17 private readonly Func<double, bool> _valueFilterDefault;
18 private readonly Func<Dictionary<int, double>, bool> _valueFilterHistogram;
19 private readonly long _windowTicks;
21 private long? _latestTicks;
22 private long? _targetTicks;
24 public SystemDiagnosticsMetricsTriggerImpl(SystemDiagnosticsMetricsTriggerSettings settings)
28 throw new ArgumentNullException(nameof(settings));
31 if (settings.HistogramPercentile.HasValue)
33 Func<double, bool> evalFunc = null;
34 SharedTriggerImplHelper.SetDefaultValueFilter(ref evalFunc, settings.GreaterThan, settings.LessThan);
36 _valueFilterHistogram = histogramValues =>
38 if (!histogramValues.TryGetValue(settings.HistogramPercentile.Value, out double value) || !evalFunc(value))
48 SharedTriggerImplHelper.SetDefaultValueFilter(ref _valueFilterDefault, settings.GreaterThan, settings.LessThan);
51 SharedTriggerImplHelper.SetIntervalAndWindowTicks(ref _intervalTicks, ref _windowTicks, settings.CounterIntervalSeconds, settings.SlidingWindowDuration.Ticks);
54 public bool HasSatisfiedCondition(ICounterPayload payload)
56 EventType eventType = payload.EventType;
58 if (eventType == EventType.Error || eventType == EventType.CounterEnded)
60 // not currently logging the error messages
66 bool passesValueFilter = (payload is PercentilePayload percentilePayload) ?
67 _valueFilterHistogram(CreatePayloadDictionary(percentilePayload)) :
68 _valueFilterDefault(payload.Value);
70 return SharedTriggerImplHelper.HasSatisfiedCondition(ref _latestTicks, ref _targetTicks, _windowTicks, _intervalTicks, payload, passesValueFilter);
74 private static Dictionary<int, double> CreatePayloadDictionary(PercentilePayload percentilePayload)
76 return percentilePayload.Quantiles.ToDictionary(keySelector: p => CounterUtilities.CreatePercentile(p.Percentage), elementSelector: p => p.Value);