From e6d69fdc1c6f254c4b1e46f955f5eaf54788bee7 Mon Sep 17 00:00:00 2001 From: Kyrre Havik Date: Wed, 21 Jan 2026 11:03:09 +0100 Subject: [PATCH 01/10] feat: bytter til Mimir service for Prometheus Co-authored-by: Carl Hedgren --- internal/thirdparty/promclient/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/thirdparty/promclient/client.go b/internal/thirdparty/promclient/client.go index ea1745fd1..1127a977f 100644 --- a/internal/thirdparty/promclient/client.go +++ b/internal/thirdparty/promclient/client.go @@ -51,7 +51,7 @@ func New(clusters []string, tenant string, log logrus.FieldLogger) (*RealClient, proms := map[string]promv1.API{} for _, cluster := range clusters { - client, err := api.NewClient(api.Config{Address: fmt.Sprintf("https://prometheus.%s.%s.cloud.nais.io", cluster, tenant)}) + client, err := api.NewClient(api.Config{Address: fmt.Sprintf("http://mimir-query-frontend", cluster, tenant)}) if err != nil { return nil, err } From 354fdb88d7156d6b490892dba05755850c778942 Mon Sep 17 00:00:00 2001 From: Kyrre Havik Date: Wed, 21 Jan 2026 12:00:40 +0100 Subject: [PATCH 02/10] fix: bruker strengen direkte --- internal/thirdparty/promclient/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/thirdparty/promclient/client.go b/internal/thirdparty/promclient/client.go index 1127a977f..2d4091364 100644 --- a/internal/thirdparty/promclient/client.go +++ b/internal/thirdparty/promclient/client.go @@ -51,7 +51,7 @@ func New(clusters []string, tenant string, log logrus.FieldLogger) (*RealClient, proms := map[string]promv1.API{} for _, cluster := range clusters { - client, err := api.NewClient(api.Config{Address: fmt.Sprintf("http://mimir-query-frontend", cluster, tenant)}) + client, err := api.NewClient(api.Config{Address: "http://mimir-query-frontend"}) if err != nil { return nil, err } From 57e37b9000245f7c24419955a8529701fe0cd583 Mon Sep 17 00:00:00 2001 From: carl hedgren Date: Wed, 21 Jan 2026 12:58:46 +0100 Subject: [PATCH 03/10] add more clients eventually we can :hohco: the old one Co-authored-by: Kyrre Havik --- internal/thirdparty/promclient/client.go | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/internal/thirdparty/promclient/client.go b/internal/thirdparty/promclient/client.go index 2d4091364..e687b9a84 100644 --- a/internal/thirdparty/promclient/client.go +++ b/internal/thirdparty/promclient/client.go @@ -10,6 +10,7 @@ import ( "github.com/prometheus/client_golang/api" promv1 "github.com/prometheus/client_golang/api/prometheus/v1" prom "github.com/prometheus/common/model" + "github.com/prometheus/prometheus/rules" "github.com/sirupsen/logrus" "github.com/sourcegraph/conc/pool" ) @@ -44,14 +45,16 @@ func WithTime(t time.Time) QueryOption { type RealClient struct { prometheuses map[string]promv1.API + mimirMetrics promv1.API + mimirAlerts promv1.API log logrus.FieldLogger } func New(clusters []string, tenant string, log logrus.FieldLogger) (*RealClient, error) { proms := map[string]promv1.API{} - for _, cluster := range clusters { - client, err := api.NewClient(api.Config{Address: "http://mimir-query-frontend"}) + client, err := api.NewClient(api.Config{Address: fmt.Sprintf("https://prometheus.%s.%s.cloud.nais.io", cluster, tenant)}) + if err != nil { return nil, err } @@ -59,8 +62,20 @@ func New(clusters []string, tenant string, log logrus.FieldLogger) (*RealClient, proms[cluster] = promv1.NewAPI(client) } + mimirMetrics, err := api.NewClient(api.Config{Address: "http://mimir-query-frontend"}) + if err != nil { + return nil, err + } + + mimirAlerts, err := api.NewClient(api.Config{Address: "http://mimir-ruler"}) + if err != nil { + return nil, err + } + return &RealClient{ prometheuses: proms, + mimirMetrics: promv1.NewAPI(mimirMetrics), + mimirAlerts: promv1.NewAPI(mimirAlerts), log: log, }, nil } From 0e659c9324d57f849b65078573c34341ee700e5f Mon Sep 17 00:00:00 2001 From: carl hedgren Date: Wed, 21 Jan 2026 13:11:10 +0100 Subject: [PATCH 04/10] update queries Co-authored-by: Kyrre Havik --- internal/utilization/model.go | 8 ++--- internal/utilization/queries.go | 56 ++++++++++++++++----------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/internal/utilization/model.go b/internal/utilization/model.go index 65a39d2e9..b562f219c 100644 --- a/internal/utilization/model.go +++ b/internal/utilization/model.go @@ -133,7 +133,7 @@ type WorkloadUtilizationRecommendations struct { } func (w WorkloadUtilizationRecommendations) CPURequestCores(ctx context.Context) (float64, error) { - v, err := w.client.Query(ctx, w.environmentName, fmt.Sprintf(cpuRequestRecommendation, w.workloadName, w.teamSlug, w.start.Hour(), w.start.Add(time.Hour*12).Hour())) + v, err := w.client.Query(ctx, w.environmentName, fmt.Sprintf(cpuRequestRecommendation, w.environmentName, w.teamSlug, w.workloadName, w.start.Hour(), w.start.Add(time.Hour*12).Hour())) if err != nil { return 0, err } @@ -143,8 +143,8 @@ func (w WorkloadUtilizationRecommendations) CPURequestCores(ctx context.Context) return math.Max(cpuReq, minCPURequest), nil } -func (w WorkloadUtilizationRecommendations) MemoryRequestBytes(ctx context.Context) (int64, error) { - v, err := w.client.Query(ctx, w.environmentName, fmt.Sprintf(memoryRequestRecommendation, w.workloadName, w.teamSlug, w.start.Hour(), w.start.Add(time.Hour*12).Hour())) +func (w WorkloadUtilizationRecommendations) MemoryRequestBytes(ctx context.Context, env string) (int64, error) { + v, err := w.client.Query(ctx, w.environmentName, fmt.Sprintf(memoryRequestRecommendation, w.environmentName, w.teamSlug, w.workloadName, w.start.Hour(), w.start.Add(time.Hour*12).Hour())) if err != nil { return 0, err } @@ -154,7 +154,7 @@ func (w WorkloadUtilizationRecommendations) MemoryRequestBytes(ctx context.Conte } func (w WorkloadUtilizationRecommendations) MemoryLimitBytes(ctx context.Context) (int64, error) { - v, err := w.client.Query(ctx, w.environmentName, fmt.Sprintf(memoryLimitRecommendation, w.workloadName, w.teamSlug, w.start.Hour(), w.start.Add(time.Hour*12).Hour())) + v, err := w.client.Query(ctx, w.environmentName, fmt.Sprintf(memoryLimitRecommendation, w.environmentName, w.teamSlug, w.workloadName, w.start.Hour(), w.start.Add(time.Hour*12).Hour())) if err != nil { return 0, err } diff --git a/internal/utilization/queries.go b/internal/utilization/queries.go index 26814c457..1f7b3f28a 100644 --- a/internal/utilization/queries.go +++ b/internal/utilization/queries.go @@ -17,35 +17,35 @@ import ( ) const ( - appCPULimit = `max by (container, namespace) (kube_pod_container_resource_limits{namespace=%q, container=%q, resource="cpu", unit="core"})` - appCPURequest = `max by (container, namespace) (kube_pod_container_resource_requests{namespace=%q, container=%q, resource="cpu",unit="core"})` - appCPUUsage = `rate(container_cpu_usage_seconds_total{namespace=%q, container=%q}[5m])` - appCPUUsageAvg = `avg by (container, namespace) (rate(container_cpu_usage_seconds_total{namespace=%q, container=%q}[5m]))` - appMemoryLimit = `max by (container, namespace) (kube_pod_container_resource_limits{namespace=%q, container=%q, resource="memory", unit="byte"})` - appMemoryRequest = `max by (container, namespace) (kube_pod_container_resource_requests{namespace=%q, container=%q, resource="memory",unit="byte"})` - appMemoryUsage = `last_over_time(container_memory_working_set_bytes{namespace=%q, container=%q}[5m])` - appMemoryUsageAvg = `avg by (container, namespace) (last_over_time(container_memory_working_set_bytes{namespace=%q, container=%q}[5m]))` - instanceCPUUsage = `rate(container_cpu_usage_seconds_total{namespace=%q, container=%q, pod=%q}[5m])` - instanceMemoryUsage = `last_over_time(container_memory_working_set_bytes{namespace=%q, container=%q, pod=%q}[5m])` - teamCPURequest = `sum by (container, owner_kind) (kube_pod_container_resource_requests{namespace=%q, container!~%q, resource="cpu",unit="core"} * on(pod,namespace) group_left(owner_kind) kube_pod_owner{owner_kind="ReplicaSet"})` - teamCPUUsage = `sum by (container, owner_kind) (rate(container_cpu_usage_seconds_total{namespace=%q, container!~%q}[5m]) * on(pod,namespace) group_left(owner_kind) kube_pod_owner{owner_kind="ReplicaSet"} )` - teamMemoryRequest = `sum by (container, owner_kind) (kube_pod_container_resource_requests{namespace=%q, container!~%q, resource="memory",unit="byte"} * on(pod,namespace) group_left(owner_kind) kube_pod_owner{owner_kind="ReplicaSet"})` - teamMemoryUsage = `sum by (container, owner_kind) (container_memory_working_set_bytes{namespace=%q, container!~%q} * on(pod,namespace) group_left(owner_kind) kube_pod_owner{owner_kind="ReplicaSet"})` - teamsCPURequest = `sum by (namespace, owner_kind) (kube_pod_container_resource_requests{namespace!~%q, container!~%q, resource="cpu",unit="core"} * on(pod,namespace) group_left(owner_kind) kube_pod_owner{owner_kind="ReplicaSet"})` - teamsCPUUsage = `sum by (namespace, owner_kind) (rate(container_cpu_usage_seconds_total{namespace!~%q, container!~%q}[5m]) * on(pod,namespace) group_left(owner_kind) kube_pod_owner{owner_kind="ReplicaSet"})` - teamsMemoryRequest = `sum by (namespace, owner_kind) (kube_pod_container_resource_requests{namespace!~%q, container!~%q, resource="memory",unit="byte"} * on(pod,namespace) group_left(owner_kind) kube_pod_owner{owner_kind="ReplicaSet"})` - teamsMemoryUsage = `sum by (namespace, owner_kind) (container_memory_working_set_bytes{namespace!~%q, container!~%q} * on(pod,namespace) group_left(owner_kind) kube_pod_owner{owner_kind="ReplicaSet"})` + appCPULimit = `max by (container, namespace) (kube_pod_container_resource_limits{k8s_cluster_name=%q,namespace=%q, container=%q, resource="cpu", unit="core"})` + appCPURequest = `max by (container, namespace) (kube_pod_container_resource_requests{k8s_cluster_name=%q, namespace=%q, container=%q, resource="cpu",unit="core"})` + appCPUUsage = `rate(container_cpu_usage_seconds_total{k8s_cluster_name=%q, namespace=%q, container=%q}[5m])` + appCPUUsageAvg = `avg by (container, namespace) (rate(container_cpu_usage_seconds_total{k8s_cluster_name=%q, namespace=%q, container=%q}[5m]))` + appMemoryLimit = `max by (container, namespace) (kube_pod_container_resource_limits{k8s_cluster_name=%q, namespace=%q, container=%q, resource="memory", unit="byte"})` + appMemoryRequest = `max by (container, namespace) (kube_pod_container_resource_requests{k8s_cluster_name=%q, namespace=%q, container=%q, resource="memory",unit="byte"})` + appMemoryUsage = `last_over_time(container_memory_working_set_bytes{k8s_cluster_name=%q, namespace=%q, container=%q}[5m])` + appMemoryUsageAvg = `avg by (container, namespace) (last_over_time(container_memory_working_set_bytes{k8s_cluster_name=%q, namespace=%q, container=%q}[5m]))` + instanceCPUUsage = `rate(container_cpu_usage_seconds_total{k8s_cluster_name=%q, namespace=%q, container=%q, pod=%q}[5m])` + instanceMemoryUsage = `last_over_time(container_memory_working_set_bytes{k8s_cluster_name=%q, namespace=%q, container=%q, pod=%q}[5m])` + teamCPURequest = `sum by (container, owner_kind) (kube_pod_container_resource_requests{k8s_cluster_name=%q, namespace=%q, container!~%q, resource="cpu",unit="core"} * on(pod,namespace) group_left(owner_kind) kube_pod_owner{owner_kind="ReplicaSet"})` + teamCPUUsage = `sum by (container, owner_kind) (rate(container_cpu_usage_seconds_total{k8s_cluster_name=%q, namespace=%q, container!~%q}[5m]) * on(pod,namespace) group_left(owner_kind) kube_pod_owner{owner_kind="ReplicaSet"} )` + teamMemoryRequest = `sum by (container, owner_kind) (kube_pod_container_resource_requests{k8s_cluster_name=%q, namespace=%q, container!~%q, resource="memory",unit="byte"} * on(pod,namespace) group_left(owner_kind) kube_pod_owner{owner_kind="ReplicaSet"})` + teamMemoryUsage = `sum by (container, owner_kind) (container_memory_working_set_bytes{k8s_cluster_name=%q, namespace=%q, container!~%q} * on(pod,namespace) group_left(owner_kind) kube_pod_owner{owner_kind="ReplicaSet"})` + teamsCPURequest = `sum by (namespace, owner_kind) (kube_pod_container_resource_requests{k8s_cluster_name=%q, namespace!~%q, container!~%q, resource="cpu",unit="core"} * on(pod,namespace) group_left(owner_kind) kube_pod_owner{owner_kind="ReplicaSet"})` + teamsCPUUsage = `sum by (namespace, owner_kind) (rate(container_cpu_usage_seconds_total{k8s_cluster_name=%q, namespace!~%q, container!~%q}[5m]) * on(pod,namespace) group_left(owner_kind) kube_pod_owner{owner_kind="ReplicaSet"})` + teamsMemoryRequest = `sum by (namespace, owner_kind) (kube_pod_container_resource_requests{k8s_cluster_name=%q, namespace!~%q, container!~%q, resource="memory",unit="byte"} * on(pod,namespace) group_left(owner_kind) kube_pod_owner{owner_kind="ReplicaSet"})` + teamsMemoryUsage = `sum by (namespace, owner_kind) (container_memory_working_set_bytes{k8s_cluster_name=%q, namespace!~%q, container!~%q} * on(pod,namespace) group_left(owner_kind) kube_pod_owner{owner_kind="ReplicaSet"})` cpuRequestRecommendation = `max( avg_over_time( - rate(container_cpu_usage_seconds_total{container=%q,namespace=%q}[5m])[1w:5m] + rate(container_cpu_usage_seconds_total{k8s_cluster_name=%q,namespace=%q, container=%q}[5m])[1w:5m] ) and on () (hour() >= %d and hour() < %d and day_of_week() > 0 and day_of_week() < 6) )` memoryRequestRecommendation = `max( avg_over_time( - quantile_over_time(0.8, container_memory_working_set_bytes{container=%q,namespace=%q}[5m])[1w:5m] + quantile_over_time(0.8, container_memory_working_set_bytes{k8s_cluster_name=%q,namespace=%q,container=%q}[5m])[1w:5m] ) and on () time() >= (hour() >= %d and hour() < %d and day_of_week() > 0 and day_of_week() < 6) @@ -54,7 +54,7 @@ const ( max_over_time( quantile_over_time( 0.95, - container_memory_working_set_bytes{container=%q,namespace=%q}[5m] + container_memory_working_set_bytes{k8s_cluster_name=%q,namespace=%q, container=%q}[5m] )[1w:5m] ) and on () @@ -204,7 +204,7 @@ func WorkloadResourceRequest(ctx context.Context, env string, teamSlug slug.Slug c := fromContext(ctx).client - v, err := c.Query(ctx, env, fmt.Sprintf(q, teamSlug, workloadName)) + v, err := c.Query(ctx, env, fmt.Sprintf(q, env, teamSlug, workloadName)) if err != nil { return 0, err } @@ -219,7 +219,7 @@ func WorkloadResourceLimit(ctx context.Context, env string, teamSlug slug.Slug, c := fromContext(ctx).client - v, err := c.Query(ctx, env, fmt.Sprintf(q, teamSlug, workloadName)) + v, err := c.Query(ctx, env, fmt.Sprintf(q, env, teamSlug, workloadName)) if err != nil { return nil, err } @@ -239,7 +239,7 @@ func WorkloadResourceUsage(ctx context.Context, env string, teamSlug slug.Slug, c := fromContext(ctx).client - v, err := c.Query(ctx, env, fmt.Sprintf(q, teamSlug, workloadName)) + v, err := c.Query(ctx, env, fmt.Sprintf(q, env, teamSlug, workloadName)) if err != nil { return 0, err } @@ -247,20 +247,20 @@ func WorkloadResourceUsage(ctx context.Context, env string, teamSlug slug.Slug, return ensuredVal(v), nil } -func queryPrometheusRange(ctx context.Context, environmentName string, teamSlug slug.Slug, workloadName string, queryTemplate string, start time.Time, end time.Time, step int) ([]*UtilizationSample, error) { +func queryPrometheusRange(ctx context.Context, env string, teamSlug slug.Slug, workloadName string, queryTemplate string, start time.Time, end time.Time, step int) ([]*UtilizationSample, error) { c := fromContext(ctx).client // Format the query - query := fmt.Sprintf(queryTemplate, teamSlug, workloadName) + query := fmt.Sprintf(queryTemplate, env, teamSlug, workloadName) // Perform the query - v, warnings, err := c.QueryRange(ctx, environmentName, query, promv1.Range{Start: start, End: end, Step: time.Duration(step) * time.Second}) + v, warnings, err := c.QueryRange(ctx, env, query, promv1.Range{Start: start, End: end, Step: time.Duration(step) * time.Second}) if err != nil { return nil, err } if len(warnings) > 0 { fromContext(ctx).log.WithFields(logrus.Fields{ - "environment": environmentName, + "environment": env, "warnings": strings.Join(warnings, ", "), }).Warn("prometheus query warnings") } From 52350d4bb446a1f06ab9234208b6b8d1bebd37b6 Mon Sep 17 00:00:00 2001 From: carl hedgren Date: Wed, 21 Jan 2026 13:36:51 +0100 Subject: [PATCH 05/10] queries are now over mimirs Co-authored-by: Kyrre Havik --- internal/thirdparty/promclient/client.go | 40 ++++++------------------ 1 file changed, 9 insertions(+), 31 deletions(-) diff --git a/internal/thirdparty/promclient/client.go b/internal/thirdparty/promclient/client.go index e687b9a84..3f7de1d50 100644 --- a/internal/thirdparty/promclient/client.go +++ b/internal/thirdparty/promclient/client.go @@ -44,24 +44,12 @@ func WithTime(t time.Time) QueryOption { } type RealClient struct { - prometheuses map[string]promv1.API mimirMetrics promv1.API - mimirAlerts promv1.API + mimirRules promv1.API log logrus.FieldLogger } -func New(clusters []string, tenant string, log logrus.FieldLogger) (*RealClient, error) { - proms := map[string]promv1.API{} - for _, cluster := range clusters { - client, err := api.NewClient(api.Config{Address: fmt.Sprintf("https://prometheus.%s.%s.cloud.nais.io", cluster, tenant)}) - - if err != nil { - return nil, err - } - - proms[cluster] = promv1.NewAPI(client) - } - +func New(tenant string, log logrus.FieldLogger) (*RealClient, error) { mimirMetrics, err := api.NewClient(api.Config{Address: "http://mimir-query-frontend"}) if err != nil { return nil, err @@ -73,9 +61,8 @@ func New(clusters []string, tenant string, log logrus.FieldLogger) (*RealClient, } return &RealClient{ - prometheuses: proms, mimirMetrics: promv1.NewAPI(mimirMetrics), - mimirAlerts: promv1.NewAPI(mimirAlerts), + mimirRules: promv1.NewAPI(mimirAlerts), log: log, }, nil } @@ -87,7 +74,7 @@ func (c *RealClient) QueryAll(ctx context.Context, query string, opts ...QueryOp } wg := pool.NewWithResults[*result]().WithContext(ctx) - for env := range c.prometheuses { + for _, env := range []string{"dev"} { wg.Go(func(ctx context.Context) (*result, error) { v, err := c.Query(ctx, env, query, opts...) if err != nil { @@ -112,10 +99,7 @@ func (c *RealClient) QueryAll(ctx context.Context, query string, opts ...QueryOp } func (c *RealClient) Query(ctx context.Context, environmentName string, query string, opts ...QueryOption) (prom.Vector, error) { - client, ok := c.prometheuses[environmentName] - if !ok { - return nil, fmt.Errorf("no prometheus client for environment %s", environmentName) - } + client := c.mimirMetrics opt := &QueryOpts{ Time: time.Now().Add(-5 * time.Minute), @@ -145,19 +129,13 @@ func (c *RealClient) Query(ctx context.Context, environmentName string, query st } func (c *RealClient) QueryRange(ctx context.Context, environment string, query string, promRange promv1.Range) (prom.Value, promv1.Warnings, error) { - client, ok := c.prometheuses[environment] - if !ok { - return nil, nil, fmt.Errorf("no prometheus client for environment %s", environment) - } - + client := c.mimirMetrics return client.QueryRange(ctx, query, promRange) } func (c *RealClient) Rules(ctx context.Context, environment string, teamSlug slug.Slug) (promv1.RulesResult, error) { - api, ok := c.prometheuses[environment] - if !ok { - return promv1.RulesResult{}, fmt.Errorf("no prometheus client for environment %s", environment) - } + api := c.mimirRules + res, err := api.Rules(ctx) if err != nil { return promv1.RulesResult{}, err @@ -175,7 +153,7 @@ func (c *RealClient) RulesAll(ctx context.Context, teamSlug slug.Slug) (map[stri } wg := pool.NewWithResults[*item]().WithContext(ctx) - for env := range c.prometheuses { + for _, env := range []string{"dev"} { wg.Go(func(ctx context.Context) (*item, error) { res, err := c.Rules(ctx, env, teamSlug) if err != nil { From 2f9382ceb6921a34a8fe1a80313a5ab9a75f69d0 Mon Sep 17 00:00:00 2001 From: carl hedgren Date: Wed, 21 Jan 2026 13:42:34 +0100 Subject: [PATCH 06/10] :hocho: unused Co-authored-by: Kyrre Havik --- internal/thirdparty/promclient/client.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/thirdparty/promclient/client.go b/internal/thirdparty/promclient/client.go index 3f7de1d50..4533981dc 100644 --- a/internal/thirdparty/promclient/client.go +++ b/internal/thirdparty/promclient/client.go @@ -10,7 +10,6 @@ import ( "github.com/prometheus/client_golang/api" promv1 "github.com/prometheus/client_golang/api/prometheus/v1" prom "github.com/prometheus/common/model" - "github.com/prometheus/prometheus/rules" "github.com/sirupsen/logrus" "github.com/sourcegraph/conc/pool" ) From 95318942c87387f4bf2ba10ed534d9fd209aa36b Mon Sep 17 00:00:00 2001 From: carl hedgren Date: Wed, 21 Jan 2026 13:59:52 +0100 Subject: [PATCH 07/10] :hocho: unuseds Co-authored-by: Kyrre Havik --- internal/utilization/model.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/utilization/model.go b/internal/utilization/model.go index b562f219c..fc12479c0 100644 --- a/internal/utilization/model.go +++ b/internal/utilization/model.go @@ -143,7 +143,7 @@ func (w WorkloadUtilizationRecommendations) CPURequestCores(ctx context.Context) return math.Max(cpuReq, minCPURequest), nil } -func (w WorkloadUtilizationRecommendations) MemoryRequestBytes(ctx context.Context, env string) (int64, error) { +func (w WorkloadUtilizationRecommendations) MemoryRequestBytes(ctx context.Context) (int64, error) { v, err := w.client.Query(ctx, w.environmentName, fmt.Sprintf(memoryRequestRecommendation, w.environmentName, w.teamSlug, w.workloadName, w.start.Hour(), w.start.Add(time.Hour*12).Hour())) if err != nil { return 0, err From e8d40c83d0f11b9578f2988869a5cfa5977b1866 Mon Sep 17 00:00:00 2001 From: carl hedgren Date: Wed, 21 Jan 2026 14:02:30 +0100 Subject: [PATCH 08/10] ci Co-authored-by: Kyrre Havik --- internal/thirdparty/promclient/client.go | 2 +- internal/utilization/model.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/thirdparty/promclient/client.go b/internal/thirdparty/promclient/client.go index 4533981dc..15d83ccb2 100644 --- a/internal/thirdparty/promclient/client.go +++ b/internal/thirdparty/promclient/client.go @@ -48,7 +48,7 @@ type RealClient struct { log logrus.FieldLogger } -func New(tenant string, log logrus.FieldLogger) (*RealClient, error) { +func New(clusters []string, tenant string, log logrus.FieldLogger) (*RealClient, error) { mimirMetrics, err := api.NewClient(api.Config{Address: "http://mimir-query-frontend"}) if err != nil { return nil, err diff --git a/internal/utilization/model.go b/internal/utilization/model.go index fc12479c0..c55cdd322 100644 --- a/internal/utilization/model.go +++ b/internal/utilization/model.go @@ -42,7 +42,7 @@ func (e UtilizationResourceType) String() string { return string(e) } -func (e *UtilizationResourceType) UnmarshalGQL(v interface{}) error { +func (e *UtilizationResourceType) UnmarshalGQL(v any) error { str, ok := v.(string) if !ok { return fmt.Errorf("enums must be strings") From 9d256b229990abd928649327108849995546ecd8 Mon Sep 17 00:00:00 2001 From: carl hedgren Date: Wed, 21 Jan 2026 14:56:35 +0100 Subject: [PATCH 09/10] service is 8080 --- internal/thirdparty/promclient/client.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/thirdparty/promclient/client.go b/internal/thirdparty/promclient/client.go index 15d83ccb2..5397ef1d4 100644 --- a/internal/thirdparty/promclient/client.go +++ b/internal/thirdparty/promclient/client.go @@ -49,12 +49,12 @@ type RealClient struct { } func New(clusters []string, tenant string, log logrus.FieldLogger) (*RealClient, error) { - mimirMetrics, err := api.NewClient(api.Config{Address: "http://mimir-query-frontend"}) + mimirMetrics, err := api.NewClient(api.Config{Address: "http://mimir-query-frontend:8080"}) if err != nil { return nil, err } - mimirAlerts, err := api.NewClient(api.Config{Address: "http://mimir-ruler"}) + mimirAlerts, err := api.NewClient(api.Config{Address: "http://mimir-ruler:8080"}) if err != nil { return nil, err } From a9728aff1a7ab8a77ad2a60d8e8279357977dc94 Mon Sep 17 00:00:00 2001 From: carl hedgren Date: Thu, 22 Jan 2026 10:10:30 +0100 Subject: [PATCH 10/10] use correct path this shouldn't fix anything --- internal/thirdparty/promclient/client.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/thirdparty/promclient/client.go b/internal/thirdparty/promclient/client.go index 5397ef1d4..faa58089d 100644 --- a/internal/thirdparty/promclient/client.go +++ b/internal/thirdparty/promclient/client.go @@ -49,12 +49,12 @@ type RealClient struct { } func New(clusters []string, tenant string, log logrus.FieldLogger) (*RealClient, error) { - mimirMetrics, err := api.NewClient(api.Config{Address: "http://mimir-query-frontend:8080"}) + mimirMetrics, err := api.NewClient(api.Config{Address: "http://mimir-query-frontend:8080/prometheus"}) if err != nil { return nil, err } - mimirAlerts, err := api.NewClient(api.Config{Address: "http://mimir-ruler:8080"}) + mimirAlerts, err := api.NewClient(api.Config{Address: "http://mimir-ruler:8080/prometheus"}) if err != nil { return nil, err }