|
|
|
# Testdata for resets() and changes().
|
|
|
|
load 5m
|
|
|
|
http_requests{path="/foo"} 1 2 3 0 1 0 0 1 2 0
|
|
|
|
http_requests{path="/bar"} 1 2 3 4 5 1 2 3 4 5
|
|
|
|
http_requests{path="/biz"} 0 0 0 0 0 1 1 1 1 1
|
|
|
|
|
|
|
|
# Tests for resets().
|
|
|
|
eval instant at 50m resets(http_requests[5m])
|
|
|
|
{path="/foo"} 0
|
|
|
|
{path="/bar"} 0
|
|
|
|
{path="/biz"} 0
|
|
|
|
|
|
|
|
eval instant at 50m resets(http_requests[20m])
|
|
|
|
{path="/foo"} 1
|
|
|
|
{path="/bar"} 0
|
|
|
|
{path="/biz"} 0
|
|
|
|
|
|
|
|
eval instant at 50m resets(http_requests[30m])
|
|
|
|
{path="/foo"} 2
|
|
|
|
{path="/bar"} 1
|
|
|
|
{path="/biz"} 0
|
|
|
|
|
|
|
|
eval instant at 50m resets(http_requests[50m])
|
|
|
|
{path="/foo"} 3
|
|
|
|
{path="/bar"} 1
|
|
|
|
{path="/biz"} 0
|
|
|
|
|
|
|
|
eval instant at 50m resets(nonexistent_metric[50m])
|
|
|
|
|
|
|
|
# Tests for changes().
|
|
|
|
eval instant at 50m changes(http_requests[5m])
|
|
|
|
{path="/foo"} 0
|
|
|
|
{path="/bar"} 0
|
|
|
|
{path="/biz"} 0
|
|
|
|
|
|
|
|
eval instant at 50m changes(http_requests[20m])
|
|
|
|
{path="/foo"} 3
|
|
|
|
{path="/bar"} 3
|
|
|
|
{path="/biz"} 0
|
|
|
|
|
|
|
|
eval instant at 50m changes(http_requests[30m])
|
|
|
|
{path="/foo"} 4
|
|
|
|
{path="/bar"} 5
|
|
|
|
{path="/biz"} 1
|
|
|
|
|
|
|
|
eval instant at 50m changes(http_requests[50m])
|
|
|
|
{path="/foo"} 8
|
|
|
|
{path="/bar"} 9
|
|
|
|
{path="/biz"} 1
|
|
|
|
|
|
|
|
eval instant at 50m changes((http_requests[50m]))
|
|
|
|
{path="/foo"} 8
|
|
|
|
{path="/bar"} 9
|
|
|
|
{path="/biz"} 1
|
|
|
|
|
|
|
|
eval instant at 50m changes(nonexistent_metric[50m])
|
|
|
|
|
|
|
|
clear
|
|
|
|
|
|
|
|
load 5m
|
|
|
|
x{a="b"} NaN NaN NaN
|
|
|
|
x{a="c"} 0 NaN 0
|
|
|
|
|
|
|
|
eval instant at 15m changes(x[15m])
|
|
|
|
{a="b"} 0
|
|
|
|
{a="c"} 2
|
|
|
|
|
|
|
|
clear
|
|
|
|
|
|
|
|
# Tests for increase().
|
|
|
|
load 5m
|
|
|
|
http_requests{path="/foo"} 0+10x10
|
|
|
|
http_requests{path="/bar"} 0+10x5 0+10x5
|
promql: Fix limiting of extrapolation to negative values
This is a bit tough to explain, but I'll try:
`rate` & friends have a sophisticated extrapolation algorithm.
Usually, we extrapolate the result to the total interval specified in
the range selector. However, if the first sample within the range is
too far away from the beginning of the interval, or if the last sample
within the range is too far away from the end of the interval, we
assume the series has just started half a sampling interval before the
first sample or after the last sample, respectively, and shorten the
extrapolation interval correspondingly. We calculate the sampling
interval by looking at the average time between samples within the
range, and we define "too far away" as "more than 110% of that
sampling interval".
However, if this algorithm leads to an extrapolated starting value
that is negative, we limit the start of the extrapolation interval to
the point where the extrapolated starting value is zero.
At least that was the intention.
What we actually implemented is the following: If extrapolating all
the way to the beginning of the total interval would lead to an
extrapolated negative value, we would only extrapolate to the zero
point as above, even if the algorithm above would have selected a
starting point that is just half a sampling interval before the first
sample and that starting point would not have an extrapolated negative
value. In other word: What was meant as a _limitation_ of the
extrapolation interval yielded a _longer_ extrapolation interval in
this case.
There is an exception to the case just described: If the increase of
the extrapolation interval is more than 110% of the sampling interval,
we suddenly drop back to only extrapolate to half a sampling interval.
This behavior can be nicely seen in the testcounter_zero_cutoff test,
where the rate goes up all the way to 0.7 and then jumps back to 0.6.
This commit changes the behavior to what was (presumably) intended
from the beginning: The extension of the extrapolation interval is
only limited if actually needed to prevent extrapolation to negative
values, but the "limitation" never leads to _more_ extrapolation
anymore.
The difference is subtle, and probably it never bothered anyone.
However, if you calculate a rate of a classic histograms, the old
behavior might create non-monotonic histograms as a result (because of
the jumps you can see nicely in the old version of the
testcounter_zero_cutoff test). With this fix, that doesn't happen
anymore.
Signed-off-by: beorn7 <beorn@grafana.com>
9 months ago
|
|
|
http_requests{path="/dings"} 10+10x10
|
|
|
|
http_requests{path="/bumms"} 1+10x10
|
|
|
|
|
|
|
|
# Tests for increase().
|
|
|
|
eval instant at 50m increase(http_requests[50m])
|
promql: Fix limiting of extrapolation to negative values
This is a bit tough to explain, but I'll try:
`rate` & friends have a sophisticated extrapolation algorithm.
Usually, we extrapolate the result to the total interval specified in
the range selector. However, if the first sample within the range is
too far away from the beginning of the interval, or if the last sample
within the range is too far away from the end of the interval, we
assume the series has just started half a sampling interval before the
first sample or after the last sample, respectively, and shorten the
extrapolation interval correspondingly. We calculate the sampling
interval by looking at the average time between samples within the
range, and we define "too far away" as "more than 110% of that
sampling interval".
However, if this algorithm leads to an extrapolated starting value
that is negative, we limit the start of the extrapolation interval to
the point where the extrapolated starting value is zero.
At least that was the intention.
What we actually implemented is the following: If extrapolating all
the way to the beginning of the total interval would lead to an
extrapolated negative value, we would only extrapolate to the zero
point as above, even if the algorithm above would have selected a
starting point that is just half a sampling interval before the first
sample and that starting point would not have an extrapolated negative
value. In other word: What was meant as a _limitation_ of the
extrapolation interval yielded a _longer_ extrapolation interval in
this case.
There is an exception to the case just described: If the increase of
the extrapolation interval is more than 110% of the sampling interval,
we suddenly drop back to only extrapolate to half a sampling interval.
This behavior can be nicely seen in the testcounter_zero_cutoff test,
where the rate goes up all the way to 0.7 and then jumps back to 0.6.
This commit changes the behavior to what was (presumably) intended
from the beginning: The extension of the extrapolation interval is
only limited if actually needed to prevent extrapolation to negative
values, but the "limitation" never leads to _more_ extrapolation
anymore.
The difference is subtle, and probably it never bothered anyone.
However, if you calculate a rate of a classic histograms, the old
behavior might create non-monotonic histograms as a result (because of
the jumps you can see nicely in the old version of the
testcounter_zero_cutoff test). With this fix, that doesn't happen
anymore.
Signed-off-by: beorn7 <beorn@grafana.com>
9 months ago
|
|
|
{path="/foo"} 100
|
|
|
|
{path="/bar"} 90
|
|
|
|
{path="/dings"} 100
|
|
|
|
{path="/bumms"} 100
|
|
|
|
|
|
|
|
# "foo" and "bar" are already at value 0 at t=0, so no extrapolation
|
|
|
|
# happens. "dings" has value 10 at t=0 and would reach 0 at t=-5m. The
|
|
|
|
# normal extrapolation by half a sample interval only goes to
|
|
|
|
# t=-2m30s, so that's not yet reaching a negative value and therefore
|
|
|
|
# chosen. However, "bumms" has value 1 at t=0 and would reach 0 at
|
|
|
|
# t=-30s. Here the extrapolation to t=-2m30s would reach a negative
|
|
|
|
# value, and therefore the extrapolation happens only by 30s.
|
|
|
|
eval instant at 50m increase(http_requests[100m])
|
promql: Fix limiting of extrapolation to negative values
This is a bit tough to explain, but I'll try:
`rate` & friends have a sophisticated extrapolation algorithm.
Usually, we extrapolate the result to the total interval specified in
the range selector. However, if the first sample within the range is
too far away from the beginning of the interval, or if the last sample
within the range is too far away from the end of the interval, we
assume the series has just started half a sampling interval before the
first sample or after the last sample, respectively, and shorten the
extrapolation interval correspondingly. We calculate the sampling
interval by looking at the average time between samples within the
range, and we define "too far away" as "more than 110% of that
sampling interval".
However, if this algorithm leads to an extrapolated starting value
that is negative, we limit the start of the extrapolation interval to
the point where the extrapolated starting value is zero.
At least that was the intention.
What we actually implemented is the following: If extrapolating all
the way to the beginning of the total interval would lead to an
extrapolated negative value, we would only extrapolate to the zero
point as above, even if the algorithm above would have selected a
starting point that is just half a sampling interval before the first
sample and that starting point would not have an extrapolated negative
value. In other word: What was meant as a _limitation_ of the
extrapolation interval yielded a _longer_ extrapolation interval in
this case.
There is an exception to the case just described: If the increase of
the extrapolation interval is more than 110% of the sampling interval,
we suddenly drop back to only extrapolate to half a sampling interval.
This behavior can be nicely seen in the testcounter_zero_cutoff test,
where the rate goes up all the way to 0.7 and then jumps back to 0.6.
This commit changes the behavior to what was (presumably) intended
from the beginning: The extension of the extrapolation interval is
only limited if actually needed to prevent extrapolation to negative
values, but the "limitation" never leads to _more_ extrapolation
anymore.
The difference is subtle, and probably it never bothered anyone.
However, if you calculate a rate of a classic histograms, the old
behavior might create non-monotonic histograms as a result (because of
the jumps you can see nicely in the old version of the
testcounter_zero_cutoff test). With this fix, that doesn't happen
anymore.
Signed-off-by: beorn7 <beorn@grafana.com>
9 months ago
|
|
|
{path="/foo"} 100
|
|
|
|
{path="/bar"} 90
|
|
|
|
{path="/dings"} 105
|
|
|
|
{path="/bumms"} 101
|
|
|
|
|
|
|
|
clear
|
|
|
|
|
|
|
|
# Test for increase() with counter reset.
|
|
|
|
# When the counter is reset, it always starts at 0.
|
|
|
|
# So the sequence 3 2 (decreasing counter = reset) is interpreted the same as 3 0 1 2.
|
|
|
|
# Prometheus assumes it missed the intermediate values 0 and 1.
|
|
|
|
load 5m
|
|
|
|
http_requests{path="/foo"} 0 1 2 3 2 3 4
|
|
|
|
|
|
|
|
eval instant at 30m increase(http_requests[30m])
|
|
|
|
{path="/foo"} 7
|
|
|
|
|
|
|
|
clear
|
|
|
|
|
|
|
|
# Tests for rate().
|
|
|
|
load 5m
|
|
|
|
testcounter_reset_middle 0+10x4 0+10x5
|
|
|
|
testcounter_reset_end 0+10x9 0 10
|
|
|
|
|
|
|
|
# Counter resets at in the middle of range are handled correctly by rate().
|
|
|
|
eval instant at 50m rate(testcounter_reset_middle[50m])
|
|
|
|
{} 0.03
|
|
|
|
|
|
|
|
# Counter resets at end of range are ignored by rate().
|
|
|
|
eval instant at 50m rate(testcounter_reset_end[5m])
|
|
|
|
{} 0
|
|
|
|
|
|
|
|
clear
|
|
|
|
|
|
|
|
load 5m
|
|
|
|
calculate_rate_offset{x="a"} 0+10x10
|
|
|
|
calculate_rate_offset{x="b"} 0+20x10
|
|
|
|
calculate_rate_window 0+80x10
|
|
|
|
|
|
|
|
# Rates should calculate per-second rates.
|
|
|
|
eval instant at 50m rate(calculate_rate_window[50m])
|
|
|
|
{} 0.26666666666666666
|
|
|
|
|
|
|
|
eval instant at 50m rate(calculate_rate_offset[10m] offset 5m)
|
|
|
|
{x="a"} 0.03333333333333333
|
|
|
|
{x="b"} 0.06666666666666667
|
|
|
|
|
|
|
|
clear
|
|
|
|
|
|
|
|
load 4m
|
|
|
|
testcounter_zero_cutoff{start="0m"} 0+240x10
|
|
|
|
testcounter_zero_cutoff{start="1m"} 60+240x10
|
|
|
|
testcounter_zero_cutoff{start="2m"} 120+240x10
|
|
|
|
testcounter_zero_cutoff{start="3m"} 180+240x10
|
|
|
|
testcounter_zero_cutoff{start="4m"} 240+240x10
|
|
|
|
testcounter_zero_cutoff{start="5m"} 300+240x10
|
|
|
|
|
promql: Fix limiting of extrapolation to negative values
This is a bit tough to explain, but I'll try:
`rate` & friends have a sophisticated extrapolation algorithm.
Usually, we extrapolate the result to the total interval specified in
the range selector. However, if the first sample within the range is
too far away from the beginning of the interval, or if the last sample
within the range is too far away from the end of the interval, we
assume the series has just started half a sampling interval before the
first sample or after the last sample, respectively, and shorten the
extrapolation interval correspondingly. We calculate the sampling
interval by looking at the average time between samples within the
range, and we define "too far away" as "more than 110% of that
sampling interval".
However, if this algorithm leads to an extrapolated starting value
that is negative, we limit the start of the extrapolation interval to
the point where the extrapolated starting value is zero.
At least that was the intention.
What we actually implemented is the following: If extrapolating all
the way to the beginning of the total interval would lead to an
extrapolated negative value, we would only extrapolate to the zero
point as above, even if the algorithm above would have selected a
starting point that is just half a sampling interval before the first
sample and that starting point would not have an extrapolated negative
value. In other word: What was meant as a _limitation_ of the
extrapolation interval yielded a _longer_ extrapolation interval in
this case.
There is an exception to the case just described: If the increase of
the extrapolation interval is more than 110% of the sampling interval,
we suddenly drop back to only extrapolate to half a sampling interval.
This behavior can be nicely seen in the testcounter_zero_cutoff test,
where the rate goes up all the way to 0.7 and then jumps back to 0.6.
This commit changes the behavior to what was (presumably) intended
from the beginning: The extension of the extrapolation interval is
only limited if actually needed to prevent extrapolation to negative
values, but the "limitation" never leads to _more_ extrapolation
anymore.
The difference is subtle, and probably it never bothered anyone.
However, if you calculate a rate of a classic histograms, the old
behavior might create non-monotonic histograms as a result (because of
the jumps you can see nicely in the old version of the
testcounter_zero_cutoff test). With this fix, that doesn't happen
anymore.
Signed-off-by: beorn7 <beorn@grafana.com>
9 months ago
|
|
|
# Zero cutoff for left-side extrapolation happens until we
|
|
|
|
# reach half a sampling interval (2m). Beyond that, we only
|
|
|
|
# extrapolate by half a sampling interval.
|
|
|
|
eval instant at 10m rate(testcounter_zero_cutoff[20m])
|
|
|
|
{start="0m"} 0.5
|
|
|
|
{start="1m"} 0.55
|
|
|
|
{start="2m"} 0.6
|
promql: Fix limiting of extrapolation to negative values
This is a bit tough to explain, but I'll try:
`rate` & friends have a sophisticated extrapolation algorithm.
Usually, we extrapolate the result to the total interval specified in
the range selector. However, if the first sample within the range is
too far away from the beginning of the interval, or if the last sample
within the range is too far away from the end of the interval, we
assume the series has just started half a sampling interval before the
first sample or after the last sample, respectively, and shorten the
extrapolation interval correspondingly. We calculate the sampling
interval by looking at the average time between samples within the
range, and we define "too far away" as "more than 110% of that
sampling interval".
However, if this algorithm leads to an extrapolated starting value
that is negative, we limit the start of the extrapolation interval to
the point where the extrapolated starting value is zero.
At least that was the intention.
What we actually implemented is the following: If extrapolating all
the way to the beginning of the total interval would lead to an
extrapolated negative value, we would only extrapolate to the zero
point as above, even if the algorithm above would have selected a
starting point that is just half a sampling interval before the first
sample and that starting point would not have an extrapolated negative
value. In other word: What was meant as a _limitation_ of the
extrapolation interval yielded a _longer_ extrapolation interval in
this case.
There is an exception to the case just described: If the increase of
the extrapolation interval is more than 110% of the sampling interval,
we suddenly drop back to only extrapolate to half a sampling interval.
This behavior can be nicely seen in the testcounter_zero_cutoff test,
where the rate goes up all the way to 0.7 and then jumps back to 0.6.
This commit changes the behavior to what was (presumably) intended
from the beginning: The extension of the extrapolation interval is
only limited if actually needed to prevent extrapolation to negative
values, but the "limitation" never leads to _more_ extrapolation
anymore.
The difference is subtle, and probably it never bothered anyone.
However, if you calculate a rate of a classic histograms, the old
behavior might create non-monotonic histograms as a result (because of
the jumps you can see nicely in the old version of the
testcounter_zero_cutoff test). With this fix, that doesn't happen
anymore.
Signed-off-by: beorn7 <beorn@grafana.com>
9 months ago
|
|
|
{start="3m"} 0.6
|
|
|
|
{start="4m"} 0.6
|
|
|
|
{start="5m"} 0.6
|
|
|
|
|
|
|
|
# Normal half-interval cutoff for left-side extrapolation.
|
|
|
|
eval instant at 50m rate(testcounter_zero_cutoff[20m])
|
|
|
|
{start="0m"} 0.6
|
|
|
|
{start="1m"} 0.6
|
|
|
|
{start="2m"} 0.6
|
|
|
|
{start="3m"} 0.6
|
|
|
|
{start="4m"} 0.6
|
|
|
|
{start="5m"} 0.6
|
|
|
|
|
|
|
|
clear
|
|
|
|
|
|
|
|
# Tests for irate().
|
|
|
|
load 5m
|
|
|
|
http_requests{path="/foo"} 0+10x10
|
|
|
|
http_requests{path="/bar"} 0+10x5 0+10x5
|
|
|
|
|
|
|
|
eval instant at 50m irate(http_requests[50m])
|
|
|
|
{path="/foo"} .03333333333333333333
|
|
|
|
{path="/bar"} .03333333333333333333
|
|
|
|
|
|
|
|
# Counter reset.
|
|
|
|
eval instant at 30m irate(http_requests[50m])
|
|
|
|
{path="/foo"} .03333333333333333333
|
|
|
|
{path="/bar"} 0
|
|
|
|
|
|
|
|
clear
|
|
|
|
|
|
|
|
# Tests for delta().
|
|
|
|
load 5m
|
|
|
|
http_requests{path="/foo"} 0 50 100 150 200
|
|
|
|
http_requests{path="/bar"} 200 150 100 50 0
|
|
|
|
|
|
|
|
eval instant at 20m delta(http_requests[20m])
|
|
|
|
{path="/foo"} 200
|
|
|
|
{path="/bar"} -200
|
|
|
|
|
|
|
|
clear
|
|
|
|
|
|
|
|
# Tests for idelta().
|
|
|
|
load 5m
|
|
|
|
http_requests{path="/foo"} 0 50 100 150
|
|
|
|
http_requests{path="/bar"} 0 50 100 50
|
|
|
|
|
|
|
|
eval instant at 20m idelta(http_requests[20m])
|
|
|
|
{path="/foo"} 50
|
|
|
|
{path="/bar"} -50
|
|
|
|
|
|
|
|
clear
|
|
|
|
|
|
|
|
# Tests for deriv() and predict_linear().
|
|
|
|
load 5m
|
|
|
|
testcounter_reset_middle 0+10x4 0+10x5
|
|
|
|
http_requests{job="app-server", instance="1", group="canary"} 0+80x10
|
|
|
|
|
|
|
|
# deriv should return the same as rate in simple cases.
|
|
|
|
eval instant at 50m rate(http_requests{group="canary", instance="1", job="app-server"}[50m])
|
|
|
|
{group="canary", instance="1", job="app-server"} 0.26666666666666666
|
|
|
|
|
|
|
|
eval instant at 50m deriv(http_requests{group="canary", instance="1", job="app-server"}[50m])
|
|
|
|
{group="canary", instance="1", job="app-server"} 0.26666666666666666
|
|
|
|
|
|
|
|
# deriv should return correct result.
|
|
|
|
eval instant at 50m deriv(testcounter_reset_middle[100m])
|
|
|
|
{} 0.010606060606060607
|
|
|
|
|
|
|
|
# predict_linear should return correct result.
|
|
|
|
# X/s = [ 0, 300, 600, 900,1200,1500,1800,2100,2400,2700,3000]
|
|
|
|
# Y = [ 0, 10, 20, 30, 40, 0, 10, 20, 30, 40, 50]
|
|
|
|
# sumX = 16500
|
|
|
|
# sumY = 250
|
|
|
|
# sumXY = 480000
|
|
|
|
# sumX2 = 34650000
|
|
|
|
# n = 11
|
|
|
|
# covXY = 105000
|
|
|
|
# varX = 9900000
|
|
|
|
# slope = 0.010606060606060607
|
|
|
|
# intercept at t=0: 6.818181818181818
|
|
|
|
# intercept at t=3000: 38.63636363636364
|
|
|
|
# intercept at t=3000+3600: 76.81818181818181
|
|
|
|
eval instant at 50m predict_linear(testcounter_reset_middle[50m], 3600)
|
|
|
|
{} 76.81818181818181
|
|
|
|
|
|
|
|
# intercept at t = 3000+3600 = 6600
|
|
|
|
eval instant at 50m predict_linear(testcounter_reset_middle[50m] @ 3000, 3600)
|
|
|
|
{} 76.81818181818181
|
|
|
|
|
|
|
|
# intercept at t = 600+3600 = 4200
|
|
|
|
eval instant at 10m predict_linear(testcounter_reset_middle[50m] @ 3000, 3600)
|
|
|
|
{} 51.36363636363637
|
|
|
|
|
|
|
|
# intercept at t = 4200+3600 = 7800
|
|
|
|
eval instant at 70m predict_linear(testcounter_reset_middle[50m] @ 3000, 3600)
|
|
|
|
{} 89.54545454545455
|
|
|
|
|
|
|
|
# With http_requests, there is a sample value exactly at the end of
|
|
|
|
# the range, and it has exactly the predicted value, so predict_linear
|
|
|
|
# can be emulated with deriv.
|
|
|
|
eval instant at 50m predict_linear(http_requests[50m], 3600) - (http_requests + deriv(http_requests[50m]) * 3600)
|
|
|
|
{group="canary", instance="1", job="app-server"} 0
|
|
|
|
|
|
|
|
clear
|
|
|
|
|
|
|
|
# Tests for label_replace.
|
|
|
|
load 5m
|
|
|
|
testmetric{src="source-value-10",dst="original-destination-value"} 0
|
|
|
|
testmetric{src="source-value-20",dst="original-destination-value"} 1
|
|
|
|
|
|
|
|
# label_replace does a full-string match and replace.
|
|
|
|
eval instant at 0m label_replace(testmetric, "dst", "destination-value-$1", "src", "source-value-(.*)")
|
|
|
|
testmetric{src="source-value-10",dst="destination-value-10"} 0
|
|
|
|
testmetric{src="source-value-20",dst="destination-value-20"} 1
|
|
|
|
|
|
|
|
# label_replace does not do a sub-string match.
|
|
|
|
eval instant at 0m label_replace(testmetric, "dst", "destination-value-$1", "src", "value-(.*)")
|
|
|
|
testmetric{src="source-value-10",dst="original-destination-value"} 0
|
|
|
|
testmetric{src="source-value-20",dst="original-destination-value"} 1
|
|
|
|
|
|
|
|
# label_replace works with multiple capture groups.
|
|
|
|
eval instant at 0m label_replace(testmetric, "dst", "$1-value-$2", "src", "(.*)-value-(.*)")
|
|
|
|
testmetric{src="source-value-10",dst="source-value-10"} 0
|
|
|
|
testmetric{src="source-value-20",dst="source-value-20"} 1
|
|
|
|
|
|
|
|
# label_replace does not overwrite the destination label if the source label
|
|
|
|
# does not exist.
|
|
|
|
eval instant at 0m label_replace(testmetric, "dst", "value-$1", "nonexistent-src", "source-value-(.*)")
|
|
|
|
testmetric{src="source-value-10",dst="original-destination-value"} 0
|
|
|
|
testmetric{src="source-value-20",dst="original-destination-value"} 1
|
|
|
|
|
|
|
|
# label_replace overwrites the destination label if the source label is empty,
|
|
|
|
# but matched.
|
|
|
|
eval instant at 0m label_replace(testmetric, "dst", "value-$1", "nonexistent-src", "(.*)")
|
|
|
|
testmetric{src="source-value-10",dst="value-"} 0
|
|
|
|
testmetric{src="source-value-20",dst="value-"} 1
|
|
|
|
|
|
|
|
# label_replace does not overwrite the destination label if the source label
|
|
|
|
# is not matched.
|
|
|
|
eval instant at 0m label_replace(testmetric, "dst", "value-$1", "src", "non-matching-regex")
|
|
|
|
testmetric{src="source-value-10",dst="original-destination-value"} 0
|
|
|
|
testmetric{src="source-value-20",dst="original-destination-value"} 1
|
|
|
|
|
|
|
|
eval instant at 0m label_replace((((testmetric))), (("dst")), (("value-$1")), (("src")), (("non-matching-regex")))
|
|
|
|
testmetric{src="source-value-10",dst="original-destination-value"} 0
|
|
|
|
testmetric{src="source-value-20",dst="original-destination-value"} 1
|
|
|
|
|
|
|
|
# label_replace drops labels that are set to empty values.
|
|
|
|
eval instant at 0m label_replace(testmetric, "dst", "", "dst", ".*")
|
|
|
|
testmetric{src="source-value-10"} 0
|
|
|
|
testmetric{src="source-value-20"} 1
|
|
|
|
|
|
|
|
# label_replace fails when the regex is invalid.
|
|
|
|
eval_fail instant at 0m label_replace(testmetric, "dst", "value-$1", "src", "(.*")
|
|
|
|
|
|
|
|
# label_replace fails when the destination label name is not a valid Prometheus label name.
|
|
|
|
eval_fail instant at 0m label_replace(testmetric, "invalid-label-name", "", "src", "(.*)")
|
|
|
|
|
|
|
|
# label_replace fails when there would be duplicated identical output label sets.
|
|
|
|
eval_fail instant at 0m label_replace(testmetric, "src", "", "", "")
|
|
|
|
|
|
|
|
clear
|
|
|
|
|
|
|
|
# Tests for vector, time and timestamp.
|
|
|
|
load 10s
|
|
|
|
metric 1 1
|
|
|
|
|
|
|
|
eval instant at 0s timestamp(metric)
|
|
|
|
{} 0
|
|
|
|
|
|
|
|
eval instant at 5s timestamp(metric)
|
|
|
|
{} 0
|
|
|
|
|
|
|
|
eval instant at 5s timestamp(((metric)))
|
|
|
|
{} 0
|
|
|
|
|
|
|
|
eval instant at 10s timestamp(metric)
|
|
|
|
{} 10
|
|
|
|
|
|
|
|
eval instant at 10s timestamp(((metric)))
|
|
|
|
{} 10
|
|
|
|
|
|
|
|
# Tests for label_join.
|
|
|
|
load 5m
|
|
|
|
testmetric{src="a",src1="b",src2="c",dst="original-destination-value"} 0
|
|
|
|
testmetric{src="d",src1="e",src2="f",dst="original-destination-value"} 1
|
|
|
|
|
|
|
|
# label_join joins all src values in order.
|
|
|
|
eval instant at 0m label_join(testmetric, "dst", "-", "src", "src1", "src2")
|
|
|
|
testmetric{src="a",src1="b",src2="c",dst="a-b-c"} 0
|
|
|
|
testmetric{src="d",src1="e",src2="f",dst="d-e-f"} 1
|
|
|
|
|
|
|
|
# label_join treats non existent src labels as empty strings.
|
|
|
|
eval instant at 0m label_join(testmetric, "dst", "-", "src", "src3", "src1")
|
|
|
|
testmetric{src="a",src1="b",src2="c",dst="a--b"} 0
|
|
|
|
testmetric{src="d",src1="e",src2="f",dst="d--e"} 1
|
|
|
|
|
|
|
|
# label_join overwrites the destination label even if the resulting dst label is empty string
|
|
|
|
eval instant at 0m label_join(testmetric, "dst", "", "emptysrc", "emptysrc1", "emptysrc2")
|
|
|
|
testmetric{src="a",src1="b",src2="c"} 0
|
|
|
|
testmetric{src="d",src1="e",src2="f"} 1
|
|
|
|
|
|
|
|
# test without src label for label_join
|
|
|
|
eval instant at 0m label_join(testmetric, "dst", ", ")
|
|
|
|
testmetric{src="a",src1="b",src2="c"} 0
|
|
|
|
testmetric{src="d",src1="e",src2="f"} 1
|
|
|
|
|
|
|
|
# test without dst label for label_join
|
|
|
|
load 5m
|
|
|
|
testmetric1{src="foo",src1="bar",src2="foobar"} 0
|
|
|
|
testmetric1{src="fizz",src1="buzz",src2="fizzbuzz"} 1
|
|
|
|
|
|
|
|
# label_join creates dst label if not present.
|
|
|
|
eval instant at 0m label_join(testmetric1, "dst", ", ", "src", "src1", "src2")
|
|
|
|
testmetric1{src="foo",src1="bar",src2="foobar",dst="foo, bar, foobar"} 0
|
|
|
|
testmetric1{src="fizz",src1="buzz",src2="fizzbuzz",dst="fizz, buzz, fizzbuzz"} 1
|
|
|
|
|
|
|
|
clear
|
|
|
|
|
|
|
|
# Tests for vector.
|
|
|
|
eval instant at 0m vector(1)
|
|
|
|
{} 1
|
|
|
|
|
|
|
|
eval instant at 0s vector(time())
|
|
|
|
{} 0
|
|
|
|
|
|
|
|
eval instant at 5s vector(time())
|
|
|
|
{} 5
|
|
|
|
|
|
|
|
eval instant at 60m vector(time())
|
|
|
|
{} 3600
|
|
|
|
|
|
|
|
|
|
|
|
# Tests for clamp_max, clamp_min(), and clamp().
|
|
|
|
load 5m
|
|
|
|
test_clamp{src="clamp-a"} -50
|
|
|
|
test_clamp{src="clamp-b"} 0
|
|
|
|
test_clamp{src="clamp-c"} 100
|
|
|
|
|
|
|
|
eval instant at 0m clamp_max(test_clamp, 75)
|
|
|
|
{src="clamp-a"} -50
|
|
|
|
{src="clamp-b"} 0
|
|
|
|
{src="clamp-c"} 75
|
|
|
|
|
|
|
|
eval instant at 0m clamp_min(test_clamp, -25)
|
|
|
|
{src="clamp-a"} -25
|
|
|
|
{src="clamp-b"} 0
|
|
|
|
{src="clamp-c"} 100
|
|
|
|
|
|
|
|
eval instant at 0m clamp(test_clamp, -25, 75)
|
|
|
|
{src="clamp-a"} -25
|
|
|
|
{src="clamp-b"} 0
|
|
|
|
{src="clamp-c"} 75
|
|
|
|
|
|
|
|
eval instant at 0m clamp_max(clamp_min(test_clamp, -20), 70)
|
|
|
|
{src="clamp-a"} -20
|
|
|
|
{src="clamp-b"} 0
|
|
|
|
{src="clamp-c"} 70
|
|
|
|
|
|
|
|
eval instant at 0m clamp_max((clamp_min(test_clamp, (-20))), (70))
|
|
|
|
{src="clamp-a"} -20
|
|
|
|
{src="clamp-b"} 0
|
|
|
|
{src="clamp-c"} 70
|
|
|
|
|
|
|
|
eval instant at 0m clamp(test_clamp, 0, NaN)
|
|
|
|
{src="clamp-a"} NaN
|
|
|
|
{src="clamp-b"} NaN
|
|
|
|
{src="clamp-c"} NaN
|
|
|
|
|
|
|
|
eval instant at 0m clamp(test_clamp, NaN, 0)
|
|
|
|
{src="clamp-a"} NaN
|
|
|
|
{src="clamp-b"} NaN
|
|
|
|
{src="clamp-c"} NaN
|
|
|
|
|
|
|
|
eval instant at 0m clamp(test_clamp, 5, -5)
|
|
|
|
|
|
|
|
# Test cases for sgn.
|
|
|
|
clear
|
|
|
|
load 5m
|
|
|
|
test_sgn{src="sgn-a"} -Inf
|
|
|
|
test_sgn{src="sgn-b"} Inf
|
|
|
|
test_sgn{src="sgn-c"} NaN
|
|
|
|
test_sgn{src="sgn-d"} -50
|
|
|
|
test_sgn{src="sgn-e"} 0
|
|
|
|
test_sgn{src="sgn-f"} 100
|
|
|
|
|
|
|
|
eval instant at 0m sgn(test_sgn)
|
|
|
|
{src="sgn-a"} -1
|
|
|
|
{src="sgn-b"} 1
|
|
|
|
{src="sgn-c"} NaN
|
|
|
|
{src="sgn-d"} -1
|
|
|
|
{src="sgn-e"} 0
|
|
|
|
{src="sgn-f"} 1
|
|
|
|
|
|
|
|
|
|
|
|
# Tests for sort/sort_desc.
|
|
|
|
clear
|
|
|
|
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="api-server", instance="2", group="canary"} NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
|
|
|
|
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
|
|
|
|
|
|
|
|
eval_ordered instant at 50m sort(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
|
|
|
|
http_requests{group="canary", instance="1", job="api-server"} 400
|
|
|
|
http_requests{group="production", instance="0", job="app-server"} 500
|
|
|
|
http_requests{group="production", instance="1", job="app-server"} 600
|
|
|
|
http_requests{group="canary", instance="0", job="app-server"} 700
|
|
|
|
http_requests{group="canary", instance="1", job="app-server"} 800
|
|
|
|
http_requests{group="canary", instance="2", job="api-server"} NaN
|
|
|
|
|
|
|
|
eval_ordered instant at 50m sort_desc(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
|
|
|
|
http_requests{group="production", instance="0", job="app-server"} 500
|
|
|
|
http_requests{group="canary", instance="1", job="api-server"} 400
|
|
|
|
http_requests{group="canary", instance="0", job="api-server"} 300
|
|
|
|
http_requests{group="production", instance="1", job="api-server"} 200
|
|
|
|
http_requests{group="production", instance="0", job="api-server"} 100
|
|
|
|
http_requests{group="canary", instance="2", job="api-server"} NaN
|
|
|
|
|
|
|
|
# Tests for sort_by_label/sort_by_label_desc.
|
|
|
|
clear
|
|
|
|
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="api-server", instance="2", group="canary"} NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
|
|
|
|
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
|
|
|
|
http_requests{job="api-server", instance="2", group="production"} 0+10x10
|
|
|
|
cpu_time_total{job="cpu", cpu="0"} 0+10x10
|
|
|
|
cpu_time_total{job="cpu", cpu="1"} 0+10x10
|
|
|
|
cpu_time_total{job="cpu", cpu="2"} 0+10x10
|
|
|
|
cpu_time_total{job="cpu", cpu="3"} 0+10x10
|
|
|
|
cpu_time_total{job="cpu", cpu="10"} 0+10x10
|
|
|
|
cpu_time_total{job="cpu", cpu="11"} 0+10x10
|
|
|
|
cpu_time_total{job="cpu", cpu="12"} 0+10x10
|
|
|
|
cpu_time_total{job="cpu", cpu="20"} 0+10x10
|
|
|
|
cpu_time_total{job="cpu", cpu="21"} 0+10x10
|
|
|
|
cpu_time_total{job="cpu", cpu="100"} 0+10x10
|
|
|
|
node_uname_info{job="node_exporter", instance="4m600", release="1.2.3"} 0+10x10
|
|
|
|
node_uname_info{job="node_exporter", instance="4m5", release="1.11.3"} 0+10x10
|
|
|
|
node_uname_info{job="node_exporter", instance="4m1000", release="1.111.3"} 0+10x10
|
|
|
|
|
|
|
|
eval_ordered instant at 50m sort_by_label(http_requests, "instance")
|
|
|
|
http_requests{group="production", instance="0", job="api-server"} 100
|
|
|
|
http_requests{group="canary", instance="0", job="api-server"} 300
|
|
|
|
http_requests{group="production", instance="0", job="app-server"} 500
|
|
|
|
http_requests{group="canary", instance="0", job="app-server"} 700
|
|
|
|
http_requests{group="production", instance="1", job="api-server"} 200
|
|
|
|
http_requests{group="canary", instance="1", job="api-server"} 400
|
|
|
|
http_requests{group="production", instance="1", job="app-server"} 600
|
|
|
|
http_requests{group="canary", instance="1", job="app-server"} 800
|
|
|
|
http_requests{group="production", instance="2", job="api-server"} 100
|
|
|
|
http_requests{group="canary", instance="2", job="api-server"} NaN
|
|
|
|
|
|
|
|
eval_ordered instant at 50m sort_by_label(http_requests, "instance", "group")
|
|
|
|
http_requests{group="canary", instance="0", job="api-server"} 300
|
|
|
|
http_requests{group="canary", instance="0", job="app-server"} 700
|
|
|
|
http_requests{group="production", instance="0", job="api-server"} 100
|
|
|
|
http_requests{group="production", instance="0", job="app-server"} 500
|
|
|
|
http_requests{group="canary", instance="1", job="api-server"} 400
|
|
|
|
http_requests{group="canary", instance="1", job="app-server"} 800
|
|
|
|
http_requests{group="production", instance="1", job="api-server"} 200
|
|
|
|
http_requests{group="production", instance="1", job="app-server"} 600
|
|
|
|
http_requests{group="canary", instance="2", job="api-server"} NaN
|
|
|
|
http_requests{group="production", instance="2", job="api-server"} 100
|
|
|
|
|
|
|
|
eval_ordered instant at 50m sort_by_label(http_requests, "instance", "group")
|
|
|
|
http_requests{group="canary", instance="0", job="api-server"} 300
|
|
|
|
http_requests{group="canary", instance="0", job="app-server"} 700
|
|
|
|
http_requests{group="production", instance="0", job="api-server"} 100
|
|
|
|
http_requests{group="production", instance="0", job="app-server"} 500
|
|
|
|
http_requests{group="canary", instance="1", job="api-server"} 400
|
|
|
|
http_requests{group="canary", instance="1", job="app-server"} 800
|
|
|
|
http_requests{group="production", instance="1", job="api-server"} 200
|
|
|
|
http_requests{group="production", instance="1", job="app-server"} 600
|
|
|
|
http_requests{group="canary", instance="2", job="api-server"} NaN
|
|
|
|
http_requests{group="production", instance="2", job="api-server"} 100
|
|
|
|
|
|
|
|
eval_ordered instant at 50m sort_by_label(http_requests, "group", "instance", "job")
|
|
|
|
http_requests{group="canary", instance="0", job="api-server"} 300
|
|
|
|
http_requests{group="canary", instance="0", job="app-server"} 700
|
|
|
|
http_requests{group="canary", instance="1", job="api-server"} 400
|
|
|
|
http_requests{group="canary", instance="1", job="app-server"} 800
|
|
|
|
http_requests{group="canary", instance="2", job="api-server"} NaN
|
|
|
|
http_requests{group="production", instance="0", job="api-server"} 100
|
|
|
|
http_requests{group="production", instance="0", job="app-server"} 500
|
|
|
|
http_requests{group="production", instance="1", job="api-server"} 200
|
|
|
|
http_requests{group="production", instance="1", job="app-server"} 600
|
|
|
|
http_requests{group="production", instance="2", job="api-server"} 100
|
|
|
|
|
|
|
|
eval_ordered instant at 50m sort_by_label(http_requests, "job", "instance", "group")
|
|
|
|
http_requests{group="canary", instance="0", job="api-server"} 300
|
|
|
|
http_requests{group="production", instance="0", job="api-server"} 100
|
|
|
|
http_requests{group="canary", instance="1", job="api-server"} 400
|
|
|
|
http_requests{group="production", instance="1", job="api-server"} 200
|
|
|
|
http_requests{group="canary", instance="2", job="api-server"} NaN
|
|
|
|
http_requests{group="production", instance="2", job="api-server"} 100
|
|
|
|
http_requests{group="canary", instance="0", job="app-server"} 700
|
|
|
|
http_requests{group="production", instance="0", job="app-server"} 500
|
|
|
|
http_requests{group="canary", instance="1", job="app-server"} 800
|
|
|
|
http_requests{group="production", instance="1", job="app-server"} 600
|
|
|
|
|
|
|
|
eval_ordered instant at 50m sort_by_label_desc(http_requests, "instance")
|
|
|
|
http_requests{group="production", instance="2", job="api-server"} 100
|
|
|
|
http_requests{group="canary", instance="2", job="api-server"} NaN
|
|
|
|
http_requests{group="canary", instance="1", job="app-server"} 800
|
|
|
|
http_requests{group="production", instance="1", job="app-server"} 600
|
|
|
|
http_requests{group="canary", instance="1", job="api-server"} 400
|
|
|
|
http_requests{group="production", instance="1", job="api-server"} 200
|
|
|
|
http_requests{group="canary", instance="0", job="app-server"} 700
|
|
|
|
http_requests{group="production", instance="0", job="app-server"} 500
|
|
|
|
http_requests{group="canary", instance="0", job="api-server"} 300
|
|
|
|
http_requests{group="production", instance="0", job="api-server"} 100
|
|
|
|
|
|
|
|
eval_ordered instant at 50m sort_by_label_desc(http_requests, "instance", "group")
|
|
|
|
http_requests{group="production", instance="2", job="api-server"} 100
|
|
|
|
http_requests{group="canary", instance="2", job="api-server"} NaN
|
|
|
|
http_requests{group="production", instance="1", job="app-server"} 600
|
|
|
|
http_requests{group="production", instance="1", job="api-server"} 200
|
|
|
|
http_requests{group="canary", instance="1", job="app-server"} 800
|
|
|
|
http_requests{group="canary", instance="1", job="api-server"} 400
|
|
|
|
http_requests{group="production", instance="0", job="app-server"} 500
|
|
|
|
http_requests{group="production", instance="0", job="api-server"} 100
|
|
|
|
http_requests{group="canary", instance="0", job="app-server"} 700
|
|
|
|
http_requests{group="canary", instance="0", job="api-server"} 300
|
|
|
|
|
|
|
|
eval_ordered instant at 50m sort_by_label_desc(http_requests, "instance", "group", "job")
|
|
|
|
http_requests{group="production", instance="2", job="api-server"} 100
|
|
|
|
http_requests{group="canary", instance="2", job="api-server"} NaN
|
|
|
|
http_requests{group="production", instance="1", job="app-server"} 600
|
|
|
|
http_requests{group="production", instance="1", job="api-server"} 200
|
|
|
|
http_requests{group="canary", instance="1", job="app-server"} 800
|
|
|
|
http_requests{group="canary", instance="1", job="api-server"} 400
|
|
|
|
http_requests{group="production", instance="0", job="app-server"} 500
|
|
|
|
http_requests{group="production", instance="0", job="api-server"} 100
|
|
|
|
http_requests{group="canary", instance="0", job="app-server"} 700
|
|
|
|
http_requests{group="canary", instance="0", job="api-server"} 300
|
|
|
|
|
|
|
|
eval_ordered instant at 50m sort_by_label(cpu_time_total, "cpu")
|
|
|
|
cpu_time_total{job="cpu", cpu="0"} 100
|
|
|
|
cpu_time_total{job="cpu", cpu="1"} 100
|
|
|
|
cpu_time_total{job="cpu", cpu="2"} 100
|
|
|
|
cpu_time_total{job="cpu", cpu="3"} 100
|
|
|
|
cpu_time_total{job="cpu", cpu="10"} 100
|
|
|
|
cpu_time_total{job="cpu", cpu="11"} 100
|
|
|
|
cpu_time_total{job="cpu", cpu="12"} 100
|
|
|
|
cpu_time_total{job="cpu", cpu="20"} 100
|
|
|
|
cpu_time_total{job="cpu", cpu="21"} 100
|
|
|
|
cpu_time_total{job="cpu", cpu="100"} 100
|
|
|
|
|
|
|
|
eval_ordered instant at 50m sort_by_label(node_uname_info, "instance")
|
|
|
|
node_uname_info{job="node_exporter", instance="4m5", release="1.11.3"} 100
|
|
|
|
node_uname_info{job="node_exporter", instance="4m600", release="1.2.3"} 100
|
|
|
|
node_uname_info{job="node_exporter", instance="4m1000", release="1.111.3"} 100
|
|
|
|
|
|
|
|
eval_ordered instant at 50m sort_by_label(node_uname_info, "release")
|
|
|
|
node_uname_info{job="node_exporter", instance="4m600", release="1.2.3"} 100
|
|
|
|
node_uname_info{job="node_exporter", instance="4m5", release="1.11.3"} 100
|
|
|
|
node_uname_info{job="node_exporter", instance="4m1000", release="1.111.3"} 100
|
|
|
|
|
|
|
|
# Tests for holt_winters
|
|
|
|
clear
|
|
|
|
|
|
|
|
# positive trends
|
|
|
|
load 10s
|
|
|
|
http_requests{job="api-server", instance="0", group="production"} 0+10x1000 100+30x1000
|
|
|
|
http_requests{job="api-server", instance="1", group="production"} 0+20x1000 200+30x1000
|
|
|
|
http_requests{job="api-server", instance="0", group="canary"} 0+30x1000 300+80x1000
|
|
|
|
http_requests{job="api-server", instance="1", group="canary"} 0+40x2000
|
|
|
|
|
|
|
|
eval instant at 8000s holt_winters(http_requests[1m], 0.01, 0.1)
|
|
|
|
{job="api-server", instance="0", group="production"} 8000
|
|
|
|
{job="api-server", instance="1", group="production"} 16000
|
|
|
|
{job="api-server", instance="0", group="canary"} 24000
|
|
|
|
{job="api-server", instance="1", group="canary"} 32000
|
|
|
|
|
|
|
|
# negative trends
|
|
|
|
clear
|
|
|
|
load 10s
|
|
|
|
http_requests{job="api-server", instance="0", group="production"} 8000-10x1000
|
|
|
|
http_requests{job="api-server", instance="1", group="production"} 0-20x1000
|
|
|
|
http_requests{job="api-server", instance="0", group="canary"} 0+30x1000 300-80x1000
|
|
|
|
http_requests{job="api-server", instance="1", group="canary"} 0-40x1000 0+40x1000
|
|
|
|
|
|
|
|
eval instant at 8000s holt_winters(http_requests[1m], 0.01, 0.1)
|
|
|
|
{job="api-server", instance="0", group="production"} 0
|
|
|
|
{job="api-server", instance="1", group="production"} -16000
|
|
|
|
{job="api-server", instance="0", group="canary"} 24000
|
|
|
|
{job="api-server", instance="1", group="canary"} -32000
|
|
|
|
|
|
|
|
# Tests for avg_over_time
|
|
|
|
clear
|
|
|
|
load 10s
|
|
|
|
metric 1 2 3 4 5
|
|
|
|
metric2 1 2 3 4 Inf
|
|
|
|
metric3 1 2 3 4 -Inf
|
|
|
|
metric4 1 2 3 Inf -Inf
|
|
|
|
metric5 Inf 0 Inf
|
|
|
|
metric5b Inf 0 Inf
|
|
|
|
metric5c Inf Inf Inf -Inf
|
|
|
|
metric6 1 2 3 -Inf -Inf
|
|
|
|
metric6b -Inf 0 -Inf
|
|
|
|
metric6c -Inf -Inf -Inf Inf
|
|
|
|
metric7 1 2 -Inf -Inf Inf
|
|
|
|
metric8 9.988465674311579e+307 9.988465674311579e+307
|
|
|
|
metric9 -9.988465674311579e+307 -9.988465674311579e+307 -9.988465674311579e+307
|
|
|
|
metric10 -9.988465674311579e+307 9.988465674311579e+307
|
|
|
|
|
|
|
|
eval instant at 1m avg_over_time(metric[1m])
|
|
|
|
{} 3
|
|
|
|
|
|
|
|
eval instant at 1m sum_over_time(metric[1m])/count_over_time(metric[1m])
|
|
|
|
{} 3
|
|
|
|
|
|
|
|
eval instant at 1m avg_over_time(metric2[1m])
|
|
|
|
{} Inf
|
|
|
|
|
|
|
|
eval instant at 1m sum_over_time(metric2[1m])/count_over_time(metric2[1m])
|
|
|
|
{} Inf
|
|
|
|
|
|
|
|
eval instant at 1m avg_over_time(metric3[1m])
|
|
|
|
{} -Inf
|
|
|
|
|
|
|
|
eval instant at 1m sum_over_time(metric3[1m])/count_over_time(metric3[1m])
|
|
|
|
{} -Inf
|
|
|
|
|
|
|
|
eval instant at 1m avg_over_time(metric4[1m])
|
|
|
|
{} NaN
|
|
|
|
|
|
|
|
eval instant at 1m sum_over_time(metric4[1m])/count_over_time(metric4[1m])
|
|
|
|
{} NaN
|
|
|
|
|
|
|
|
eval instant at 1m avg_over_time(metric5[1m])
|
|
|
|
{} Inf
|
|
|
|
|
|
|
|
eval instant at 1m sum_over_time(metric5[1m])/count_over_time(metric5[1m])
|
|
|
|
{} Inf
|
|
|
|
|
|
|
|
eval instant at 1m avg_over_time(metric5b[1m])
|
|
|
|
{} Inf
|
|
|
|
|
|
|
|
eval instant at 1m sum_over_time(metric5b[1m])/count_over_time(metric5b[1m])
|
|
|
|
{} Inf
|
|
|
|
|
|
|
|
eval instant at 1m avg_over_time(metric5c[1m])
|
|
|
|
{} NaN
|
|
|
|
|
|
|
|
eval instant at 1m sum_over_time(metric5c[1m])/count_over_time(metric5c[1m])
|
|
|
|
{} NaN
|
|
|
|
|
|
|
|
eval instant at 1m avg_over_time(metric6[1m])
|
|
|
|
{} -Inf
|
|
|
|
|
|
|
|
eval instant at 1m sum_over_time(metric6[1m])/count_over_time(metric6[1m])
|
|
|
|
{} -Inf
|
|
|
|
|
|
|
|
eval instant at 1m avg_over_time(metric6b[1m])
|
|
|
|
{} -Inf
|
|
|
|
|
|
|
|
eval instant at 1m sum_over_time(metric6b[1m])/count_over_time(metric6b[1m])
|
|
|
|
{} -Inf
|
|
|
|
|
|
|
|
eval instant at 1m avg_over_time(metric6c[1m])
|
|
|
|
{} NaN
|
|
|
|
|
|
|
|
eval instant at 1m sum_over_time(metric6c[1m])/count_over_time(metric6c[1m])
|
|
|
|
{} NaN
|
|
|
|
|
|
|
|
|
|
|
|
eval instant at 1m avg_over_time(metric7[1m])
|
|
|
|
{} NaN
|
|
|
|
|
|
|
|
eval instant at 1m sum_over_time(metric7[1m])/count_over_time(metric7[1m])
|
|
|
|
{} NaN
|
|
|
|
|
|
|
|
eval instant at 1m avg_over_time(metric8[1m])
|
|
|
|
{} 9.988465674311579e+307
|
|
|
|
|
|
|
|
# This overflows float64.
|
|
|
|
eval instant at 1m sum_over_time(metric8[1m])/count_over_time(metric8[1m])
|
|
|
|
{} Inf
|
|
|
|
|
|
|
|
eval instant at 1m avg_over_time(metric9[1m])
|
|
|
|
{} -9.988465674311579e+307
|
|
|
|
|
|
|
|
# This overflows float64.
|
|
|
|
eval instant at 1m sum_over_time(metric9[1m])/count_over_time(metric9[1m])
|
|
|
|
{} -Inf
|
|
|
|
|
|
|
|
eval instant at 1m avg_over_time(metric10[1m])
|
|
|
|
{} 0
|
|
|
|
|
|
|
|
eval instant at 1m sum_over_time(metric10[1m])/count_over_time(metric10[1m])
|
|
|
|
{} 0
|
|
|
|
|
|
|
|
# Tests for stddev_over_time and stdvar_over_time.
|
|
|
|
clear
|
|
|
|
load 10s
|
|
|
|
metric 0 8 8 2 3
|
|
|
|
|
|
|
|
eval instant at 1m stdvar_over_time(metric[1m])
|
|
|
|
{} 10.56
|
|
|
|
|
|
|
|
eval instant at 1m stddev_over_time(metric[1m])
|
|
|
|
{} 3.249615
|
|
|
|
|
|
|
|
eval instant at 1m stddev_over_time((metric[1m]))
|
|
|
|
{} 3.249615
|
|
|
|
|
|
|
|
# Tests for stddev_over_time and stdvar_over_time #4927.
|
|
|
|
clear
|
|
|
|
load 10s
|
|
|
|
metric 1.5990505637277868 1.5990505637277868 1.5990505637277868
|
|
|
|
|
|
|
|
eval instant at 1m stdvar_over_time(metric[1m])
|
|
|
|
{} 0
|
|
|
|
|
|
|
|
eval instant at 1m stddev_over_time(metric[1m])
|
|
|
|
{} 0
|
|
|
|
|
|
|
|
# Tests for mad_over_time.
|
|
|
|
clear
|
|
|
|
load 10s
|
|
|
|
metric 4 6 2 1 999 1 2
|
|
|
|
|
|
|
|
eval instant at 70s mad_over_time(metric[70s])
|
|
|
|
{} 1
|
|
|
|
|
|
|
|
# Tests for quantile_over_time
|
|
|
|
clear
|
|
|
|
|
|
|
|
load 10s
|
|
|
|
data{test="two samples"} 0 1
|
|
|
|
data{test="three samples"} 0 1 2
|
|
|
|
data{test="uneven samples"} 0 1 4
|
|
|
|
|
|
|
|
eval instant at 1m quantile_over_time(0, data[1m])
|
|
|
|
{test="two samples"} 0
|
|
|
|
{test="three samples"} 0
|
|
|
|
{test="uneven samples"} 0
|
|
|
|
|
|
|
|
eval instant at 1m quantile_over_time(0.5, data[1m])
|
|
|
|
{test="two samples"} 0.5
|
|
|
|
{test="three samples"} 1
|
|
|
|
{test="uneven samples"} 1
|
|
|
|
|
|
|
|
eval instant at 1m quantile_over_time(0.75, data[1m])
|
|
|
|
{test="two samples"} 0.75
|
|
|
|
{test="three samples"} 1.5
|
|
|
|
{test="uneven samples"} 2.5
|
|
|
|
|
|
|
|
eval instant at 1m quantile_over_time(0.8, data[1m])
|
|
|
|
{test="two samples"} 0.8
|
|
|
|
{test="three samples"} 1.6
|
|
|
|
{test="uneven samples"} 2.8
|
|
|
|
|
|
|
|
eval instant at 1m quantile_over_time(1, data[1m])
|
|
|
|
{test="two samples"} 1
|
|
|
|
{test="three samples"} 2
|
|
|
|
{test="uneven samples"} 4
|
|
|
|
|
|
|
|
eval instant at 1m quantile_over_time(-1, data[1m])
|
|
|
|
{test="two samples"} -Inf
|
|
|
|
{test="three samples"} -Inf
|
|
|
|
{test="uneven samples"} -Inf
|
|
|
|
|
|
|
|
eval instant at 1m quantile_over_time(2, data[1m])
|
|
|
|
{test="two samples"} +Inf
|
|
|
|
{test="three samples"} +Inf
|
|
|
|
{test="uneven samples"} +Inf
|
|
|
|
|
|
|
|
eval instant at 1m (quantile_over_time(2, (data[1m])))
|
|
|
|
{test="two samples"} +Inf
|
|
|
|
{test="three samples"} +Inf
|
|
|
|
{test="uneven samples"} +Inf
|
|
|
|
|
|
|
|
clear
|
|
|
|
|
|
|
|
# Test time-related functions.
|
|
|
|
eval instant at 0m year()
|
|
|
|
{} 1970
|
|
|
|
|
|
|
|
eval instant at 1ms time()
|
|
|
|
0.001
|
|
|
|
|
|
|
|
eval instant at 50m time()
|
|
|
|
3000
|
|
|
|
|
|
|
|
eval instant at 0m year(vector(1136239445))
|
|
|
|
{} 2006
|
|
|
|
|
|
|
|
eval instant at 0m month()
|
|
|
|
{} 1
|
|
|
|
|
|
|
|
eval instant at 0m month(vector(1136239445))
|
|
|
|
{} 1
|
|
|
|
|
|
|
|
eval instant at 0m day_of_month()
|
|
|
|
{} 1
|
|
|
|
|
|
|
|
eval instant at 0m day_of_month(vector(1136239445))
|
|
|
|
{} 2
|
|
|
|
|
|
|
|
eval instant at 0m day_of_year()
|
|
|
|
{} 1
|
|
|
|
|
|
|
|
eval instant at 0m day_of_year(vector(1136239445))
|
|
|
|
{} 2
|
|
|
|
|
|
|
|
# Thursday.
|
|
|
|
eval instant at 0m day_of_week()
|
|
|
|
{} 4
|
|
|
|
|
|
|
|
eval instant at 0m day_of_week(vector(1136239445))
|
|
|
|
{} 1
|
|
|
|
|
|
|
|
eval instant at 0m hour()
|
|
|
|
{} 0
|
|
|
|
|
|
|
|
eval instant at 0m hour(vector(1136239445))
|
|
|
|
{} 22
|
|
|
|
|
|
|
|
eval instant at 0m minute()
|
|
|
|
{} 0
|
|
|
|
|
|
|
|
eval instant at 0m minute(vector(1136239445))
|
|
|
|
{} 4
|
|
|
|
|
|
|
|
# 2008-12-31 23:59:59 just before leap second.
|
|
|
|
eval instant at 0m year(vector(1230767999))
|
|
|
|
{} 2008
|
|
|
|
|
|
|
|
# 2009-01-01 00:00:00 just after leap second.
|
|
|
|
eval instant at 0m year(vector(1230768000))
|
|
|
|
{} 2009
|
|
|
|
|
|
|
|
# 2016-02-29 23:59:59 February 29th in leap year.
|
|
|
|
eval instant at 0m month(vector(1456790399)) + day_of_month(vector(1456790399)) / 100
|
|
|
|
{} 2.29
|
|
|
|
|
|
|
|
# 2016-03-01 00:00:00 March 1st in leap year.
|
|
|
|
eval instant at 0m month(vector(1456790400)) + day_of_month(vector(1456790400)) / 100
|
|
|
|
{} 3.01
|
|
|
|
|
|
|
|
# 2016-12-31 13:37:00 366th day in leap year.
|
|
|
|
eval instant at 0m day_of_year(vector(1483191420))
|
|
|
|
{} 366
|
|
|
|
|
|
|
|
# 2022-12-31 13:37:00 365th day in non-leap year.
|
|
|
|
eval instant at 0m day_of_year(vector(1672493820))
|
|
|
|
{} 365
|
|
|
|
|
|
|
|
# February 1st 2016 in leap year.
|
|
|
|
eval instant at 0m days_in_month(vector(1454284800))
|
|
|
|
{} 29
|
|
|
|
|
|
|
|
# February 1st 2017 not in leap year.
|
|
|
|
eval instant at 0m days_in_month(vector(1485907200))
|
|
|
|
{} 28
|
|
|
|
|
|
|
|
clear
|
|
|
|
|
|
|
|
# Test duplicate labelset in promql output.
|
|
|
|
load 5m
|
|
|
|
testmetric1{src="a",dst="b"} 0
|
|
|
|
testmetric2{src="a",dst="b"} 1
|
|
|
|
|
|
|
|
eval_fail instant at 0m changes({__name__=~'testmetric1|testmetric2'}[5m])
|
|
|
|
|
|
|
|
# Tests for *_over_time
|
|
|
|
clear
|
|
|
|
|
|
|
|
load 10s
|
|
|
|
data{type="numbers"} 2 0 3
|
|
|
|
data{type="some_nan"} 2 0 NaN
|
|
|
|
data{type="some_nan2"} 2 NaN 1
|
|
|
|
data{type="some_nan3"} NaN 0 1
|
|
|
|
data{type="only_nan"} NaN NaN NaN
|
|
|
|
|
|
|
|
eval instant at 1m min_over_time(data[1m])
|
|
|
|
{type="numbers"} 0
|
|
|
|
{type="some_nan"} 0
|
|
|
|
{type="some_nan2"} 1
|
|
|
|
{type="some_nan3"} 0
|
|
|
|
{type="only_nan"} NaN
|
|
|
|
|
|
|
|
eval instant at 1m max_over_time(data[1m])
|
|
|
|
{type="numbers"} 3
|
|
|
|
{type="some_nan"} 2
|
|
|
|
{type="some_nan2"} 2
|
|
|
|
{type="some_nan3"} 1
|
|
|
|
{type="only_nan"} NaN
|
|
|
|
|
|
|
|
eval instant at 1m last_over_time(data[1m])
|
|
|
|
data{type="numbers"} 3
|
|
|
|
data{type="some_nan"} NaN
|
|
|
|
data{type="some_nan2"} 1
|
|
|
|
data{type="some_nan3"} 1
|
|
|
|
data{type="only_nan"} NaN
|
|
|
|
|
|
|
|
clear
|
|
|
|
|
|
|
|
# Test for absent()
|
|
|
|
eval instant at 50m absent(nonexistent)
|
|
|
|
{} 1
|
|
|
|
|
|
|
|
eval instant at 50m absent(nonexistent{job="testjob", instance="testinstance", method=~".x"})
|
|
|
|
{instance="testinstance", job="testjob"} 1
|
|
|
|
|
|
|
|
eval instant at 50m absent(nonexistent{job="testjob",job="testjob2",foo="bar"})
|
|
|
|
{foo="bar"} 1
|
|
|
|
|
|
|
|
eval instant at 50m absent(nonexistent{job="testjob",job="testjob2",job="three",foo="bar"})
|
|
|
|
{foo="bar"} 1
|
|
|
|
|
|
|
|
eval instant at 50m absent(nonexistent{job="testjob",job=~"testjob2",foo="bar"})
|
|
|
|
{foo="bar"} 1
|
|
|
|
|
|
|
|
clear
|
|
|
|
|
|
|
|
# Don't return anything when there's something there.
|
|
|
|
load 5m
|
|
|
|
http_requests{job="api-server", instance="0", group="production"} 0+10x10
|
|
|
|
|
|
|
|
eval instant at 50m absent(http_requests)
|
|
|
|
|
|
|
|
eval instant at 50m absent(sum(http_requests))
|
|
|
|
|
|
|
|
clear
|
|
|
|
|
|
|
|
eval instant at 50m absent(sum(nonexistent{job="testjob", instance="testinstance"}))
|
|
|
|
{} 1
|
|
|
|
|
|
|
|
eval instant at 50m absent(max(nonexistant))
|
|
|
|
{} 1
|
|
|
|
|
|
|
|
eval instant at 50m absent(nonexistant > 1)
|
|
|
|
{} 1
|
|
|
|
|
|
|
|
eval instant at 50m absent(a + b)
|
|
|
|
{} 1
|
|
|
|
|
|
|
|
eval instant at 50m absent(a and b)
|
|
|
|
{} 1
|
|
|
|
|
|
|
|
eval instant at 50m absent(rate(nonexistant[5m]))
|
|
|
|
{} 1
|
|
|
|
|
|
|
|
clear
|
|
|
|
|
|
|
|
# Testdata for absent_over_time()
|
|
|
|
eval instant at 1m absent_over_time(http_requests[5m])
|
|
|
|
{} 1
|
|
|
|
|
|
|
|
eval instant at 1m absent_over_time(http_requests{handler="/foo"}[5m])
|
|
|
|
{handler="/foo"} 1
|
|
|
|
|
|
|
|
eval instant at 1m absent_over_time(http_requests{handler!="/foo"}[5m])
|
|
|
|
{} 1
|
|
|
|
|
|
|
|
eval instant at 1m absent_over_time(http_requests{handler="/foo", handler="/bar", handler="/foobar"}[5m])
|
|
|
|
{} 1
|
|
|
|
|
|
|
|
eval instant at 1m absent_over_time(rate(nonexistant[5m])[5m:])
|
|
|
|
{} 1
|
|
|
|
|
|
|
|
eval instant at 1m absent_over_time(http_requests{handler="/foo", handler="/bar", instance="127.0.0.1"}[5m])
|
|
|
|
{instance="127.0.0.1"} 1
|
|
|
|
|
|
|
|
load 1m
|
|
|
|
http_requests{path="/foo",instance="127.0.0.1",job="httpd"} 1+1x10
|
|
|
|
http_requests{path="/bar",instance="127.0.0.1",job="httpd"} 1+1x10
|
|
|
|
httpd_handshake_failures_total{instance="127.0.0.1",job="node"} 1+1x15
|
|
|
|
httpd_log_lines_total{instance="127.0.0.1",job="node"} 1
|
|
|
|
ssl_certificate_expiry_seconds{job="ingress"} NaN NaN NaN NaN NaN
|
|
|
|
|
|
|
|
eval instant at 5m absent_over_time(http_requests[5m])
|
|
|
|
|
|
|
|
eval instant at 5m absent_over_time(rate(http_requests[5m])[5m:1m])
|
|
|
|
|
|
|
|
eval instant at 0m absent_over_time(httpd_log_lines_total[30s])
|
|
|
|
|
|
|
|
eval instant at 1m absent_over_time(httpd_log_lines_total[30s])
|
|
|
|
{} 1
|
|
|
|
|
|
|
|
eval instant at 15m absent_over_time(http_requests[5m])
|
|
|
|
|
|
|
|
eval instant at 16m absent_over_time(http_requests[5m])
|
|
|
|
{} 1
|
|
|
|
|
|
|
|
eval instant at 16m absent_over_time(http_requests[6m])
|
|
|
|
|
|
|
|
eval instant at 16m absent_over_time(httpd_handshake_failures_total[1m])
|
|
|
|
|
|
|
|
eval instant at 16m absent_over_time({instance="127.0.0.1"}[5m])
|
|
|
|
|
|
|
|
eval instant at 21m absent_over_time({instance="127.0.0.1"}[5m])
|
|
|
|
{instance="127.0.0.1"} 1
|
|
|
|
|
|
|
|
eval instant at 21m absent_over_time({instance="127.0.0.1"}[20m])
|
|
|
|
|
|
|
|
eval instant at 21m absent_over_time({job="grok"}[20m])
|
|
|
|
{job="grok"} 1
|
|
|
|
|
|
|
|
eval instant at 30m absent_over_time({instance="127.0.0.1"}[5m:5s])
|
|
|
|
{} 1
|
|
|
|
|
|
|
|
eval instant at 5m absent_over_time({job="ingress"}[4m])
|
|
|
|
|
|
|
|
eval instant at 10m absent_over_time({job="ingress"}[4m])
|
|
|
|
{job="ingress"} 1
|
|
|
|
|
|
|
|
clear
|
|
|
|
|
|
|
|
# Testdata for present_over_time()
|
|
|
|
eval instant at 1m present_over_time(http_requests[5m])
|
|
|
|
|
|
|
|
eval instant at 1m present_over_time(http_requests{handler="/foo"}[5m])
|
|
|
|
|
|
|
|
eval instant at 1m present_over_time(http_requests{handler!="/foo"}[5m])
|
|
|
|
|
|
|
|
eval instant at 1m present_over_time(http_requests{handler="/foo", handler="/bar", handler="/foobar"}[5m])
|
|
|
|
|
|
|
|
eval instant at 1m present_over_time(rate(nonexistant[5m])[5m:])
|
|
|
|
|
|
|
|
eval instant at 1m present_over_time(http_requests{handler="/foo", handler="/bar", instance="127.0.0.1"}[5m])
|
|
|
|
|
|
|
|
load 1m
|
|
|
|
http_requests{path="/foo",instance="127.0.0.1",job="httpd"} 1+1x10
|
|
|
|
http_requests{path="/bar",instance="127.0.0.1",job="httpd"} 1+1x10
|
|
|
|
httpd_handshake_failures_total{instance="127.0.0.1",job="node"} 1+1x15
|
|
|
|
httpd_log_lines_total{instance="127.0.0.1",job="node"} 1
|
|
|
|
ssl_certificate_expiry_seconds{job="ingress"} NaN NaN NaN NaN NaN
|
|
|
|
|
|
|
|
eval instant at 5m present_over_time(http_requests[5m])
|
|
|
|
{instance="127.0.0.1", job="httpd", path="/bar"} 1
|
|
|
|
{instance="127.0.0.1", job="httpd", path="/foo"} 1
|
|
|
|
|
|
|
|
eval instant at 5m present_over_time(rate(http_requests[5m])[5m:1m])
|
|
|
|
{instance="127.0.0.1", job="httpd", path="/bar"} 1
|
|
|
|
{instance="127.0.0.1", job="httpd", path="/foo"} 1
|
|
|
|
|
|
|
|
eval instant at 0m present_over_time(httpd_log_lines_total[30s])
|
|
|
|
{instance="127.0.0.1",job="node"} 1
|
|
|
|
|
|
|
|
eval instant at 1m present_over_time(httpd_log_lines_total[30s])
|
|
|
|
|
|
|
|
eval instant at 15m present_over_time(http_requests[5m])
|
|
|
|
{instance="127.0.0.1", job="httpd", path="/bar"} 1
|
|
|
|
{instance="127.0.0.1", job="httpd", path="/foo"} 1
|
|
|
|
|
|
|
|
eval instant at 16m present_over_time(http_requests[5m])
|
|
|
|
|
|
|
|
eval instant at 16m present_over_time(http_requests[6m])
|
|
|
|
{instance="127.0.0.1", job="httpd", path="/bar"} 1
|
|
|
|
{instance="127.0.0.1", job="httpd", path="/foo"} 1
|
|
|
|
|
|
|
|
eval instant at 16m present_over_time(httpd_handshake_failures_total[1m])
|
|
|
|
{instance="127.0.0.1", job="node"} 1
|
|
|
|
|
|
|
|
eval instant at 16m present_over_time({instance="127.0.0.1"}[5m])
|
|
|
|
{instance="127.0.0.1",job="node"} 1
|
|
|
|
|
|
|
|
eval instant at 21m present_over_time({job="grok"}[20m])
|
|
|
|
|
|
|
|
eval instant at 30m present_over_time({instance="127.0.0.1"}[5m:5s])
|
|
|
|
|
|
|
|
eval instant at 5m present_over_time({job="ingress"}[4m])
|
|
|
|
{job="ingress"} 1
|
|
|
|
|
|
|
|
eval instant at 10m present_over_time({job="ingress"}[4m])
|
|
|
|
|
|
|
|
clear
|
|
|
|
|
|
|
|
# Testing exp() sqrt() log2() log10() ln()
|
|
|
|
load 5m
|
|
|
|
exp_root_log{l="x"} 10
|
|
|
|
exp_root_log{l="y"} 20
|
|
|
|
|
|
|
|
eval instant at 5m exp(exp_root_log)
|
|
|
|
{l="x"} 22026.465794806718
|
|
|
|
{l="y"} 485165195.4097903
|
|
|
|
|
|
|
|
eval instant at 5m exp(exp_root_log - 10)
|
|
|
|
{l="y"} 22026.465794806718
|
|
|
|
{l="x"} 1
|
|
|
|
|
|
|
|
eval instant at 5m exp(exp_root_log - 20)
|
|
|
|
{l="x"} 4.5399929762484854e-05
|
|
|
|
{l="y"} 1
|
|
|
|
|
|
|
|
eval instant at 5m ln(exp_root_log)
|
|
|
|
{l="x"} 2.302585092994046
|
|
|
|
{l="y"} 2.995732273553991
|
|
|
|
|
|
|
|
eval instant at 5m ln(exp_root_log - 10)
|
|
|
|
{l="y"} 2.302585092994046
|
|
|
|
{l="x"} -Inf
|
|
|
|
|
|
|
|
eval instant at 5m ln(exp_root_log - 20)
|
|
|
|
{l="y"} -Inf
|
|
|
|
{l="x"} NaN
|
|
|
|
|
|
|
|
eval instant at 5m exp(ln(exp_root_log))
|
|
|
|
{l="y"} 20
|
|
|
|
{l="x"} 10
|
|
|
|
|
|
|
|
eval instant at 5m sqrt(exp_root_log)
|
|
|
|
{l="x"} 3.1622776601683795
|
|
|
|
{l="y"} 4.47213595499958
|
|
|
|
|
|
|
|
eval instant at 5m log2(exp_root_log)
|
|
|
|
{l="x"} 3.3219280948873626
|
|
|
|
{l="y"} 4.321928094887363
|
|
|
|
|
|
|
|
eval instant at 5m log2(exp_root_log - 10)
|
|
|
|
{l="y"} 3.3219280948873626
|
|
|
|
{l="x"} -Inf
|
|
|
|
|
|
|
|
eval instant at 5m log2(exp_root_log - 20)
|
|
|
|
{l="x"} NaN
|
|
|
|
{l="y"} -Inf
|
|
|
|
|
|
|
|
eval instant at 5m log10(exp_root_log)
|
|
|
|
{l="x"} 1
|
|
|
|
{l="y"} 1.301029995663981
|
|
|
|
|
|
|
|
eval instant at 5m log10(exp_root_log - 10)
|
|
|
|
{l="y"} 1
|
|
|
|
{l="x"} -Inf
|
|
|
|
|
|
|
|
eval instant at 5m log10(exp_root_log - 20)
|
|
|
|
{l="x"} NaN
|
|
|
|
{l="y"} -Inf
|
|
|
|
|
|
|
|
clear
|