Skip to content
Snippets Groups Projects
Commit 2e592492 authored by Sören Henning's avatar Sören Henning
Browse files

Add "first" and "last" aggregation for generic SLO

parent ca2a2fe3
Branches
No related tags found
No related merge requests found
Pipeline #14137 failed
......@@ -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.
......
......@@ -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)
......
......@@ -30,12 +30,18 @@ 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)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment