Merge branch 'main' into release-3.0-beta.0

Conflicts:
	scrape/scrape_test.go
          Pick both changes.
This commit is contained in:
Jan Fajerski 2024-09-10 20:51:20 +02:00
commit 91608c002f
21 changed files with 423 additions and 170 deletions

View file

@ -12,13 +12,9 @@ jobs:
# Whenever the Go version is updated here, .promu.yml
# should also be updated.
image: quay.io/prometheus/golang-builder:1.23-base
env:
# Preliminary fix to make Go tests with race detector not use too much memory,
# see https://github.com/prometheus/prometheus/issues/14858.
GOMEMLIMIT: 10GiB
steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- uses: prometheus/promci@45166329da36d74895901808f1c8c97efafc7f84 # v0.3.0
- uses: prometheus/promci@468927c440349ab56c4a1aafd453b312841503c2 # v0.4.4
- uses: ./.github/promci/actions/setup_environment
with:
enable_npm: true
@ -34,7 +30,7 @@ jobs:
image: quay.io/prometheus/golang-builder:1.23-base
steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- uses: prometheus/promci@45166329da36d74895901808f1c8c97efafc7f84 # v0.3.0
- uses: prometheus/promci@468927c440349ab56c4a1aafd453b312841503c2 # v0.4.4
- uses: ./.github/promci/actions/setup_environment
- run: go test --tags=dedupelabels ./...
- run: GOARCH=386 go test ./cmd/prometheus
@ -67,7 +63,7 @@ jobs:
steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- uses: prometheus/promci@45166329da36d74895901808f1c8c97efafc7f84 # v0.3.0
- uses: prometheus/promci@468927c440349ab56c4a1aafd453b312841503c2 # v0.4.4
- uses: ./.github/promci/actions/setup_environment
with:
enable_go: false
@ -126,7 +122,7 @@ jobs:
thread: [ 0, 1, 2 ]
steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- uses: prometheus/promci@45166329da36d74895901808f1c8c97efafc7f84 # v0.3.0
- uses: prometheus/promci@468927c440349ab56c4a1aafd453b312841503c2 # v0.4.4
- uses: ./.github/promci/actions/build
with:
promu_opts: "-p linux/amd64 -p windows/amd64 -p linux/arm64 -p darwin/amd64 -p darwin/arm64 -p linux/386"
@ -151,7 +147,7 @@ jobs:
# should also be updated.
steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- uses: prometheus/promci@45166329da36d74895901808f1c8c97efafc7f84 # v0.3.0
- uses: prometheus/promci@468927c440349ab56c4a1aafd453b312841503c2 # v0.4.4
- uses: ./.github/promci/actions/build
with:
parallelism: 12
@ -213,7 +209,7 @@ jobs:
if: github.event_name == 'push' && github.event.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- uses: prometheus/promci@45166329da36d74895901808f1c8c97efafc7f84 # v0.3.0
- uses: prometheus/promci@468927c440349ab56c4a1aafd453b312841503c2 # v0.4.4
- uses: ./.github/promci/actions/publish_main
with:
docker_hub_login: ${{ secrets.docker_hub_login }}
@ -230,7 +226,7 @@ jobs:
(github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v3.'))
steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- uses: prometheus/promci@45166329da36d74895901808f1c8c97efafc7f84 # v0.3.0
- uses: prometheus/promci@468927c440349ab56c4a1aafd453b312841503c2 # v0.4.4
- uses: ./.github/promci/actions/publish_release
with:
docker_hub_login: ${{ secrets.docker_hub_login }}
@ -245,7 +241,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- uses: prometheus/promci@45166329da36d74895901808f1c8c97efafc7f84 # v0.3.0
- uses: prometheus/promci@468927c440349ab56c4a1aafd453b312841503c2 # v0.4.4
- name: Install nodejs
uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3
with:

View file

@ -19,7 +19,6 @@ George Krajcsovits (<gyorgy.krajcsovits@grafana.com> / @krajorama)
* `remote`: Callum Styan (<callumstyan@gmail.com> / @cstyan), Bartłomiej Płotka (<bwplotka@gmail.com> / @bwplotka), Tom Wilkie (tom.wilkie@gmail.com / @tomwilkie), Nicolás Pazos ( <npazosmendez@gmail.com> / @npazosmendez), Alex Greenbank ( <alex.greenbank@grafana.com> / @alexgreenbank)
* `otlptranslator`: Arve Knudsen (<arve.knudsen@gmail.com> / @aknuds1), Jesús Vázquez (<jesus.vazquez@grafana.com> / @jesusvazquez)
* `tsdb`: Ganesh Vernekar (<ganesh@grafana.com> / @codesome), Bartłomiej Płotka (<bwplotka@gmail.com> / @bwplotka), Jesús Vázquez (<jesus.vazquez@grafana.com> / @jesusvazquez)
* `agent`: Robert Fratto (<robert.fratto@grafana.com> / @rfratto)
* `web`
* `ui`: Julius Volz (<julius.volz@gmail.com> / @juliusv)
* `module`: Augustin Husson (<husson.augustin@gmail.com> @nexucis)

4
go.mod
View file

@ -64,7 +64,7 @@ require (
github.com/vultr/govultr/v2 v2.17.2
go.opentelemetry.io/collector/pdata v1.14.1
go.opentelemetry.io/collector/semconv v0.108.1
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0
go.opentelemetry.io/otel v1.29.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0
@ -81,7 +81,7 @@ require (
golang.org/x/text v0.18.0
golang.org/x/time v0.6.0
golang.org/x/tools v0.24.0
google.golang.org/api v0.196.0
google.golang.org/api v0.195.0
google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed
google.golang.org/grpc v1.66.0
google.golang.org/protobuf v1.34.2

8
go.sum
View file

@ -736,8 +736,8 @@ go.opentelemetry.io/collector/pdata v1.14.1 h1:wXZjtQA7Vy5HFqco+yA95ENyMQU5heBB1
go.opentelemetry.io/collector/pdata v1.14.1/go.mod h1:z1dTjwwtcoXxZx2/nkHysjxMeaxe9pEmYTEr4SMNIx8=
go.opentelemetry.io/collector/semconv v0.108.1 h1:Txk9tauUnamZaxS5vlf1O0uZ4VD6nioRBR0nX8L/fU4=
go.opentelemetry.io/collector/semconv v0.108.1/go.mod h1:zCJ5njhWpejR+A40kiEoeFm1xq1uzyZwMnRNX6/D82A=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg=
go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw=
go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 h1:dIIDULZJpgdiHz5tXrTgKIMLkus6jEFa7x5SOKcyR7E=
@ -1056,8 +1056,8 @@ google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.196.0 h1:k/RafYqebaIJBO3+SMnfEGtFVlvp5vSgqTUF54UN/zg=
google.golang.org/api v0.196.0/go.mod h1:g9IL21uGkYgvQ5BZg6BAtoGJQIm8r6EgaAbpNey5wBE=
google.golang.org/api v0.195.0 h1:Ude4N8FvTKnnQJHU48RFI40jOBgIrL8Zqr3/QeST6yU=
google.golang.org/api v0.195.0/go.mod h1:DOGRWuv3P8TU8Lnz7uQc4hyNqrBpMtD9ppW3wBJurgc=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=

View file

@ -131,6 +131,54 @@ func TestFloatHistogramMul(t *testing.T) {
NegativeBuckets: []float64{9, 3, 15, 18},
},
},
{
"negation",
&FloatHistogram{
ZeroThreshold: 0.01,
ZeroCount: 11,
Count: 30,
Sum: 23,
PositiveSpans: []Span{{-2, 2}, {1, 3}},
PositiveBuckets: []float64{1, 0, 3, 4, 7},
NegativeSpans: []Span{{3, 2}, {3, 2}},
NegativeBuckets: []float64{3, 1, 5, 6},
},
-1,
&FloatHistogram{
ZeroThreshold: 0.01,
ZeroCount: -11,
Count: -30,
Sum: -23,
PositiveSpans: []Span{{-2, 2}, {1, 3}},
PositiveBuckets: []float64{-1, 0, -3, -4, -7},
NegativeSpans: []Span{{3, 2}, {3, 2}},
NegativeBuckets: []float64{-3, -1, -5, -6},
},
},
{
"negative multiplier",
&FloatHistogram{
ZeroThreshold: 0.01,
ZeroCount: 11,
Count: 30,
Sum: 23,
PositiveSpans: []Span{{-2, 2}, {1, 3}},
PositiveBuckets: []float64{1, 0, 3, 4, 7},
NegativeSpans: []Span{{3, 2}, {3, 2}},
NegativeBuckets: []float64{3, 1, 5, 6},
},
-2,
&FloatHistogram{
ZeroThreshold: 0.01,
ZeroCount: -22,
Count: -60,
Sum: -46,
PositiveSpans: []Span{{-2, 2}, {1, 3}},
PositiveBuckets: []float64{-2, 0, -6, -8, -14},
NegativeSpans: []Span{{3, 2}, {3, 2}},
NegativeBuckets: []float64{-6, -2, -10, -12},
},
},
{
"no-op with custom buckets",
&FloatHistogram{
@ -409,6 +457,54 @@ func TestFloatHistogramDiv(t *testing.T) {
NegativeBuckets: []float64{1.5, 0.5, 2.5, 3},
},
},
{
"negation",
&FloatHistogram{
ZeroThreshold: 0.01,
ZeroCount: 5.5,
Count: 3493.3,
Sum: 2349209.324,
PositiveSpans: []Span{{-2, 1}, {2, 3}},
PositiveBuckets: []float64{1, 3.3, 4.2, 0.1},
NegativeSpans: []Span{{3, 2}, {3, 2}},
NegativeBuckets: []float64{3.1, 3, 1.234e5, 1000},
},
-1,
&FloatHistogram{
ZeroThreshold: 0.01,
ZeroCount: -5.5,
Count: -3493.3,
Sum: -2349209.324,
PositiveSpans: []Span{{-2, 1}, {2, 3}},
PositiveBuckets: []float64{-1, -3.3, -4.2, -0.1},
NegativeSpans: []Span{{3, 2}, {3, 2}},
NegativeBuckets: []float64{-3.1, -3, -1.234e5, -1000},
},
},
{
"negative half",
&FloatHistogram{
ZeroThreshold: 0.01,
ZeroCount: 11,
Count: 30,
Sum: 23,
PositiveSpans: []Span{{-2, 2}, {1, 3}},
PositiveBuckets: []float64{1, 0, 3, 4, 7},
NegativeSpans: []Span{{3, 2}, {3, 2}},
NegativeBuckets: []float64{3, 1, 5, 6},
},
-2,
&FloatHistogram{
ZeroThreshold: 0.01,
ZeroCount: -5.5,
Count: -15,
Sum: -11.5,
PositiveSpans: []Span{{-2, 2}, {1, 3}},
PositiveBuckets: []float64{-0.5, 0, -1.5, -2, -3.5},
NegativeSpans: []Span{{3, 2}, {3, 2}},
NegativeBuckets: []float64{-1.5, -0.5, -2.5, -3},
},
},
{
"no-op with custom buckets",
&FloatHistogram{

View file

@ -1821,6 +1821,9 @@ func (ev *evaluator) eval(ctx context.Context, expr parser.Expr) (parser.Value,
for j := range mat[i].Floats {
mat[i].Floats[j].F = -mat[i].Floats[j].F
}
for j := range mat[i].Histograms {
mat[i].Histograms[j].H = mat[i].Histograms[j].H.Copy().Mul(-1)
}
}
if !ev.enableDelayedNameRemoval && mat.ContainsSameLabelset() {
ev.errorf("vector cannot contain metrics with the same labelset")

View file

@ -818,12 +818,12 @@ histogram_desc_item
$$ = yylex.(*parser).newMap()
$$["sum"] = $3
}
| COUNT_DESC COLON number
| COUNT_DESC COLON signed_or_unsigned_number
{
$$ = yylex.(*parser).newMap()
$$["count"] = $3
}
| ZERO_BUCKET_DESC COLON number
| ZERO_BUCKET_DESC COLON signed_or_unsigned_number
{
$$ = yylex.(*parser).newMap()
$$["z_bucket"] = $3
@ -875,11 +875,11 @@ bucket_set : LEFT_BRACKET bucket_set_list SPACE RIGHT_BRACKET
}
;
bucket_set_list : bucket_set_list SPACE number
bucket_set_list : bucket_set_list SPACE signed_or_unsigned_number
{
$$ = append($1, $3)
}
| number
| signed_or_unsigned_number
{
$$ = []float64{$1}
}

View file

@ -410,55 +410,55 @@ const yyPrivate = 57344
const yyLast = 799
var yyAct = [...]int16{
155, 334, 332, 276, 339, 152, 226, 39, 192, 44,
291, 290, 156, 118, 82, 178, 229, 107, 106, 346,
347, 348, 349, 109, 108, 198, 239, 199, 133, 110,
105, 60, 245, 121, 6, 329, 325, 111, 328, 228,
200, 201, 160, 119, 304, 267, 293, 128, 260, 160,
151, 261, 159, 302, 358, 311, 122, 55, 89, 159,
196, 241, 242, 259, 113, 243, 114, 54, 98, 99,
302, 112, 101, 256, 104, 88, 230, 232, 234, 235,
152, 334, 332, 155, 339, 226, 39, 192, 276, 44,
291, 290, 118, 82, 178, 229, 107, 106, 346, 347,
348, 349, 109, 108, 198, 239, 199, 156, 110, 105,
6, 245, 200, 201, 133, 325, 111, 329, 228, 60,
357, 293, 328, 304, 267, 160, 266, 128, 55, 151,
302, 311, 302, 196, 340, 159, 55, 89, 54, 356,
241, 242, 355, 113, 243, 114, 54, 98, 99, 265,
112, 101, 256, 104, 88, 230, 232, 234, 235, 236,
244, 246, 249, 250, 251, 252, 253, 257, 258, 105,
333, 231, 233, 237, 238, 240, 247, 248, 103, 115,
109, 254, 255, 324, 150, 218, 110, 264, 111, 270,
77, 35, 7, 149, 188, 163, 322, 321, 173, 320,
167, 170, 323, 165, 271, 166, 2, 3, 4, 5,
263, 101, 194, 104, 180, 184, 197, 187, 186, 319,
272, 202, 203, 204, 205, 206, 207, 208, 209, 210,
211, 212, 213, 214, 215, 216, 195, 299, 103, 318,
217, 36, 298, 1, 190, 219, 220, 317, 160, 160,
316, 193, 160, 154, 182, 196, 229, 297, 159, 159,
160, 358, 159, 268, 181, 183, 239, 260, 296, 262,
159, 315, 245, 129, 314, 55, 225, 313, 161, 228,
161, 161, 259, 312, 161, 54, 86, 295, 310, 288,
289, 8, 161, 292, 162, 37, 162, 162, 49, 269,
162, 241, 242, 309, 179, 243, 180, 127, 162, 126,
308, 223, 294, 256, 48, 222, 230, 232, 234, 235,
236, 244, 246, 249, 250, 251, 252, 253, 257, 258,
160, 115, 231, 233, 237, 238, 240, 247, 248, 103,
159, 109, 254, 255, 324, 150, 357, 110, 333, 218,
111, 340, 310, 149, 77, 163, 7, 105, 35, 173,
167, 170, 161, 323, 165, 356, 166, 309, 355, 194,
2, 3, 4, 5, 308, 322, 184, 197, 162, 186,
321, 195, 202, 203, 204, 205, 206, 207, 208, 209,
210, 211, 212, 213, 214, 215, 216, 229, 129, 101,
217, 104, 219, 220, 190, 266, 270, 239, 160, 121,
268, 193, 264, 245, 55, 196, 154, 225, 159, 119,
228, 271, 188, 160, 54, 161, 103, 117, 265, 84,
262, 299, 122, 159, 320, 263, 298, 272, 10, 83,
161, 162, 241, 242, 269, 187, 243, 185, 79, 288,
289, 297, 319, 292, 256, 161, 162, 230, 232, 234,
235, 236, 244, 246, 249, 250, 251, 252, 253, 257,
258, 162, 294, 231, 233, 237, 238, 240, 247, 248,
318, 317, 316, 254, 255, 180, 315, 134, 135, 136,
137, 138, 139, 140, 141, 142, 143, 144, 145, 146,
147, 148, 157, 158, 169, 105, 314, 296, 300, 301,
303, 223, 305, 313, 55, 222, 179, 168, 180, 84,
306, 307, 177, 125, 54, 182, 295, 176, 124, 83,
221, 312, 87, 89, 8, 181, 183, 81, 37, 86,
175, 123, 36, 98, 99, 326, 327, 101, 102, 104,
88, 127, 331, 126, 50, 336, 337, 338, 182, 335,
78, 1, 342, 341, 344, 343, 49, 48, 181, 183,
350, 351, 47, 55, 103, 352, 53, 77, 164, 56,
46, 354, 22, 54, 59, 55, 172, 9, 9, 57,
132, 45, 43, 130, 171, 54, 359, 42, 131, 41,
40, 51, 191, 353, 273, 75, 85, 189, 224, 80,
345, 18, 19, 120, 153, 20, 58, 227, 52, 116,
221, 169, 231, 233, 237, 238, 240, 247, 248, 157,
158, 164, 254, 255, 168, 10, 182, 300, 55, 301,
303, 47, 305, 46, 132, 79, 181, 183, 54, 306,
307, 45, 134, 135, 136, 137, 138, 139, 140, 141,
142, 143, 144, 145, 146, 147, 148, 43, 59, 50,
84, 9, 9, 121, 326, 78, 327, 130, 171, 121,
83, 42, 131, 119, 335, 336, 337, 331, 185, 119,
338, 261, 342, 341, 344, 343, 122, 117, 41, 177,
350, 351, 122, 55, 176, 352, 53, 77, 40, 56,
125, 354, 22, 54, 84, 124, 172, 175, 51, 57,
191, 353, 273, 85, 83, 189, 359, 224, 123, 80,
345, 120, 81, 153, 58, 75, 227, 52, 116, 0,
0, 18, 19, 0, 0, 20, 0, 0, 0, 0,
0, 76, 0, 0, 0, 0, 61, 62, 63, 64,
65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
0, 0, 0, 13, 0, 0, 0, 24, 0, 30,
0, 0, 31, 32, 55, 38, 0, 53, 77, 0,
0, 0, 31, 32, 55, 38, 105, 53, 77, 0,
56, 275, 0, 22, 54, 0, 0, 0, 274, 0,
57, 0, 278, 279, 277, 284, 286, 283, 285, 280,
281, 282, 287, 0, 0, 0, 75, 0, 0, 0,
0, 0, 18, 19, 0, 0, 20, 0, 0, 0,
0, 0, 76, 0, 0, 0, 0, 61, 62, 63,
281, 282, 287, 87, 89, 0, 75, 0, 0, 0,
0, 0, 18, 19, 98, 99, 20, 0, 101, 102,
104, 88, 76, 0, 0, 0, 0, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
74, 0, 0, 0, 13, 0, 0, 0, 24, 0,
74, 0, 0, 0, 13, 103, 0, 0, 24, 0,
30, 0, 55, 31, 32, 53, 77, 0, 56, 330,
0, 22, 54, 0, 0, 0, 0, 0, 57, 0,
278, 279, 277, 284, 286, 283, 285, 280, 281, 282,
@ -493,51 +493,51 @@ var yyAct = [...]int16{
}
var yyPact = [...]int16{
32, 106, 569, 569, 405, 526, -1000, -1000, -1000, 105,
28, 102, 569, 569, 405, 526, -1000, -1000, -1000, 98,
-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-1000, -1000, -1000, -1000, -1000, 277, -1000, 297, -1000, 650,
-1000, -1000, -1000, -1000, -1000, 342, -1000, 204, -1000, 650,
-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-1000, -1000, 22, 95, -1000, -1000, 483, -1000, 483, 101,
-1000, -1000, 21, 93, -1000, -1000, 483, -1000, 483, 97,
-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-1000, -1000, -1000, -1000, -1000, -1000, -1000, 167, -1000, -1000,
281, -1000, -1000, 309, -1000, 23, -1000, -50, -50, -50,
-50, -50, -50, -50, -50, -50, -50, -50, -50, -50,
-50, -50, -50, 48, 174, 336, 95, -56, -1000, 262,
262, 324, -1000, 631, 103, -1000, 280, -1000, -1000, 274,
241, -1000, -1000, -1000, 187, -1000, 180, -1000, 159, 483,
-1000, -57, -40, -1000, 483, 483, 483, 483, 483, 483,
-1000, -1000, -1000, -1000, -1000, -1000, -1000, 307, -1000, -1000,
338, -1000, -1000, 225, -1000, 23, -1000, -44, -44, -44,
-44, -44, -44, -44, -44, -44, -44, -44, -44, -44,
-44, -44, -44, 47, 171, 259, 93, -57, -1000, 249,
249, 324, -1000, 631, 75, -1000, 327, -1000, -1000, 222,
130, -1000, -1000, -1000, 298, -1000, 112, -1000, 159, 483,
-1000, -58, -48, -1000, 483, 483, 483, 483, 483, 483,
483, 483, 483, 483, 483, 483, 483, 483, 483, -1000,
165, -1000, -1000, 94, -1000, -1000, -1000, -1000, -1000, -1000,
-1000, 40, 40, 269, -1000, -1000, -1000, -1000, 155, -1000,
-1000, 41, -1000, 650, -1000, -1000, 31, -1000, 170, -1000,
-1000, -1000, -1000, -1000, 163, -1000, -1000, -1000, -1000, -1000,
19, 144, 140, -1000, -1000, -1000, 404, 16, 262, 262,
262, 262, 103, 103, 251, 251, 251, 715, 696, 251,
251, 715, 103, 103, 251, 103, 16, -1000, 24, -1000,
-1000, -1000, 265, -1000, 189, -1000, -1000, -1000, -1000, -1000,
39, -1000, -1000, 90, -1000, -1000, -1000, -1000, -1000, -1000,
-1000, 36, 36, 229, -1000, -1000, -1000, -1000, 174, -1000,
-1000, 180, -1000, 650, -1000, -1000, 301, -1000, 105, -1000,
-1000, -1000, -1000, -1000, 44, -1000, -1000, -1000, -1000, -1000,
18, 157, 83, -1000, -1000, -1000, 404, 15, 249, 249,
249, 249, 75, 75, 402, 402, 402, 715, 696, 402,
402, 715, 75, 75, 402, 75, 15, -1000, 19, -1000,
-1000, -1000, 186, -1000, 155, -1000, -1000, -1000, -1000, -1000,
-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
483, -1000, -1000, -1000, -1000, -1000, -1000, 34, 34, 18,
34, 44, 44, 110, 38, -1000, -1000, 285, 267, 260,
240, 236, 235, 234, 206, 188, 134, 129, -1000, -1000,
-1000, -1000, -1000, -1000, 102, -1000, -1000, -1000, 14, -1000,
650, -1000, -1000, -1000, 34, -1000, 12, 9, 482, -1000,
-1000, -1000, 51, 81, 40, 40, 40, 97, 97, 51,
97, 51, -73, -1000, -1000, -1000, -1000, -1000, 34, 34,
-1000, -1000, -1000, 34, -1000, -1000, -1000, -1000, -1000, -1000,
40, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-1000, -1000, -1000, 104, -1000, 33, -1000, -1000, -1000, -1000,
483, -1000, -1000, -1000, -1000, -1000, -1000, 31, 31, 17,
31, 37, 37, 206, 34, -1000, -1000, 197, 191, 188,
185, 164, 161, 153, 133, 113, 111, 110, -1000, -1000,
-1000, -1000, -1000, -1000, 101, -1000, -1000, -1000, 13, -1000,
650, -1000, -1000, -1000, 31, -1000, 16, 11, 482, -1000,
-1000, -1000, 33, 163, 163, 163, 36, 40, 40, 33,
40, 33, -74, -1000, -1000, -1000, -1000, -1000, 31, 31,
-1000, -1000, -1000, 31, -1000, -1000, -1000, -1000, -1000, -1000,
163, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-1000, -1000, -1000, 38, -1000, 160, -1000, -1000, -1000, -1000,
}
var yyPgo = [...]int16{
0, 379, 13, 378, 6, 15, 377, 344, 376, 374,
373, 370, 198, 294, 369, 14, 368, 10, 11, 367,
366, 8, 364, 3, 4, 363, 2, 1, 0, 362,
12, 5, 361, 360, 18, 158, 359, 358, 7, 357,
354, 17, 353, 31, 352, 9, 351, 350, 340, 332,
327, 326, 314, 321, 302,
0, 368, 12, 367, 5, 14, 366, 298, 364, 363,
361, 360, 265, 211, 359, 13, 357, 10, 11, 355,
353, 7, 352, 8, 4, 351, 2, 1, 3, 350,
27, 0, 348, 338, 17, 193, 328, 312, 6, 311,
308, 16, 307, 39, 297, 9, 281, 274, 273, 271,
234, 218, 299, 163, 161,
}
var yyR1 = [...]int8{
@ -630,9 +630,9 @@ var yyChk = [...]int16{
-38, -27, 19, -27, 26, -27, -21, -21, 24, 17,
2, 17, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 21, 2, 22, -4, -27, 26, 26,
17, -23, -26, 57, -27, -31, -28, -28, -28, -24,
17, -23, -26, 57, -27, -31, -31, -31, -28, -24,
14, -24, -26, -24, -26, -11, 92, 93, 94, 95,
-27, -27, -27, -25, -28, 24, 21, 2, 21, -28,
-27, -27, -27, -25, -31, 24, 21, 2, 21, -31,
}
var yyDef = [...]int16{

View file

@ -610,6 +610,9 @@ func lexBuckets(l *Lexer) stateFn {
case isSpace(r):
l.emit(SPACE)
return lexSpace
case r == '-':
l.emit(SUB)
return lexNumber
case isDigit(r):
l.backup()
return lexNumber

View file

@ -4084,17 +4084,17 @@ func TestParseHistogramSeries(t *testing.T) {
},
{
name: "all properties used",
input: `{} {{schema:1 sum:-0.3 count:3.1 z_bucket:7.1 z_bucket_w:0.05 buckets:[5.1 10 7] offset:-3 n_buckets:[4.1 5] n_offset:-5 counter_reset_hint:gauge}}`,
input: `{} {{schema:1 sum:0.3 count:3.1 z_bucket:7.1 z_bucket_w:0.05 buckets:[5.1 10 7] offset:3 n_buckets:[4.1 5] n_offset:5 counter_reset_hint:gauge}}`,
expected: []histogram.FloatHistogram{{
Schema: 1,
Sum: -0.3,
Sum: 0.3,
Count: 3.1,
ZeroCount: 7.1,
ZeroThreshold: 0.05,
PositiveBuckets: []float64{5.1, 10, 7},
PositiveSpans: []histogram.Span{{Offset: -3, Length: 3}},
PositiveSpans: []histogram.Span{{Offset: 3, Length: 3}},
NegativeBuckets: []float64{4.1, 5},
NegativeSpans: []histogram.Span{{Offset: -5, Length: 2}},
NegativeSpans: []histogram.Span{{Offset: 5, Length: 2}},
CounterResetHint: histogram.GaugeType,
}},
},
@ -4114,6 +4114,22 @@ func TestParseHistogramSeries(t *testing.T) {
CounterResetHint: histogram.GaugeType,
}},
},
{
name: "all properties used, with negative values where supported",
input: `{} {{schema:1 sum:-0.3 count:-3.1 z_bucket:-7.1 z_bucket_w:0.05 buckets:[-5.1 -10 -7] offset:-3 n_buckets:[-4.1 -5] n_offset:-5 counter_reset_hint:gauge}}`,
expected: []histogram.FloatHistogram{{
Schema: 1,
Sum: -0.3,
Count: -3.1,
ZeroCount: -7.1,
ZeroThreshold: 0.05,
PositiveBuckets: []float64{-5.1, -10, -7},
PositiveSpans: []histogram.Span{{Offset: -3, Length: 3}},
NegativeBuckets: []float64{-4.1, -5},
NegativeSpans: []histogram.Span{{Offset: -5, Length: 2}},
CounterResetHint: histogram.GaugeType,
}},
},
{
name: "static series",
input: `{} {{buckets:[5 10 7] schema:1}}x2`,

View file

@ -752,27 +752,39 @@ eval instant at 10m histogram_sum(scalar(histogram_fraction(-Inf, +Inf, sum(hist
# Apply multiplication and division operator to histogram.
load 10m
histogram_mul_div {{schema:0 count:21 sum:33 z_bucket:3 z_bucket_w:0.001 buckets:[3 3 3] n_buckets:[3 3 3]}}x1
histogram_mul_div {{schema:0 count:30 sum:33 z_bucket:3 z_bucket_w:0.001 buckets:[3 3 3] n_buckets:[6 6 6]}}x1
float_series_3 3+0x1
float_series_0 0+0x1
eval instant at 10m histogram_mul_div*3
{} {{schema:0 count:63 sum:99 z_bucket:9 z_bucket_w:0.001 buckets:[9 9 9] n_buckets:[9 9 9]}}
{} {{schema:0 count:90 sum:99 z_bucket:9 z_bucket_w:0.001 buckets:[9 9 9] n_buckets:[18 18 18]}}
eval instant at 10m histogram_mul_div*-1
{} {{schema:0 count:-30 sum:-33 z_bucket:-3 z_bucket_w:0.001 buckets:[-3 -3 -3] n_buckets:[-6 -6 -6]}}
eval instant at 10m -histogram_mul_div
{} {{schema:0 count:-30 sum:-33 z_bucket:-3 z_bucket_w:0.001 buckets:[-3 -3 -3] n_buckets:[-6 -6 -6]}}
eval instant at 10m histogram_mul_div*-3
{} {{schema:0 count:-90 sum:-99 z_bucket:-9 z_bucket_w:0.001 buckets:[-9 -9 -9] n_buckets:[-18 -18 -18]}}
eval instant at 10m 3*histogram_mul_div
{} {{schema:0 count:63 sum:99 z_bucket:9 z_bucket_w:0.001 buckets:[9 9 9] n_buckets:[9 9 9]}}
{} {{schema:0 count:90 sum:99 z_bucket:9 z_bucket_w:0.001 buckets:[9 9 9] n_buckets:[18 18 18]}}
eval instant at 10m histogram_mul_div*float_series_3
{} {{schema:0 count:63 sum:99 z_bucket:9 z_bucket_w:0.001 buckets:[9 9 9] n_buckets:[9 9 9]}}
{} {{schema:0 count:90 sum:99 z_bucket:9 z_bucket_w:0.001 buckets:[9 9 9] n_buckets:[18 18 18]}}
eval instant at 10m float_series_3*histogram_mul_div
{} {{schema:0 count:63 sum:99 z_bucket:9 z_bucket_w:0.001 buckets:[9 9 9] n_buckets:[9 9 9]}}
{} {{schema:0 count:90 sum:99 z_bucket:9 z_bucket_w:0.001 buckets:[9 9 9] n_buckets:[18 18 18]}}
eval instant at 10m histogram_mul_div/3
{} {{schema:0 count:7 sum:11 z_bucket:1 z_bucket_w:0.001 buckets:[1 1 1] n_buckets:[1 1 1]}}
{} {{schema:0 count:10 sum:11 z_bucket:1 z_bucket_w:0.001 buckets:[1 1 1] n_buckets:[2 2 2]}}
eval instant at 10m histogram_mul_div/-3
{} {{schema:0 count:-10 sum:-11 z_bucket:-1 z_bucket_w:0.001 buckets:[-1 -1 -1] n_buckets:[-2 -2 -2]}}
eval instant at 10m histogram_mul_div/float_series_3
{} {{schema:0 count:7 sum:11 z_bucket:1 z_bucket_w:0.001 buckets:[1 1 1] n_buckets:[1 1 1]}}
{} {{schema:0 count:10 sum:11 z_bucket:1 z_bucket_w:0.001 buckets:[1 1 1] n_buckets:[2 2 2]}}
eval instant at 10m histogram_mul_div*0
{} {{schema:0 count:0 sum:0 z_bucket:0 z_bucket_w:0.001 buckets:[0 0 0] n_buckets:[0 0 0]}}

View file

@ -524,6 +524,7 @@ func (sp *scrapePool) sync(targets []*Target) {
interval: interval,
timeout: timeout,
scrapeClassicHistograms: scrapeClassicHistograms,
validationScheme: validationScheme,
})
if err != nil {
l.setForcedError(err)

View file

@ -34,6 +34,7 @@ import (
"github.com/go-kit/log"
"github.com/gogo/protobuf/proto"
"github.com/google/go-cmp/cmp"
"github.com/grafana/regexp"
"github.com/prometheus/client_golang/prometheus"
prom_testutil "github.com/prometheus/client_golang/prometheus/testutil"
dto "github.com/prometheus/client_model/go"
@ -2380,8 +2381,11 @@ func TestTargetScraperScrapeOK(t *testing.T) {
expectedTimeout = "1.5"
)
var protobufParsing bool
var allowUTF8 bool
var (
protobufParsing bool
allowUTF8 bool
qValuePattern = regexp.MustCompile(`q=([0-9]+(\.\d+)?)`)
)
server := httptest.NewServer(
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@ -2394,6 +2398,17 @@ func TestTargetScraperScrapeOK(t *testing.T) {
"Expected Accept header to prefer application/vnd.google.protobuf.")
}
contentTypes := strings.Split(accept, ",")
for _, ct := range contentTypes {
match := qValuePattern.FindStringSubmatch(ct)
require.Len(t, match, 3)
qValue, err := strconv.ParseFloat(match[1], 64)
require.NoError(t, err, "Error parsing q value")
require.GreaterOrEqual(t, qValue, float64(0))
require.LessOrEqual(t, qValue, float64(1))
require.LessOrEqual(t, len(strings.Split(match[1], ".")[1]), 3, "q value should have at most 3 decimal places")
}
timeout := r.Header.Get("X-Prometheus-Scrape-Timeout-Seconds")
require.Equal(t, expectedTimeout, timeout, "Expected scrape timeout header.")
@ -3115,18 +3130,7 @@ func TestScrapeReportLimit(t *testing.T) {
ScrapeTimeout: model.Duration(100 * time.Millisecond),
}
var (
scrapes int
scrapedTwice = make(chan bool)
)
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "metric_a 44\nmetric_b 44\nmetric_c 44\nmetric_d 44\n")
scrapes++
if scrapes == 2 {
close(scrapedTwice)
}
}))
ts, scrapedTwice := newScrapableServer("metric_a 44\nmetric_b 44\nmetric_c 44\nmetric_d 44\n")
defer ts.Close()
sp, err := newScrapePool(cfg, s, 0, nil, nil, &Options{}, newTestScrapeMetrics(t))
@ -3169,6 +3173,52 @@ func TestScrapeReportLimit(t *testing.T) {
require.True(t, found)
}
func TestScrapeUTF8(t *testing.T) {
s := teststorage.New(t)
defer s.Close()
model.NameValidationScheme = model.UTF8Validation
t.Cleanup(func() { model.NameValidationScheme = model.LegacyValidation })
cfg := &config.ScrapeConfig{
JobName: "test",
Scheme: "http",
ScrapeInterval: model.Duration(100 * time.Millisecond),
ScrapeTimeout: model.Duration(100 * time.Millisecond),
MetricNameValidationScheme: config.UTF8ValidationConfig,
}
ts, scrapedTwice := newScrapableServer("{\"with.dots\"} 42\n")
defer ts.Close()
sp, err := newScrapePool(cfg, s, 0, nil, nil, &Options{}, newTestScrapeMetrics(t))
require.NoError(t, err)
defer sp.stop()
testURL, err := url.Parse(ts.URL)
require.NoError(t, err)
sp.Sync([]*targetgroup.Group{
{
Targets: []model.LabelSet{{model.AddressLabel: model.LabelValue(testURL.Host)}},
},
})
select {
case <-time.After(5 * time.Second):
t.Fatalf("target was not scraped twice")
case <-scrapedTwice:
// If the target has been scraped twice, report samples from the first
// scrape have been inserted in the database.
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
q, err := s.Querier(time.Time{}.UnixNano(), time.Now().UnixNano())
require.NoError(t, err)
defer q.Close()
series := q.Select(ctx, false, nil, labels.MustNewMatcher(labels.MatchRegexp, "__name__", "with.dots"))
require.True(t, series.Next(), "series not found in tsdb")
}
func TestScrapeLoopLabelLimit(t *testing.T) {
tests := []struct {
title string
@ -3365,16 +3415,7 @@ test_summary_count 199
// The expected "quantile" values do not have the trailing ".0".
expectedQuantileValues := []string{"0.5", "0.9", "0.95", "0.99", "1"}
scrapeCount := 0
scraped := make(chan bool)
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, metricsText)
scrapeCount++
if scrapeCount > 2 {
close(scraped)
}
}))
ts, scrapedTwice := newScrapableServer(metricsText)
defer ts.Close()
sp, err := newScrapePool(config, simpleStorage, 0, nil, nil, &Options{}, newTestScrapeMetrics(t))
@ -3393,7 +3434,7 @@ test_summary_count 199
select {
case <-time.After(5 * time.Second):
t.Fatalf("target was not scraped")
case <-scraped:
case <-scrapedTwice:
}
ctx, cancel := context.WithCancel(context.Background())
@ -4001,3 +4042,16 @@ func TestTargetScrapeConfigWithLabels(t *testing.T) {
})
}
}
func newScrapableServer(scrapeText string) (s *httptest.Server, scrapedTwice chan bool) {
var scrapes int
scrapedTwice = make(chan bool)
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, scrapeText)
scrapes++
if scrapes == 2 {
close(scrapedTwice)
}
})), scrapedTwice
}

View file

@ -7,19 +7,21 @@
<!--
Placeholders replaced by Prometheus during serving:
- GLOBAL_CONSOLES_LINK is replaced and set to the consoles link if it exists.
- CONSOLES_LINK_PLACEHOLDER is replaced and set to the consoles link if it exists.
It will render a "Consoles" link in the navbar when it is non-empty.
- PROMETHEUS_AGENT_MODE is replaced by a boolean indicating if Prometheus is running in agent mode.
- AGENT_MODE_PLACEHOLDER is replaced by a boolean indicating if Prometheus is running in agent mode.
It true, it will disable querying capacities in the UI and generally adapt the UI to the agent mode.
It has to be represented as a string, because booleans can be mangled to !1 in production builds.
- PROMETHEUS_READY is replaced by a boolean indicating whether Prometheus was ready at the time the
- READY_PLACEHOLDER is replaced by a boolean indicating whether Prometheus was ready at the time the
web app was served. It has to be represented as a string, because booleans can be mangled to !1 in
production builds.
- LOOKBACKDELTA_PLACEHOLDER is replaced by the default lookback delta duration used for queries.
-->
<script>
const GLOBAL_CONSOLES_LINK='CONSOLES_LINK_PLACEHOLDER';
const GLOBAL_AGENT_MODE='AGENT_MODE_PLACEHOLDER';
const GLOBAL_READY='READY_PLACEHOLDER';
const GLOBAL_LOOKBACKDELTA='LOOKBACKDELTA_PLACEHOLDER';
</script>
<!--

View file

@ -6,6 +6,7 @@ import classes from "./App.module.css";
import PrometheusLogo from "./images/prometheus-logo.svg";
import {
ActionIcon,
AppShell,
Box,
Burger,
@ -22,6 +23,7 @@ import { useDisclosure } from "@mantine/hooks";
import {
IconBell,
IconBellFilled,
IconBook,
IconChevronDown,
IconChevronRight,
IconCloudDataConnection,
@ -109,13 +111,6 @@ const monitoringStatusPages = [
element: <ServiceDiscoveryPage />,
inAgentMode: true,
},
{
title: "Alertmanager discovery",
path: "/discovered-alertmanagers",
icon: <IconBell style={navIconStyle} />,
element: <AlertmanagerDiscoveryPage />,
inAgentMode: false,
},
];
const serverStatusPages = [
@ -147,6 +142,13 @@ const serverStatusPages = [
element: <ConfigPage />,
inAgentMode: true,
},
{
title: "Alertmanager discovery",
path: "/alertmanager-discovery",
icon: <IconBell style={navIconStyle} />,
element: <AlertmanagerDiscoveryPage />,
inAgentMode: false,
},
];
const allStatusPages = [...monitoringStatusPages, ...serverStatusPages];
@ -306,17 +308,24 @@ function App() {
))}
</Menu.Dropdown>
</Menu>
</>
);
{/* <Button
const navActionIcons = (
<>
<ThemeSelector />
<SettingsMenu />
<ActionIcon
component="a"
href="https://prometheus.io/docs/prometheus/latest/getting_started/"
className={classes.link}
leftSection={<IconHelp style={navIconStyle} />}
target="_blank"
px={navLinkXPadding}
color="gray"
title="Documentation"
aria-label="Documentation"
size={32}
>
Help
</Button> */}
<IconBook size={20} />
</ActionIcon>
</>
);
@ -359,9 +368,8 @@ function App() {
{navLinks}
</Group>
</Group>
<Group visibleFrom="xs" wrap="nowrap">
<ThemeSelector />
<SettingsMenu />
<Group visibleFrom="xs" wrap="nowrap" gap="xs">
{navActionIcons}
</Group>
</Group>
<Burger
@ -377,8 +385,7 @@ function App() {
<AppShell.Navbar py="md" px={4} bg="rgb(65, 73, 81)" c="#fff">
{navLinks}
<Group mt="md" hiddenFrom="xs" justify="center">
<ThemeSelector />
<SettingsMenu />
{navActionIcons}
</Group>
</AppShell.Navbar>

View file

@ -18,7 +18,12 @@ const SettingsMenu: FC = () => {
return (
<Popover position="bottom" withArrow shadow="md">
<Popover.Target>
<ActionIcon color="gray" aria-label="Settings" size={32}>
<ActionIcon
color="gray"
title="Settings"
aria-label="Settings"
size={32}
>
<IconSettings size={20} />
</ActionIcon>
</Popover.Target>

View file

@ -45,9 +45,37 @@ const describeAggregationType = (
</>
);
case "bottomk":
return "returns the bottom K series by value";
if (param === null || param.type !== "numberLiteral") {
return (
<>
returns the bottom{" "}
<span className="promql-code promql-number">K</span> series by value
</>
);
}
return (
<>
returns the bottom{" "}
<span className="promql-code promql-number">{param.val}</span> series
by value
</>
);
case "topk":
return "returns the top K series by value";
if (param === null || param.type !== "numberLiteral") {
return (
<>
returns the top <span className="promql-code promql-number">K</span>{" "}
series by value
</>
);
}
return (
<>
returns the top{" "}
<span className="promql-code promql-number">{param.val}</span> series
by value
</>
);
case "quantile":
if (param === null) {
throw new Error(
@ -62,9 +90,31 @@ const describeAggregationType = (
return "calculates a quantile over the sample values of the input series";
case "limitk":
return "limits the output to K series";
if (param === null || param.type !== "numberLiteral") {
return (
<>
limits the output to{" "}
<span className="promql-code promql-number">K</span> series
</>
);
}
return (
<>
limits the output to{" "}
<span className="promql-code promql-number">{param.val}</span> series
</>
);
case "limit_ratio":
return "limits the output to a ratio of the input series";
if (param === null || param.type !== "numberLiteral") {
return "limits the output to a ratio of the input series";
}
return (
<>
limits the output to a ratio of{" "}
<span className="promql-code promql-number">{param.val}</span> (
{parsePrometheusFloat(param.val) * 100}%) of the input series
</>
);
default:
throw new Error(`invalid aggregation type ${aggrType}`);
}

View file

@ -11,6 +11,7 @@ import { useSuspenseAPIQuery } from "../../../api/api";
import { Card, Text, Divider, List } from "@mantine/core";
import { MetadataResult } from "../../../api/responseTypes/metadata";
import { formatPrometheusDuration } from "../../../lib/formatTime";
import { useSettings } from "../../../state/settingsSlice";
interface SelectorExplainViewProps {
node: VectorSelector | MatrixSelector;
@ -126,6 +127,7 @@ const matchingCriteriaList = (
const SelectorExplainView: FC<SelectorExplainViewProps> = ({ node }) => {
const baseMetricName = node.name.replace(/(_count|_sum|_bucket)$/, "");
const { lookbackDelta } = useSettings();
const { data: metricMeta } = useSuspenseAPIQuery<MetadataResult>({
path: `/metadata`,
params: {
@ -159,7 +161,7 @@ const SelectorExplainView: FC<SelectorExplainViewProps> = ({ node }) => {
{node.type === nodeType.vectorSelector ? (
<>
This node selects the latest (non-stale) sample value within the
last <span className="promql-code promql-duration">5m</span>
last <span className="promql-code promql-duration">{lookbackDelta}</span>
</>
) : (
<>
@ -208,7 +210,7 @@ const SelectorExplainView: FC<SelectorExplainViewProps> = ({ node }) => {
If a series has no values in the last{" "}
<span className="promql-code promql-duration">
{node.type === nodeType.vectorSelector
? "5m"
? lookbackDelta
: formatPrometheusDuration(node.range)}
</span>
{node.offset > 0 && (

View file

@ -4,6 +4,7 @@ import { initializeFromLocalStorage } from "./initializeFromLocalStorage";
interface Settings {
consolesLink: string | null;
lookbackDelta: string,
agentMode: boolean;
ready: boolean;
pathPrefix: string;
@ -19,6 +20,7 @@ interface Settings {
declare const GLOBAL_CONSOLES_LINK: string;
declare const GLOBAL_AGENT_MODE: string;
declare const GLOBAL_READY: string;
declare const GLOBAL_LOOKBACKDELTA: string;
export const localStorageKeyUseLocalTime = "settings.useLocalTime";
export const localStorageKeyEnableQueryHistory = "settings.enableQueryHistory";
@ -37,6 +39,11 @@ export const initialState: Settings = {
: GLOBAL_CONSOLES_LINK,
agentMode: GLOBAL_AGENT_MODE === "true",
ready: GLOBAL_READY === "true",
lookbackDelta:
GLOBAL_LOOKBACKDELTA === "LOOKBACKDELTA_PLACEHOLDER" ||
GLOBAL_LOOKBACKDELTA === null
? ""
: GLOBAL_LOOKBACKDELTA,
pathPrefix: "",
useLocalTime: initializeFromLocalStorage<boolean>(
localStorageKeyUseLocalTime,

View file

@ -2971,11 +2971,10 @@
"license": "MIT"
},
"node_modules/@types/node": {
"version": "22.5.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.2.tgz",
"integrity": "sha512-acJsPTEqYqulZS/Yp/S3GgeE6GZ0qYODUR8aVr/DkhHQ8l9nd4j5x1/ZJy9/gHrRlFMqkO6i0I3E27Alu4jjPg==",
"version": "22.5.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz",
"integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==",
"dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~6.19.2"
}

View file

@ -444,6 +444,7 @@ func New(logger log.Logger, o *Options) *Handler {
replacedIdx = bytes.ReplaceAll(replacedIdx, []byte("TITLE_PLACEHOLDER"), []byte(h.options.PageTitle))
replacedIdx = bytes.ReplaceAll(replacedIdx, []byte("AGENT_MODE_PLACEHOLDER"), []byte(strconv.FormatBool(h.options.IsAgent)))
replacedIdx = bytes.ReplaceAll(replacedIdx, []byte("READY_PLACEHOLDER"), []byte(strconv.FormatBool(h.isReady())))
replacedIdx = bytes.ReplaceAll(replacedIdx, []byte("LOOKBACKDELTA_PLACEHOLDER"), []byte(model.Duration(h.options.LookbackDelta).String()))
w.Write(replacedIdx)
}