Skip to content

Commit 2dbc409

Browse files
committed
Support holt_winters function
Signed-off-by: SungJin1212 <[email protected]>
1 parent 4c5e97b commit 2dbc409

File tree

9 files changed

+203
-31
lines changed

9 files changed

+203
-31
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* [FEATURE] Querier/Ruler: Add `query_partial_data` and `rules_partial_data` limits to allow queries/rules to be evaluated with data from a single zone, if other zones are not available. #6526
77
* [FEATURE] Update prometheus alertmanager version to v0.28.0 and add new integration msteamsv2, jira, and rocketchat. #6590
88
* [ENHANCEMENT] Alertmanager: Add new limits `-alertmanager.max-silences-count` and `-alertmanager.max-silences-size-bytes` for limiting silences per tenant. #6605
9+
* [ENHANCEMENT] Update prometheus version to v3.1.0. #6583
910
* [ENHANCEMENT] Add `compactor.auto-forget-delay` for compactor to auto forget compactors after X minutes without heartbeat. #6533
1011
* [ENHANCEMENT] StoreGateway: Emit more histogram buckets on the `cortex_querier_storegateway_refetches_per_query` metric. #6570
1112
* [ENHANCEMENT] Querier: Apply bytes limiter to LabelNames and LabelValuesForLabelNames. #6568

go.mod

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,9 @@ require (
247247
google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect
248248
gopkg.in/alecthomas/kingpin.v2 v2.2.6 // indirect
249249
gopkg.in/telebot.v3 v3.3.8 // indirect
250-
k8s.io/apimachinery v0.31.1 // indirect
251-
k8s.io/client-go v0.31.0 // indirect
250+
k8s.io/apimachinery v0.31.3 // indirect
251+
k8s.io/client-go v0.31.3 // indirect
252+
k8s.io/klog/v2 v2.130.1 // indirect
252253
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect
253254
)
254255

go.sum

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,8 @@ github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWH
934934
github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
935935
github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 h1:QVw89YDxXxEe+l8gU8ETbOasdwEV+avkR75ZzsVV9WI=
936936
github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
937+
github.com/coder/quartz v0.1.2 h1:PVhc9sJimTdKd3VbygXtS4826EOCpB1fXoRlLnCrE+s=
938+
github.com/coder/quartz v0.1.2/go.mod h1:vsiCc+AHViMKH2CQpGIpFgdHIEQsxwm8yCscqKmzbRA=
937939
github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
938940
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
939941
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
@@ -980,6 +982,10 @@ github.com/efficientgo/e2e v0.14.1-0.20230710114240-c316eb95ae5b h1:8VX23BNufsa4
980982
github.com/efficientgo/e2e v0.14.1-0.20230710114240-c316eb95ae5b/go.mod h1:plsKU0YHE9uX+7utvr7SiDtVBSHJyEfHRO4UnUgDmts=
981983
github.com/efficientgo/tools/extkingpin v0.0.0-20220817170617-6c25e3b627dd h1:VaYzzXeUbC5fVheskcKVNOyJMEYD+HgrJNzIAg/mRIM=
982984
github.com/efficientgo/tools/extkingpin v0.0.0-20220817170617-6c25e3b627dd/go.mod h1:ZV0utlglOczUWv3ih2AbqPSoLoFzdplUYxwV62eZi6Q=
985+
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 h1:OJyUGMJTzHTd1XQp98QTaHernxMYzRaOasRir9hUlFQ=
986+
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ=
987+
github.com/emersion/go-smtp v0.21.3 h1:7uVwagE8iPYE48WhNsng3RRpCUpFvNl39JGNSIyGVMY=
988+
github.com/emersion/go-smtp v0.21.3/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ=
983989
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
984990
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
985991
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
@@ -1334,8 +1340,8 @@ github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
13341340
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
13351341
github.com/ionos-cloud/sdk-go/v6 v6.0.4 h1:4LoWeM7WtcDqYDjlntqQ3fD6XaENlCw2YqiVWkHQbNA=
13361342
github.com/ionos-cloud/sdk-go/v6 v6.0.4/go.mod h1:UE3V/2DjnqD5doOqtjYqzJRMpI1RiwrvuuSEPX1pdnk=
1337-
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
1338-
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
1343+
github.com/jessevdk/go-flags v1.6.1 h1:Cvu5U8UGrLay1rZfv/zP7iLpSHGUZ/Ou68T0iX1bBK4=
1344+
github.com/jessevdk/go-flags v1.6.1/go.mod h1:Mk8T1hIAWpOiJiHa9rJASDK2UGWji0EuPGBnNLMooyc=
13391345
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
13401346
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
13411347
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
@@ -1541,8 +1547,8 @@ github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndr
15411547
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
15421548
github.com/prometheus-community/prom-label-proxy v0.8.1-0.20240127162815-c1195f9aabc0 h1:owfYHh79h8Y5HvNMGyww+DaVwo10CKiRW1RQrrZzIwg=
15431549
github.com/prometheus-community/prom-label-proxy v0.8.1-0.20240127162815-c1195f9aabc0/go.mod h1:rT989D4UtOcfd9tVqIZRVIM8rkg+9XbreBjFNEKXvVI=
1544-
github.com/prometheus/alertmanager v0.27.0 h1:V6nTa2J5V4s8TG4C4HtrBP/WNSebCCTYGGv4qecA/+I=
1545-
github.com/prometheus/alertmanager v0.27.0/go.mod h1:8Ia/R3urPmbzJ8OsdvmZvIprDwvwmYCmUbwBL+jlPOE=
1550+
github.com/prometheus/alertmanager v0.28.0 h1:sLN+6HhZet8hrbmGHLAHWsTXgZSVCvq9Ix3U3wvivqc=
1551+
github.com/prometheus/alertmanager v0.28.0/go.mod h1:/okSnb2LlodbMlRoOWQEKtqI/coOo2NKZDm2Hu9QHLQ=
15461552
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
15471553
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
15481554
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
@@ -1594,8 +1600,8 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE
15941600
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
15951601
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
15961602
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
1597-
github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po=
1598-
github.com/rs/cors v1.11.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
1603+
github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA=
1604+
github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
15991605
github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
16001606
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
16011607
github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w=
@@ -1614,8 +1620,8 @@ github.com/sercand/kuberesolver/v5 v5.1.1 h1:CYH+d67G0sGBj7q5wLK61yzqJJ8gLLC8aep
16141620
github.com/sercand/kuberesolver/v5 v5.1.1/go.mod h1:Fs1KbKhVRnB2aDWN12NjKCB+RgYMWZJ294T3BtmVCpQ=
16151621
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c h1:aqg5Vm5dwtvL+YgDpBcK1ITf3o96N/K7/wsRXQnUTEs=
16161622
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c/go.mod h1:owqhoLW1qZoYLZzLnBw+QkPP9WZnjlSWihhxAJC1+/M=
1617-
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 h1:pXY9qYc/MP5zdvqWEUH6SjNiu7VhSjuVFTFiTcphaLU=
1618-
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
1623+
github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92 h1:OfRzdxCzDhp+rsKWXuOO2I/quKMJ/+TQwVbIP/gltZg=
1624+
github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92/go.mod h1:7/OT02F6S6I7v6WXb+IjhMuZEYfH/RJ5RwEWnEo5BMg=
16191625
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
16201626
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
16211627
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
@@ -1672,6 +1678,8 @@ github.com/thanos-io/thanos v0.37.3-0.20250212101700-346d18bb0f80 h1:mOCRYn9SLBW
16721678
github.com/thanos-io/thanos v0.37.3-0.20250212101700-346d18bb0f80/go.mod h1:Y7D8la8B5rpzRVKq2HCR4hbYZ4LGroSPqIJjtizgQg8=
16731679
github.com/tjhop/slog-gokit v0.1.2 h1:pmQI4SvU9h4gA0vIQsdhJQSqQg4mOmsPykG2/PM3j1I=
16741680
github.com/tjhop/slog-gokit v0.1.2/go.mod h1:8fhlcp8C8ELbg3GCyKv06tgt4B5sDq2P1r2DQAu1HuM=
1681+
github.com/trivago/tgo v1.0.7 h1:uaWH/XIy9aWYWpjm2CU3RpcqZXmX2ysQ9/Go+d9gyrM=
1682+
github.com/trivago/tgo v1.0.7/go.mod h1:w4dpD+3tzNIIiIfkWWa85w5/B77tlvdZckQ+6PkFnhc=
16751683
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
16761684
github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o=
16771685
github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
@@ -2520,8 +2528,8 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
25202528
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
25212529
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
25222530
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
2523-
gopkg.in/telebot.v3 v3.2.1 h1:3I4LohaAyJBiivGmkfB+CiVu7QFOWkuZ4+KHgO/G3rs=
2524-
gopkg.in/telebot.v3 v3.2.1/go.mod h1:GJKwwWqp9nSkIVN51eRKU78aB5f5OnQuWdwiIZfPbko=
2531+
gopkg.in/telebot.v3 v3.3.8 h1:uVDGjak9l824FN9YARWUHMsiNZnlohAVwUycw21k6t8=
2532+
gopkg.in/telebot.v3 v3.3.8/go.mod h1:1mlbqcLTVSfK9dx7fdp+Nb5HZsy4LLPtpZTKmwhwtzM=
25252533
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
25262534
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
25272535
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

integration/backward_compatibility_test.go

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,21 @@ package integration
55

66
import (
77
"fmt"
8+
"path"
9+
"strconv"
810
"testing"
911
"time"
1012

1113
"github.com/prometheus/common/model"
1214
"github.com/prometheus/prometheus/model/labels"
15+
"github.com/prometheus/prometheus/prompb"
1316
"github.com/stretchr/testify/assert"
1417
"github.com/stretchr/testify/require"
1518

1619
"github.com/cortexproject/cortex/integration/e2e"
1720
e2edb "github.com/cortexproject/cortex/integration/e2e/db"
1821
"github.com/cortexproject/cortex/integration/e2ecortex"
22+
"github.com/cortexproject/cortex/pkg/storage/tsdb"
1923
)
2024

2125
type versionsImagesFlags struct {
@@ -118,6 +122,118 @@ func TestNewDistributorsCanPushToOldIngestersWithReplication(t *testing.T) {
118122
}
119123
}
120124

125+
// Test cortex which uses Prometheus v3.x can support holt_winters function
126+
func TestCanSupportHoltWintersFunc(t *testing.T) {
127+
s, err := e2e.NewScenario(networkName)
128+
require.NoError(t, err)
129+
defer s.Close()
130+
131+
// Start dependencies.
132+
consul := e2edb.NewConsulWithName("consul")
133+
require.NoError(t, s.StartAndWaitReady(consul))
134+
135+
flags := mergeFlags(
136+
AlertmanagerLocalFlags(),
137+
map[string]string{
138+
"-store.engine": blocksStorageEngine,
139+
"-blocks-storage.backend": "filesystem",
140+
"-blocks-storage.tsdb.head-compaction-interval": "4m",
141+
"-blocks-storage.tsdb.block-ranges-period": "2h",
142+
"-blocks-storage.tsdb.ship-interval": "1h",
143+
"-blocks-storage.bucket-store.sync-interval": "15m",
144+
"-blocks-storage.tsdb.retention-period": "2h",
145+
"-blocks-storage.bucket-store.index-cache.backend": tsdb.IndexCacheBackendInMemory,
146+
"-blocks-storage.bucket-store.bucket-index.enabled": "true",
147+
"-querier.query-store-for-labels-enabled": "true",
148+
// Ingester.
149+
"-ring.store": "consul",
150+
"-consul.hostname": consul.NetworkHTTPEndpoint(),
151+
// Distributor.
152+
"-distributor.replication-factor": "1",
153+
// Store-gateway.
154+
"-store-gateway.sharding-enabled": "false",
155+
// alert manager
156+
"-alertmanager.web.external-url": "http://localhost/alertmanager",
157+
// enable experimental promQL funcs
158+
"-querier.enable-promql-experimental-functions": "true",
159+
},
160+
)
161+
// make alert manager config dir
162+
require.NoError(t, writeFileToSharedDir(s, "alertmanager_configs", []byte{}))
163+
164+
path := path.Join(s.SharedDir(), "cortex-1")
165+
166+
flags = mergeFlags(flags, map[string]string{"-blocks-storage.filesystem.dir": path})
167+
// Start Cortex replicas.
168+
cortex := e2ecortex.NewSingleBinary("cortex", flags, "")
169+
require.NoError(t, s.StartAndWaitReady(cortex))
170+
171+
// Wait until Cortex replicas have updated the ring state.
172+
require.NoError(t, cortex.WaitSumMetrics(e2e.Equals(float64(512)), "cortex_ring_tokens_total"))
173+
174+
c, err := e2ecortex.NewClient(cortex.HTTPEndpoint(), cortex.HTTPEndpoint(), "", "", "user-1")
175+
require.NoError(t, err)
176+
177+
now := time.Now()
178+
// Push some series to Cortex.
179+
start := now.Add(-time.Minute * 120)
180+
end := now
181+
scrapeInterval := 30 * time.Second
182+
183+
numSeries := 10
184+
numSamples := 240
185+
serieses := make([]prompb.TimeSeries, numSeries)
186+
lbls := make([]labels.Labels, numSeries)
187+
for i := 0; i < numSeries; i++ {
188+
series := e2e.GenerateSeriesWithSamples("test_series", start, scrapeInterval, i*numSamples, numSamples, prompb.Label{Name: "job", Value: "test"}, prompb.Label{Name: "series", Value: strconv.Itoa(i)})
189+
serieses[i] = series
190+
191+
builder := labels.NewBuilder(labels.EmptyLabels())
192+
for _, lbl := range series.Labels {
193+
builder.Set(lbl.Name, lbl.Value)
194+
}
195+
lbls[i] = builder.Labels()
196+
}
197+
198+
res, err := c.Push(serieses)
199+
require.NoError(t, err)
200+
require.Equal(t, 200, res.StatusCode)
201+
202+
// Test holt_winters range query
203+
hQuery := "holt_winters(test_series[2h], 0.5, 0.5)"
204+
hRangeResult, err := c.QueryRange(hQuery, start, end, scrapeInterval)
205+
require.NoError(t, err)
206+
hMatrix, ok := hRangeResult.(model.Matrix)
207+
require.True(t, ok)
208+
require.True(t, hMatrix.Len() > 0)
209+
210+
// Test holt_winters instant query
211+
hInstantResult, err := c.Query(hQuery, now)
212+
require.NoError(t, err)
213+
hVector, ok := hInstantResult.(model.Vector)
214+
require.True(t, ok)
215+
require.True(t, hVector.Len() > 0)
216+
217+
// Test double_exponential_smoothing range query
218+
dQuery := "double_exponential_smoothing(test_series[2h], 0.5, 0.5)"
219+
dRangeResult, err := c.QueryRange(dQuery, start, end, scrapeInterval)
220+
require.NoError(t, err)
221+
dMatrix, ok := dRangeResult.(model.Matrix)
222+
require.True(t, ok)
223+
require.True(t, dMatrix.Len() > 0)
224+
225+
// Test double_exponential_smoothing instant query
226+
dInstantResult, err := c.Query(dQuery, now)
227+
require.NoError(t, err)
228+
dVector, ok := dInstantResult.(model.Vector)
229+
require.True(t, ok)
230+
require.True(t, dVector.Len() > 0)
231+
232+
// compare lengths of query results
233+
require.True(t, hMatrix.Len() == dMatrix.Len())
234+
require.True(t, hVector.Len() == dVector.Len())
235+
}
236+
121237
func blocksStorageFlagsWithFlushOnShutdown() map[string]string {
122238
return mergeFlags(BlocksStorageFlags(), map[string]string{
123239
"-blocks-storage.tsdb.flush-blocks-on-shutdown": "true",

pkg/configs/userconfig/config_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import (
1616
"github.com/prometheus/prometheus/rules"
1717
"github.com/stretchr/testify/assert"
1818
"github.com/stretchr/testify/require"
19-
"github.com/thanos-io/thanos/pkg/logutil"
2019
"gopkg.in/yaml.v3"
2120

2221
util_log "github.com/cortexproject/cortex/pkg/util/log"
@@ -96,7 +95,7 @@ func TestParseLegacyAlerts(t *testing.T) {
9695
nil,
9796
"",
9897
true,
99-
logutil.GoKitLogToSlog(log.With(util_log.Logger, "alert", "TestAlert")),
98+
util_log.GoKitLogToSlog(log.With(util_log.Logger, "alert", "TestAlert")),
10099
)
101100

102101
for i, tc := range []struct {

pkg/querier/querier.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,9 @@ func New(cfg Config, limits *validation.Overrides, distributor Distributor, stor
204204
})
205205
maxConcurrentMetric.Set(float64(cfg.MaxConcurrent))
206206

207-
// set EnableExperimentalFunctions
208-
parser.EnableExperimentalFunctions = cfg.EnablePromQLExperimentalFunctions
207+
// The holt_winters function is renamed to double_exponential_smoothing and has been experimental since Prometheus v3. (https://github.com/prometheus/prometheus/pull/14930)
208+
// The cortex supports holt_winters for users using this function.
209+
EnableExperimentalPromQLFunctions(cfg.EnablePromQLExperimentalFunctions, true)
209210

210211
var queryEngine promql.QueryEngine
211212
opts := promql.EngineOpts{
@@ -665,3 +666,15 @@ func validateQueryTimeRange(ctx context.Context, userID string, startMs, endMs i
665666

666667
return int64(startTime), int64(endTime), nil
667668
}
669+
670+
func EnableExperimentalPromQLFunctions(enablePromQLExperimentalFunctions, enableHoltWinters bool) {
671+
parser.EnableExperimentalFunctions = enablePromQLExperimentalFunctions
672+
673+
if enableHoltWinters {
674+
holtWinters := *parser.Functions["double_exponential_smoothing"]
675+
holtWinters.Experimental = false
676+
holtWinters.Name = "holt_winters"
677+
parser.Functions["holt_winters"] = &holtWinters
678+
promql.FunctionCalls["holt_winters"] = promql.FunctionCalls["double_exponential_smoothing"]
679+
}
680+
}

pkg/querier/querier_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"github.com/prometheus/common/promslog"
1818
"github.com/prometheus/prometheus/model/labels"
1919
"github.com/prometheus/prometheus/promql"
20+
"github.com/prometheus/prometheus/promql/parser"
2021
"github.com/prometheus/prometheus/scrape"
2122
"github.com/prometheus/prometheus/storage"
2223
"github.com/prometheus/prometheus/tsdb/chunkenc"
@@ -1691,6 +1692,37 @@ func TestConfig_Validate(t *testing.T) {
16911692
}
16921693
}
16931694

1695+
func Test_EnableExperimentalPromQLFunctions(t *testing.T) {
1696+
EnableExperimentalPromQLFunctions(true, true)
1697+
1698+
// holt_winters function should exist
1699+
holtWintersFunc, ok := parser.Functions["holt_winters"]
1700+
require.True(t, ok)
1701+
1702+
// double_exponential_smoothing function should exist
1703+
doubleExponentialSmoothingFunc, ok := parser.Functions["double_exponential_smoothing"]
1704+
require.True(t, ok)
1705+
1706+
// holt_winters should not experimental function.
1707+
require.False(t, holtWintersFunc.Experimental)
1708+
// holt_winters's Variadic, ReturnType, and ArgTypes are the same as the double_exponential_smoothing.
1709+
require.Equal(t, doubleExponentialSmoothingFunc.Variadic, holtWintersFunc.Variadic)
1710+
require.Equal(t, doubleExponentialSmoothingFunc.ReturnType, holtWintersFunc.ReturnType)
1711+
require.Equal(t, doubleExponentialSmoothingFunc.ArgTypes, holtWintersFunc.ArgTypes)
1712+
1713+
// double_exponential_smoothing shouldn't be changed.
1714+
require.Equal(t, "double_exponential_smoothing", doubleExponentialSmoothingFunc.Name)
1715+
require.True(t, parser.Functions["double_exponential_smoothing"].Experimental)
1716+
1717+
// holt_winters function calls should exist.
1718+
_, ok = promql.FunctionCalls["holt_winters"]
1719+
require.True(t, ok)
1720+
1721+
// double_exponential_smoothing function calls should exist.
1722+
_, ok = promql.FunctionCalls["double_exponential_smoothing"]
1723+
require.True(t, ok)
1724+
}
1725+
16941726
type mockQueryableWithFilter struct {
16951727
useQueryableCalled bool
16961728
}

pkg/querier/tripperware/roundtrip.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ import (
2727
"github.com/opentracing/opentracing-go"
2828
"github.com/prometheus/client_golang/prometheus"
2929
"github.com/prometheus/client_golang/prometheus/promauto"
30-
"github.com/prometheus/prometheus/promql/parser"
3130
"github.com/thanos-io/thanos/pkg/querysharding"
3231
"github.com/weaveworks/common/httpgrpc"
3332
"github.com/weaveworks/common/user"
3433

34+
"github.com/cortexproject/cortex/pkg/querier"
3535
"github.com/cortexproject/cortex/pkg/tenant"
3636
"github.com/cortexproject/cortex/pkg/util"
3737
util_log "github.com/cortexproject/cortex/pkg/util/log"
@@ -119,8 +119,9 @@ func NewQueryTripperware(
119119
enablePromQLExperimentalFunctions bool,
120120
) Tripperware {
121121

122-
// set EnableExperimentalFunctions
123-
parser.EnableExperimentalFunctions = enablePromQLExperimentalFunctions
122+
// The holt_winters function is renamed to double_exponential_smoothing and has been experimental since Prometheus v3. (https://github.com/prometheus/prometheus/pull/14930)
123+
// The cortex supports holt_winters for users using this function.
124+
querier.EnableExperimentalPromQLFunctions(enablePromQLExperimentalFunctions, true)
124125

125126
// Per tenant query metrics.
126127
queriesPerTenant := promauto.With(registerer).NewCounterVec(prometheus.CounterOpts{

0 commit comments

Comments
 (0)