public AggregateGauge() { var strategy = GetAggregatorStategy(); // denormalize these for one less level of indirection _percentiles = strategy.Percentiles; _suffixes = strategy.Suffixes; _trackMean = strategy.TrackMean; _specialCaseMin = strategy.SpecialCaseMin; _specialCaseMax = strategy.SpecialCaseMax; _specialCaseLast = strategy.SpecialCaseLast; _reportCount = strategy.ReportCount; // setup heap, if required. if (strategy.UseList) { _list = new List <double>(); } _snapshot = new double[_suffixes.Length]; _snapshotReportingMode = SnapshotReportingMode.None; }
/// <summary> /// Instantiates a new <see cref="AggregateGauge"/>. /// </summary> public AggregateGauge(IEnumerable <GaugeAggregator> aggregators, string name, string unit, string description, MetricSourceOptions options, ImmutableDictionary <string, string> tags = null) : base(name, unit, description, options, tags) { var strategy = new GaugeAggregatorStrategy(aggregators.ToImmutableArray()); // denormalize these for one less level of indirection _percentiles = strategy.Percentiles; _suffixes = strategy.Suffixes; _trackMean = strategy.TrackMean; _specialCaseMin = strategy.SpecialCaseMin; _specialCaseMax = strategy.SpecialCaseMax; _specialCaseLast = strategy.SpecialCaseLast; _reportCount = strategy.ReportCount; // setup heap, if required. if (strategy.UseList) { _list = new List <double>(); } _snapshot = new double[_suffixes.Length]; _snapshotReportingMode = SnapshotReportingMode.None; }
private void CaptureSnapshot() { List <double> list = null; double last; double min; double max; int count; double sum; lock (_recordLock) { if (_count > 0) { list = _list; if (list != null) { #if DEBUG if (_warmlist != null) { Debug.WriteLine("BosunReporter: Re-using pre-warmed list for aggregate gauge."); } #endif _list = _warmlist ?? new List <double>(); _warmlist = null; } } last = _last; min = _min; _min = Double.PositiveInfinity; max = _max; _max = Double.NegativeInfinity; sum = _sum; _sum = 0; count = _count; _count = 0; } if (count == 0 || count < MinimumEvents) { _snapshotReportingMode = _reportCount ? SnapshotReportingMode.CountOnly : SnapshotReportingMode.None; } else { _snapshotReportingMode = SnapshotReportingMode.All; } if (_snapshotReportingMode != SnapshotReportingMode.None) { var countOnly = _snapshotReportingMode == SnapshotReportingMode.CountOnly; var lastIndex = 0; if (!countOnly && list != null) { lastIndex = list.Count - 1; if (!_specialCaseLast) { last = list[lastIndex]; } list.Sort(); } for (var i = 0; i < _percentiles.Length; i++) { var mode = PercentileToAggregateMode(_percentiles[i]); if (countOnly && mode != AggregateMode.Count) { continue; } double value; switch (mode) { case AggregateMode.Average: value = sum / count; break; case AggregateMode.Median: case AggregateMode.Percentile: var index = (int)Math.Round(_percentiles[i] * lastIndex); value = list[index]; break; case AggregateMode.Max: value = _specialCaseMax ? max : list[lastIndex]; break; case AggregateMode.Min: value = _specialCaseMin ? min : list[0]; break; case AggregateMode.Last: value = last; break; case AggregateMode.Count: value = count; break; default: throw new NotImplementedException(); } _snapshot[i] = value; } } if (list != null && list.Count * 2 >= list.Capacity) { // if at least half of the list capacity was used, then we'll consider re-using this list. list.Clear(); lock (_recordLock) { _warmlist = list; } } }