diff --git a/docs/creating-a-benchmark.md b/docs/creating-a-benchmark.md index bbd3eb372c53d47b249ac7f5aff85d89068f46f7..d9e1b779f434f9d320ddcfb7777b0fb6e5bc58b5 100644 --- a/docs/creating-a-benchmark.md +++ b/docs/creating-a-benchmark.md @@ -193,7 +193,7 @@ A good choice to get started is defining an SLO of type `generic`: ``` All you have to do is to define a [PromQL query](https://prometheus.io/docs/prometheus/latest/querying/basics/) describing which metrics should be requested (`promQLQuery`) and how the resulting time series should be evaluated. With `queryAggregation` you specify how the resulting time series is aggregated to a single value and `repetitionAggregation` describes how the results of multiple repetitions are aggregated. Possible values are -`mean`, `median`, `mode`, `sum`, `count`, `max`, `min`, `std`, `var`, `skew`, `kurt` as well as percentiles such as `p99` or `p99.9`. The result of aggregation all repetitions is checked against `threshold`. This check is performed using an `operator`, which describes that the result must be "less than" (`lt`), "less than equal" (`lte`), "greater than" (`gt`) or "greater than equal" (`gte`) to the threshold. +`mean`, `median`, `mode`, `sum`, `count`, `max`, `min`, `std`, `var`, `skew`, `kurt`, `first`, `last` as well as percentiles such as `p99` or `p99.9`. The result of aggregation all repetitions is checked against `threshold`. This check is performed using an `operator`, which describes that the result must be "less than" (`lt`), "less than equal" (`lte`), "greater than" (`gt`) or "greater than equal" (`gte`) to the threshold. If you do not want to have a static threshold, you can also define it relatively to the tested load with `thresholdRelToLoad` or relatively to the tested resource value with `thresholdRelToResources`. For example, setting `thresholdRelToLoad: 0.01` means that in each experiment, the threshold is 1% of the generated load. Even more complex thresholds can be defined with `thresholdFromExpression`. This field accepts a mathematical expression with two variables `L` and `R` for the load and resources, respectively. The previous example with a threshold of 1% of the generated load can thus also be defined with `thresholdFromExpression: 0.01*L`. For further details of allowed expressions, see the documentation of the underlying [exp4j](https://github.com/fasseg/exp4j) library. diff --git a/slo-checker/generic/app/main.py b/slo-checker/generic/app/main.py index 6dd78ac131c3c5f7a6e163ae729ab3d3e396dbde..ff9de19b542b9ec150a9a4f46c86c930b1253faa 100644 --- a/slo-checker/generic/app/main.py +++ b/slo-checker/generic/app/main.py @@ -25,6 +25,16 @@ elif os.getenv('LOG_LEVEL') == 'DEBUG': def get_aggr_func(func_string: str): if func_string in ['mean', 'median', 'mode', 'sum', 'count', 'max', 'min', 'std', 'var', 'skew', 'kurt']: return func_string + elif func_string == 'first': + def first(x): + return x.iloc[0] + first.__name__ = 'first' + return first + elif func_string == 'last': + def last(x): + return x.iloc[-1] + last.__name__ = 'last' + return last elif re.search(r'^p\d\d?(\.\d+)?$', func_string): # matches strings like 'p99', 'p99.99', 'p1', 'p0.001' def percentile(x): return x.quantile(float(func_string[1:]) / 100) diff --git a/slo-checker/generic/app/test.py b/slo-checker/generic/app/test.py index 2609225ddc9e6e96cdcd01db197cebbdd6501102..8405335f4508644a0b58472e9862f976117107d2 100644 --- a/slo-checker/generic/app/test.py +++ b/slo-checker/generic/app/test.py @@ -30,11 +30,17 @@ class TestSloEvaluation(unittest.TestCase): def test_get_aggr_func_p99_(self): self.assertRaises(ValueError, get_aggr_func, 'p99.') - def test_get_aggr_func_p99_(self): + def test_get_aggr_func_q99(self): self.assertRaises(ValueError, get_aggr_func, 'q99') - def test_get_aggr_func_p99_(self): + def test_get_aggr_func_mux(self): self.assertRaises(ValueError, get_aggr_func, 'mux') + + def test_get_aggr_func_first(self): + self.assertTrue(callable(get_aggr_func('first'))) + + def test_get_aggr_func_last(self): + self.assertTrue(callable(get_aggr_func('last'))) def test_check_result_lt(self): self.assertEqual(check_result(100, 'lt', 200), True)