load 5m http_requests{job="api-server", instance="0", group="production"} 0+10x10 http_requests{job="api-server", instance="1", group="production"} 0+20x10 http_requests{job="api-server", instance="0", group="canary"} 0+30x10 http_requests{job="api-server", instance="1", group="canary"} 0+40x10 http_requests{job="app-server", instance="0", group="production"} 0+50x10 http_requests{job="app-server", instance="1", group="production"} 0+60x10 http_requests{job="app-server", instance="0", group="canary"} 0+70x10 http_requests{job="app-server", instance="1", group="canary"} 0+80x10 load 5m foo{job="api-server", instance="0", region="europe"} 0+90x10 foo{job="api-server"} 0+100x10 # Simple sum. eval instant at 50m SUM BY (group) (http_requests{job="api-server"}) {group="canary"} 700 {group="production"} 300 eval instant at 50m SUM BY (group) (((http_requests{job="api-server"}))) {group="canary"} 700 {group="production"} 300 # Test alternative "by"-clause order. eval instant at 50m sum by (group) (http_requests{job="api-server"}) {group="canary"} 700 {group="production"} 300 # Simple average. eval instant at 50m avg by (group) (http_requests{job="api-server"}) {group="canary"} 350 {group="production"} 150 # Simple count. eval instant at 50m count by (group) (http_requests{job="api-server"}) {group="canary"} 2 {group="production"} 2 # Simple without. eval instant at 50m sum without (instance) (http_requests{job="api-server"}) {group="canary",job="api-server"} 700 {group="production",job="api-server"} 300 # Empty by. eval instant at 50m sum by () (http_requests{job="api-server"}) {} 1000 # No by/without. eval instant at 50m sum(http_requests{job="api-server"}) {} 1000 # Empty without. eval instant at 50m sum without () (http_requests{job="api-server",group="production"}) {group="production",job="api-server",instance="0"} 100 {group="production",job="api-server",instance="1"} 200 # Without with mismatched and missing labels. Do not do this. eval instant at 50m sum without (instance) (http_requests{job="api-server"} or foo) {group="canary",job="api-server"} 700 {group="production",job="api-server"} 300 {region="europe",job="api-server"} 900 {job="api-server"} 1000 # Lower-cased aggregation operators should work too. eval instant at 50m sum(http_requests) by (job) + min(http_requests) by (job) + max(http_requests) by (job) + avg(http_requests) by (job) {job="app-server"} 4550 {job="api-server"} 1750 # Test alternative "by"-clause order. eval instant at 50m sum by (group) (http_requests{job="api-server"}) {group="canary"} 700 {group="production"} 300 # Test both alternative "by"-clause orders in one expression. # Public health warning: stick to one form within an expression (or even # in an organization), or risk serious user confusion. eval instant at 50m sum(sum by (group) (http_requests{job="api-server"})) by (job) {} 1000 eval instant at 50m SUM(http_requests) {} 3600 eval instant at 50m SUM(http_requests{instance="0"}) BY(job) {job="api-server"} 400 {job="app-server"} 1200 eval instant at 50m SUM(http_requests) BY (job) {job="api-server"} 1000 {job="app-server"} 2600 # Non-existent labels mentioned in BY-clauses shouldn't propagate to output. eval instant at 50m SUM(http_requests) BY (job, nonexistent) {job="api-server"} 1000 {job="app-server"} 2600 eval instant at 50m COUNT(http_requests) BY (job) {job="api-server"} 4 {job="app-server"} 4 eval instant at 50m SUM(http_requests) BY (job, group) {group="canary", job="api-server"} 700 {group="canary", job="app-server"} 1500 {group="production", job="api-server"} 300 {group="production", job="app-server"} 1100 eval instant at 50m AVG(http_requests) BY (job) {job="api-server"} 250 {job="app-server"} 650 eval instant at 50m MIN(http_requests) BY (job) {job="api-server"} 100 {job="app-server"} 500 eval instant at 50m MAX(http_requests) BY (job) {job="api-server"} 400 {job="app-server"} 800 eval instant at 50m abs(-1 * http_requests{group="production",job="api-server"}) {group="production", instance="0", job="api-server"} 100 {group="production", instance="1", job="api-server"} 200 eval instant at 50m floor(0.004 * http_requests{group="production",job="api-server"}) {group="production", instance="0", job="api-server"} 0 {group="production", instance="1", job="api-server"} 0 eval instant at 50m ceil(0.004 * http_requests{group="production",job="api-server"}) {group="production", instance="0", job="api-server"} 1 {group="production", instance="1", job="api-server"} 1 eval instant at 50m round(0.004 * http_requests{group="production",job="api-server"}) {group="production", instance="0", job="api-server"} 0 {group="production", instance="1", job="api-server"} 1 # Round should correctly handle negative numbers. eval instant at 50m round(-1 * (0.004 * http_requests{group="production",job="api-server"})) {group="production", instance="0", job="api-server"} 0 {group="production", instance="1", job="api-server"} -1 # Round should round half up. eval instant at 50m round(0.005 * http_requests{group="production",job="api-server"}) {group="production", instance="0", job="api-server"} 1 {group="production", instance="1", job="api-server"} 1 eval instant at 50m round(-1 * (0.005 * http_requests{group="production",job="api-server"})) {group="production", instance="0", job="api-server"} 0 {group="production", instance="1", job="api-server"} -1 eval instant at 50m round(1 + 0.005 * http_requests{group="production",job="api-server"}) {group="production", instance="0", job="api-server"} 2 {group="production", instance="1", job="api-server"} 2 eval instant at 50m round(-1 * (1 + 0.005 * http_requests{group="production",job="api-server"})) {group="production", instance="0", job="api-server"} -1 {group="production", instance="1", job="api-server"} -2 # Round should accept the number to round nearest to. eval instant at 50m round(0.0005 * http_requests{group="production",job="api-server"}, 0.1) {group="production", instance="0", job="api-server"} 0.1 {group="production", instance="1", job="api-server"} 0.1 eval instant at 50m round(2.1 + 0.0005 * http_requests{group="production",job="api-server"}, 0.1) {group="production", instance="0", job="api-server"} 2.2 {group="production", instance="1", job="api-server"} 2.2 eval instant at 50m round(5.2 + 0.0005 * http_requests{group="production",job="api-server"}, 0.1) {group="production", instance="0", job="api-server"} 5.3 {group="production", instance="1", job="api-server"} 5.3 # Round should work correctly with negative numbers and multiple decimal places. eval instant at 50m round(-1 * (5.2 + 0.0005 * http_requests{group="production",job="api-server"}), 0.1) {group="production", instance="0", job="api-server"} -5.2 {group="production", instance="1", job="api-server"} -5.3 # Round should work correctly with big toNearests. eval instant at 50m round(0.025 * http_requests{group="production",job="api-server"}, 5) {group="production", instance="0", job="api-server"} 5 {group="production", instance="1", job="api-server"} 5 eval instant at 50m round(0.045 * http_requests{group="production",job="api-server"}, 5) {group="production", instance="0", job="api-server"} 5 {group="production", instance="1", job="api-server"} 10 # Standard deviation and variance. eval instant at 50m stddev(http_requests) {} 229.12878474779 eval instant at 50m stddev by (instance)(http_requests) {instance="0"} 223.60679774998 {instance="1"} 223.60679774998 eval instant at 50m stdvar(http_requests) {} 52500 eval instant at 50m stdvar by (instance)(http_requests) {instance="0"} 50000 {instance="1"} 50000 # Float precision test for standard deviation and variance clear load 5m http_requests{job="api-server", instance="0", group="production"} 0+1.33x10 http_requests{job="api-server", instance="1", group="production"} 0+1.33x10 http_requests{job="api-server", instance="0", group="canary"} 0+1.33x10 eval instant at 50m stddev(http_requests) {} 0.0 eval instant at 50m stdvar(http_requests) {} 0.0 # Regression test for missing separator byte in labelsToGroupingKey. clear load 5m label_grouping_test{a="aa", b="bb"} 0+10x10 label_grouping_test{a="a", b="abb"} 0+20x10 eval instant at 50m sum(label_grouping_test) by (a, b) {a="a", b="abb"} 200 {a="aa", b="bb"} 100 # Tests for min/max. clear load 5m http_requests{job="api-server", instance="0", group="production"} 1 http_requests{job="api-server", instance="1", group="production"} 2 http_requests{job="api-server", instance="0", group="canary"} NaN http_requests{job="api-server", instance="1", group="canary"} 3 http_requests{job="api-server", instance="2", group="canary"} 4 eval instant at 0m max(http_requests) {} 4 eval instant at 0m min(http_requests) {} 1 eval instant at 0m max by (group) (http_requests) {group="production"} 2 {group="canary"} 4 eval instant at 0m min by (group) (http_requests) {group="production"} 1 {group="canary"} 3 clear # Tests for topk/bottomk. load 5m http_requests{job="api-server", instance="0", group="production"} 0+10x10 http_requests{job="api-server", instance="1", group="production"} 0+20x10 http_requests{job="api-server", instance="2", group="production"} NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN http_requests{job="api-server", instance="0", group="canary"} 0+30x10 http_requests{job="api-server", instance="1", group="canary"} 0+40x10 http_requests{job="app-server", instance="0", group="production"} 0+50x10 http_requests{job="app-server", instance="1", group="production"} 0+60x10 http_requests{job="app-server", instance="0", group="canary"} 0+70x10 http_requests{job="app-server", instance="1", group="canary"} 0+80x10 foo 3+0x10 eval_ordered instant at 50m topk(3, http_requests) http_requests{group="canary", instance="1", job="app-server"} 800 http_requests{group="canary", instance="0", job="app-server"} 700 http_requests{group="production", instance="1", job="app-server"} 600 eval_ordered instant at 50m topk((3), (http_requests)) http_requests{group="canary", instance="1", job="app-server"} 800 http_requests{group="canary", instance="0", job="app-server"} 700 http_requests{group="production", instance="1", job="app-server"} 600 eval_ordered instant at 50m topk(5, http_requests{group="canary",job="app-server"}) http_requests{group="canary", instance="1", job="app-server"} 800 http_requests{group="canary", instance="0", job="app-server"} 700 eval_ordered instant at 50m bottomk(3, http_requests) http_requests{group="production", instance="0", job="api-server"} 100 http_requests{group="production", instance="1", job="api-server"} 200 http_requests{group="canary", instance="0", job="api-server"} 300 eval_ordered instant at 50m bottomk(5, http_requests{group="canary",job="app-server"}) http_requests{group="canary", instance="0", job="app-server"} 700 http_requests{group="canary", instance="1", job="app-server"} 800 eval instant at 50m topk by (group) (1, http_requests) http_requests{group="production", instance="1", job="app-server"} 600 http_requests{group="canary", instance="1", job="app-server"} 800 eval instant at 50m bottomk by (group) (2, http_requests) http_requests{group="canary", instance="0", job="api-server"} 300 http_requests{group="canary", instance="1", job="api-server"} 400 http_requests{group="production", instance="0", job="api-server"} 100 http_requests{group="production", instance="1", job="api-server"} 200 eval_ordered instant at 50m bottomk by (group) (2, http_requests{group="production"}) http_requests{group="production", instance="0", job="api-server"} 100 http_requests{group="production", instance="1", job="api-server"} 200 # Test NaN is sorted away from the top/bottom. eval_ordered instant at 50m topk(3, http_requests{job="api-server",group="production"}) http_requests{job="api-server", instance="1", group="production"} 200 http_requests{job="api-server", instance="0", group="production"} 100 http_requests{job="api-server", instance="2", group="production"} NaN eval_ordered instant at 50m bottomk(3, http_requests{job="api-server",group="production"}) http_requests{job="api-server", instance="0", group="production"} 100 http_requests{job="api-server", instance="1", group="production"} 200 http_requests{job="api-server", instance="2", group="production"} NaN # Test topk and bottomk allocate min(k, input_vector) for results vector eval_ordered instant at 50m bottomk(9999999999, http_requests{job="app-server",group="canary"}) http_requests{group="canary", instance="0", job="app-server"} 700 http_requests{group="canary", instance="1", job="app-server"} 800 eval_ordered instant at 50m topk(9999999999, http_requests{job="api-server",group="production"}) http_requests{job="api-server", instance="1", group="production"} 200 http_requests{job="api-server", instance="0", group="production"} 100 http_requests{job="api-server", instance="2", group="production"} NaN # Bug #5276. eval_ordered instant at 50m topk(scalar(foo), http_requests) http_requests{group="canary", instance="1", job="app-server"} 800 http_requests{group="canary", instance="0", job="app-server"} 700 http_requests{group="production", instance="1", job="app-server"} 600 clear # Tests for count_values. load 5m version{job="api-server", instance="0", group="production"} 6 version{job="api-server", instance="1", group="production"} 6 version{job="api-server", instance="2", group="production"} 6 version{job="api-server", instance="0", group="canary"} 8 version{job="api-server", instance="1", group="canary"} 8 version{job="app-server", instance="0", group="production"} 6 version{job="app-server", instance="1", group="production"} 6 version{job="app-server", instance="0", group="canary"} 7 version{job="app-server", instance="1", group="canary"} 7 eval instant at 1m count_values("version", version) {version="6"} 5 {version="7"} 2 {version="8"} 2 eval instant at 1m count_values(((("version"))), version) {version="6"} 5 {version="7"} 2 {version="8"} 2 eval instant at 1m count_values without (instance)("version", version) {job="api-server", group="production", version="6"} 3 {job="api-server", group="canary", version="8"} 2 {job="app-server", group="production", version="6"} 2 {job="app-server", group="canary", version="7"} 2 # Overwrite label with output. Don't do this. eval instant at 1m count_values without (instance)("job", version) {job="6", group="production"} 5 {job="8", group="canary"} 2 {job="7", group="canary"} 2 # Overwrite label with output. Don't do this. eval instant at 1m count_values by (job, group)("job", version) {job="6", group="production"} 5 {job="8", group="canary"} 2 {job="7", group="canary"} 2 # Tests for quantile. clear load 10s data{test="two samples",point="a"} 0 data{test="two samples",point="b"} 1 data{test="three samples",point="a"} 0 data{test="three samples",point="b"} 1 data{test="three samples",point="c"} 2 data{test="uneven samples",point="a"} 0 data{test="uneven samples",point="b"} 1 data{test="uneven samples",point="c"} 4 foo .8 eval instant at 1m quantile without(point)(0.8, data) {test="two samples"} 0.8 {test="three samples"} 1.6 {test="uneven samples"} 2.8 # Bug #5276. eval instant at 1m quantile without(point)(scalar(foo), data) {test="two samples"} 0.8 {test="three samples"} 1.6 {test="uneven samples"} 2.8 eval instant at 1m quantile without(point)((scalar(foo)), data) {test="two samples"} 0.8 {test="three samples"} 1.6 {test="uneven samples"} 2.8 eval_warn instant at 1m quantile without(point)(NaN, data) {test="two samples"} NaN {test="three samples"} NaN {test="uneven samples"} NaN # Tests for group. clear load 10s data{test="two samples",point="a"} 0 data{test="two samples",point="b"} 1 data{test="three samples",point="a"} 0 data{test="three samples",point="b"} 1 data{test="three samples",point="c"} 2 data{test="uneven samples",point="a"} 0 data{test="uneven samples",point="b"} 1 data{test="uneven samples",point="c"} 4 foo .8 eval instant at 1m group without(point)(data) {test="two samples"} 1 {test="three samples"} 1 {test="uneven samples"} 1 eval instant at 1m group(foo) {} 1 # Tests for avg. clear load 10s data{test="ten",point="a"} 8 data{test="ten",point="b"} 10 data{test="ten",point="c"} 12 data{test="inf",point="a"} 0 data{test="inf",point="b"} Inf data{test="inf",point="d"} Inf data{test="inf",point="c"} 0 data{test="-inf",point="a"} -Inf data{test="-inf",point="b"} -Inf data{test="-inf",point="c"} 0 data{test="inf2",point="a"} Inf data{test="inf2",point="b"} 0 data{test="inf2",point="c"} Inf data{test="-inf2",point="a"} -Inf data{test="-inf2",point="b"} 0 data{test="-inf2",point="c"} -Inf data{test="inf3",point="b"} Inf data{test="inf3",point="d"} Inf data{test="inf3",point="c"} Inf data{test="inf3",point="d"} -Inf data{test="-inf3",point="b"} -Inf data{test="-inf3",point="d"} -Inf data{test="-inf3",point="c"} -Inf data{test="-inf3",point="c"} Inf data{test="nan",point="a"} -Inf data{test="nan",point="b"} 0 data{test="nan",point="c"} Inf data{test="big",point="a"} 9.988465674311579e+307 data{test="big",point="b"} 9.988465674311579e+307 data{test="big",point="c"} 9.988465674311579e+307 data{test="big",point="d"} 9.988465674311579e+307 data{test="-big",point="a"} -9.988465674311579e+307 data{test="-big",point="b"} -9.988465674311579e+307 data{test="-big",point="c"} -9.988465674311579e+307 data{test="-big",point="d"} -9.988465674311579e+307 data{test="bigzero",point="a"} -9.988465674311579e+307 data{test="bigzero",point="b"} -9.988465674311579e+307 data{test="bigzero",point="c"} 9.988465674311579e+307 data{test="bigzero",point="d"} 9.988465674311579e+307 eval instant at 1m avg(data{test="ten"}) {} 10 eval instant at 1m avg(data{test="inf"}) {} Inf eval instant at 1m avg(data{test="inf2"}) {} Inf eval instant at 1m avg(data{test="inf3"}) {} NaN eval instant at 1m avg(data{test="-inf"}) {} -Inf eval instant at 1m avg(data{test="-inf2"}) {} -Inf eval instant at 1m avg(data{test="-inf3"}) {} NaN eval instant at 1m avg(data{test="nan"}) {} NaN eval instant at 1m avg(data{test="big"}) {} 9.988465674311579e+307 eval instant at 1m avg(data{test="-big"}) {} -9.988465674311579e+307 eval instant at 1m avg(data{test="bigzero"}) {} 0 # Test summing and averaging extreme values. clear load 10s data{test="ten",point="a"} 2 data{test="ten",point="b"} 8 data{test="ten",point="c"} 1e+100 data{test="ten",point="d"} -1e100 data{test="pos_inf",group="1",point="a"} Inf data{test="pos_inf",group="1",point="b"} 2 data{test="pos_inf",group="2",point="a"} 2 data{test="pos_inf",group="2",point="b"} Inf data{test="neg_inf",group="1",point="a"} -Inf data{test="neg_inf",group="1",point="b"} 2 data{test="neg_inf",group="2",point="a"} 2 data{test="neg_inf",group="2",point="b"} -Inf data{test="inf_inf",point="a"} Inf data{test="inf_inf",point="b"} -Inf data{test="nan",group="1",point="a"} NaN data{test="nan",group="1",point="b"} 2 data{test="nan",group="2",point="a"} 2 data{test="nan",group="2",point="b"} NaN eval instant at 1m sum(data{test="ten"}) {} 10 eval instant at 1m avg(data{test="ten"}) {} 2.5 eval instant at 1m sum by (group) (data{test="pos_inf"}) {group="1"} Inf {group="2"} Inf eval instant at 1m avg by (group) (data{test="pos_inf"}) {group="1"} Inf {group="2"} Inf eval instant at 1m sum by (group) (data{test="neg_inf"}) {group="1"} -Inf {group="2"} -Inf eval instant at 1m avg by (group) (data{test="neg_inf"}) {group="1"} -Inf {group="2"} -Inf eval instant at 1m sum(data{test="inf_inf"}) {} NaN eval instant at 1m avg(data{test="inf_inf"}) {} NaN eval instant at 1m sum by (group) (data{test="nan"}) {group="1"} NaN {group="2"} NaN eval instant at 1m avg by (group) (data{test="nan"}) {group="1"} NaN {group="2"} NaN clear # Test that aggregations are deterministic. # Commented because it is flaky in range mode. #load 10s # up{job="prometheus"} 1 # up{job="prometheus2"} 1 # #eval instant at 1m count(topk(1,max(up) without()) == topk(1,max(up) without()) == topk(1,max(up) without()) == topk(1,max(up) without()) == topk(1,max(up) without())) # {} 1