Last active
September 19, 2017 20:57
-
-
Save analogrelay/03c6746204317bd3616c372b4df9dbba to your computer and use it in GitHub Desktop.
Sample IMetric implementation for aggregated data.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.Extensions.Logging; | |
namespace MetricsSample | |
{ | |
internal class SampleMetric : IMetric | |
{ | |
private object _lock = new object(); | |
private int _count; | |
private double _sum; | |
private double _sumOfSquares; | |
private double? _max; | |
private double? _min; | |
public string CategoryName { get; } | |
public string Name { get; } | |
public SampleMetric(string categoryName, string name) | |
{ | |
_count = 0; | |
_sum = 0; | |
_sumOfSquares = 0; | |
CategoryName = categoryName; | |
Name = name; | |
} | |
public void RecordValue(double value) | |
{ | |
lock (_lock) | |
{ | |
// This lock is relatively cheap because a) it is separate for each individual metric and b) it is taken over very short time periods involving only arithmetic and memory writing (no I/O) | |
// Of course, it's still a lock. This could even be improved to be somewhat (or even entirely) lock free based on optimistic concurrency principles. | |
if (_max == null || _max.Value < value) | |
{ | |
_max = value; | |
} | |
if (_min == null || _min.Value > value) | |
{ | |
_min = value; | |
} | |
_count += 1; | |
_sum += value; | |
_sumOfSquares += (value * value); | |
} | |
} | |
public MetricAggregates GetAggregates() | |
{ | |
lock (_lock) | |
{ | |
return new MetricAggregates(_count, _sum, _sumOfSquares, _max, _min); | |
} | |
} | |
} | |
public struct MetricAggregates | |
{ | |
public int Count { get; } | |
public double Sum { get; } | |
public double SumOfSquares { get; } | |
public double? Max { get; } | |
public double? Min { get; } | |
public MetricAggregates(int count, double sum, double sumOfSquares, double? max, double? min) | |
{ | |
Count = count; | |
Sum = sum; | |
SumOfSquares = sumOfSquares; | |
Max = max; | |
Min = min; | |
} | |
public double GetMean() => Sum / Count; | |
// Estimated std-dev via online sum-of-squares method. | |
public double GetStdDev() => Math.Sqrt((SumOfSquares - ((Sum * Sum) / Count)) / (Count - 1)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment