public ProcessOrSingleTimeWindowServiceProfiler(IAmbientServiceProfiler metrics, string scopeName, Regex?systemGroupTransform) { _profiler = metrics; _scopeName = scopeName; _systemToGroupTransform = systemGroupTransform; _accumulatorsByGroup = new ConcurrentDictionary <string, AmbientServiceProfilerAccumulator>(); _activeGroupByCallContext = new ConcurrentDictionary <object, CallContextActiveSystemData>(); _callContextKey = new AsyncLocal <object>(); _profiler.RegisterSystemSwitchedNotificationSink(this); }
private ProcessOrSingleTimeWindowServiceProfiler?Rotate(IAmbientServiceProfiler metrics, TimeSpan windowPeriod, Regex?systemGroupTransform) { string windowName = WindowScope.WindowId(AmbientClock.UtcNow, windowPeriod); string newAccumulatorScopeName = _scopeNamePrefix + windowName + "(" + WindowScope.WindowSize(windowPeriod) + ")";; ProcessOrSingleTimeWindowServiceProfiler newAccumulator = new ProcessOrSingleTimeWindowServiceProfiler(metrics, newAccumulatorScopeName, systemGroupTransform); ProcessOrSingleTimeWindowServiceProfiler?oldAccumulator = System.Threading.Interlocked.Exchange(ref _timeWindowCallContextCollector, newAccumulator); if (oldAccumulator != null) { // close out the old accumulator oldAccumulator.CloseSampling(); } return(oldAccumulator); }
/// <summary> /// Constructs a TimeWindowProcessingDistributionTracker. /// </summary> /// <param name="metrics">A <see cref="IAmbientServiceProfiler"/> to hook into to receive processor change events.</param> /// <param name="scopeNamePrefix">A <see cref="TimeSpan"/> indicating the size of the window.</param> /// <param name="windowPeriod">A <see cref="TimeSpan"/> indicating how often reports are desired.</param> /// <param name="onWindowComplete">An async delegate that receives a <see cref="IAmbientServiceProfile"/> at the end of each time window.</param> /// <param name="systemGroupTransform">A <see cref="Regex"/> string to transform the system into a system group.</param> public TimeWindowServiceProfiler(IAmbientServiceProfiler metrics, string scopeNamePrefix, TimeSpan windowPeriod, Func <IAmbientServiceProfile, Task> onWindowComplete, Regex?systemGroupTransform) { if (onWindowComplete == null) { throw new ArgumentNullException(nameof(onWindowComplete), "Time Window Collection is pointless without a completion delegate!"); } _scopeNamePrefix = scopeNamePrefix; using (Rotate(metrics, windowPeriod, systemGroupTransform)) { } _timeWindowRotator = new AmbientEventTimer(windowPeriod); _timeWindowRotator.Elapsed += (sender, handler) => { ProcessOrSingleTimeWindowServiceProfiler?oldAccumulator = Rotate(metrics, windowPeriod, systemGroupTransform); if (oldAccumulator != null) { Task t = onWindowComplete(oldAccumulator); t.Wait(); } }; _timeWindowRotator.AutoReset = true; _timeWindowRotator.Enabled = true; }