Add benchmarks to prometheus#346
Conversation
| module Stats = { | ||
| open Belt | ||
| type t = { | ||
| n: int, | ||
| mean: float, | ||
| @as("std-dev") stdDev: float, | ||
| min: float, | ||
| max: float, | ||
| sum: float, | ||
| } | ||
|
|
||
| let round = (float, ~precision=2) => { | ||
| let factor = Js.Math.pow_float(~base=10.0, ~exp=precision->Int.toFloat) | ||
| Js.Math.round(float *. factor) /. factor | ||
| } | ||
|
|
||
| let makeFromDataSet = (dataSet: SummaryData.DataSet.t) => { | ||
| let n = dataSet.count | ||
| let countBigDecimal = n->BigDecimal.fromInt | ||
| let mean = dataSet.sum->BigDecimal.div(countBigDecimal) | ||
| let variance = | ||
| dataSet.sumOfSquares | ||
| ->BigDecimal.div(countBigDecimal) | ||
| ->BigDecimal.minus(mean->BigDecimal.times(mean)) | ||
| let stdDev = BigDecimal.sqrt(variance) | ||
| let roundBigDecimal = bd => | ||
| bd->BigDecimal.decimalPlaces(dataSet.decimalPlaces)->BigDecimal.toNumber | ||
| let roundFloat = float => float->round(~precision=dataSet.decimalPlaces) | ||
| { | ||
| n, | ||
| mean: mean->roundBigDecimal, | ||
| stdDev: stdDev->roundBigDecimal, | ||
| min: dataSet.min->roundFloat, | ||
| max: dataSet.max->roundFloat, | ||
| sum: dataSet.sum->roundBigDecimal, | ||
| } | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
Moved out of the "Summary" module below
| let saveLiveMetrics = if ( | ||
| Env.Benchmark.saveDataStrategy->Env.Benchmark.SaveDataStrategy.shouldSavePrometheus | ||
| ) { | ||
| let throttlerMapping = ThrottlerMapping.make() | ||
|
|
||
| (dataSet: SummaryData.DataSet.t, ~group, ~label) => { | ||
| let throttler = throttlerMapping->ThrottlerMapping.get(~group, ~label) | ||
| throttler->Throttler.schedule(() => { | ||
| let {n, mean, stdDev, min, max, sum} = dataSet->Stats.makeFromDataSet | ||
| Prometheus.setBenchmarkSummaryData( | ||
| ~group, | ||
| ~label, | ||
| ~n, | ||
| ~mean, | ||
| ~stdDev, | ||
| ~min, | ||
| ~max, | ||
| ~sum, | ||
| )->Promise.resolve | ||
| }) | ||
| } | ||
| } else { | ||
| (_dataSet, ~group as _, ~label as _) => () | ||
| } |
There was a problem hiding this comment.
If ENVIO_SAVE_BENCHMARK_DATA_STRATEGY="prometheus" this will return true. I black boxed the strategy type since we may want to introduce other things like saving to postgres orboth prometheus and another type etc.
| let throttlerMapping = ThrottlerMapping.make() | ||
|
|
||
| (dataSet: SummaryData.DataSet.t, ~group, ~label) => { | ||
| let throttler = throttlerMapping->ThrottlerMapping.get(~group, ~label) |
There was a problem hiding this comment.
Throttler for setting prometheus is per group/label of the data set
DZakh
left a comment
There was a problem hiding this comment.
Looks good, but I'd like to have a single env var for the benchmark configuration
| let shouldSaveData = envSafe->EnvSafe.get("ENVIO_SAVE_BENCHMARK_DATA", S.bool, ~fallback=false) | ||
| let saveDataStrategy = | ||
| envSafe->EnvSafe.get( | ||
| "ENVIO_SAVE_BENCHMARK_DATA_STRATEGY", | ||
| SaveDataStrategy.schema, | ||
| ~fallback=SaveDataStrategy.default, | ||
| ) |
There was a problem hiding this comment.
How about having a single env var with options:
- true (JsonFile)
- json-file (JsonFile)
- prometheus (Prometheus)
There was a problem hiding this comment.
Ok sure that works 👍🏼
There was a problem hiding this comment.
@DZakh check the latest commit and lmk if you're happy 👍🏼
9e938d2 to
599280c
Compare
No description provided.