From 46774543c98dc43af4f8cadbfd9846c2e7e9e2b8 Mon Sep 17 00:00:00 2001 From: dominikhei <105610163+dominikhei@users.noreply.github.com> Date: Wed, 29 Apr 2026 20:37:00 +0200 Subject: [PATCH] Added ctx passing to analyzer api call methods and moved semaphore such that goroutine creation is also limited --- cmd/cardamon/main.go | 5 +---- pkg/grafana/analyzer.go | 10 ++++++---- pkg/grafana/client.go | 13 +++++++------ 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/cmd/cardamon/main.go b/cmd/cardamon/main.go index c772a28..c6eb34e 100644 --- a/cmd/cardamon/main.go +++ b/cmd/cardamon/main.go @@ -45,9 +45,6 @@ func main() { log.Fatalf("Failed to initialize Prometheus client: %v", err) } promAnalyzer := prom.NewAnalyzer(promClient) - if err != nil { - log.Fatalf("Failed to initialize Prometeheus analyzer: %v", err) - } grafanaClient := grafana.NewClient(cfg.Grafana.Address, cfg.Grafana.PathPrefix, cfg.Grafana.Token, cfg.Grafana.Username, cfg.Grafana.Password) grafanaAnalyzer := grafana.NewAnalyzer(grafanaClient) @@ -58,7 +55,7 @@ func main() { log.Fatalf("Error fetching all metric names from Prometheus: %v", err) } - grafanaUsed, err := grafanaAnalyzer.DiscoverUsedMetrics() + grafanaUsed, err := grafanaAnalyzer.DiscoverUsedMetrics(ctx) if err != nil { fmt.Printf("Warning: Creawling Grafana failed: %v\n", err) } diff --git a/pkg/grafana/analyzer.go b/pkg/grafana/analyzer.go index ca82898..279a40a 100644 --- a/pkg/grafana/analyzer.go +++ b/pkg/grafana/analyzer.go @@ -15,6 +15,7 @@ package grafana import ( + "context" "regexp" "sync" ) @@ -32,8 +33,8 @@ func NewAnalyzer(client *Client) *Analyzer { } // DiscoverUsedMetrics crawls all dashboards and returns a unique set of metric names found. -func (a *Analyzer) DiscoverUsedMetrics() ([]string, error) { - dashboards, err := a.client.SearchDashboards() +func (a *Analyzer) DiscoverUsedMetrics(ctx context.Context) ([]string, error) { + dashboards, err := a.client.SearchDashboards(ctx) if err != nil { return nil, err } @@ -44,13 +45,14 @@ func (a *Analyzer) DiscoverUsedMetrics() ([]string, error) { sem := make(chan struct{}, 10) for _, dash := range dashboards { + // The Semaphore limits the amount of goroutines that can be created and thus also the API calls + sem <- struct{}{} wg.Add(1) go func(d DashboardMetadata) { defer wg.Done() - sem <- struct{}{} defer func() { <-sem }() - rawJSON, err := a.client.GetDashboardModel(d.UID) + rawJSON, err := a.client.GetDashboardModel(ctx, d.UID) if err != nil { return } diff --git a/pkg/grafana/client.go b/pkg/grafana/client.go index 4a6b2a8..50ff1d2 100644 --- a/pkg/grafana/client.go +++ b/pkg/grafana/client.go @@ -15,6 +15,7 @@ package grafana import ( + "context" "encoding/json" "io" "net/http" @@ -48,8 +49,8 @@ func NewClient(url, pathPrefix string, token string, username string, password s } // newRequest is used to make a request to the Grafana instance, based on the params in the client struct. -func (c *Client) newRequest(method, path string) (*http.Request, error) { - req, err := http.NewRequest(method, c.URL+c.PathPrefix+path, nil) +func (c *Client) newRequest(ctx context.Context, method, path string) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, method, c.URL+c.PathPrefix+path, nil) if err != nil { return nil, err } @@ -63,8 +64,8 @@ func (c *Client) newRequest(method, path string) (*http.Request, error) { } // SearchDashboards finds all dashboard UIDs. -func (c *Client) SearchDashboards() ([]DashboardMetadata, error) { - req, err := c.newRequest("GET", "/api/search?type=dash-db") +func (c *Client) SearchDashboards(ctx context.Context) ([]DashboardMetadata, error) { + req, err := c.newRequest(ctx, "GET", "/api/search?type=dash-db") if err != nil { return nil, err } @@ -83,8 +84,8 @@ func (c *Client) SearchDashboards() ([]DashboardMetadata, error) { } // GetDashboardModel fetches the raw JSON of a dashboard based on a UID. -func (c *Client) GetDashboardModel(uid string) ([]byte, error) { - req, err := c.newRequest("GET", "/api/dashboards/uid/"+uid) +func (c *Client) GetDashboardModel(ctx context.Context, uid string) ([]byte, error) { + req, err := c.newRequest(ctx, "GET", "/api/dashboards/uid/"+uid) if err != nil { return nil, err }