From 93b60314bfb8dfc8348b573ddeb9127484c8dc05 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Wed, 30 Apr 2025 13:33:18 +0200 Subject: [PATCH 1/2] Fix linter issue Signed-Off-By: Colin Leroy-Mira --- .golangci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 6175bc1..6966875 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -8,6 +8,6 @@ run: issues: exclude-rules: - - path: _test.go - linters: - - errcheck + - path: _test.go + linters: + - errcheck From 5a1efa42d38d8be61707d439a1d86b0f72694159 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Wed, 30 Apr 2025 13:35:29 +0200 Subject: [PATCH 2/2] Fix "metric was collected before" error The networksecurity.googleapis.com/https/request_count sometimes returns duplicate series. Filter them out to avoid errors. Signed-Off-By: Colin Leroy-Mira --- collectors/monitoring_collector.go | 31 +++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/collectors/monitoring_collector.go b/collectors/monitoring_collector.go index a2c1543..cd03949 100644 --- a/collectors/monitoring_collector.go +++ b/collectors/monitoring_collector.go @@ -18,6 +18,7 @@ import ( "fmt" "log/slog" "math" + "reflect" "strings" "sync" "time" @@ -399,6 +400,28 @@ func (c *MonitoringCollector) reportMonitoringMetrics(ch chan<- prometheus.Metri return <-errChannel } +func (c *MonitoringCollector) filterDuplicateTimeSeries( + timeSeries []*monitoring.TimeSeries, +) []*monitoring.TimeSeries { + var keptTimeSeries []*monitoring.TimeSeries + + for _, timeSerie := range timeSeries { + var skip = false + + for _, keptTimeSerie := range keptTimeSeries { + // Did we already find a timeSerie with the exact same key-value labels? + if reflect.DeepEqual(timeSerie.Metric.Labels, keptTimeSerie.Metric.Labels) { + skip = true + break + } + } + if !skip { + keptTimeSeries = append(keptTimeSeries, timeSerie) + } + } + return keptTimeSeries +} + func (c *MonitoringCollector) reportTimeSeriesMetrics( page *monitoring.ListTimeSeriesResponse, metricDescriptor *monitoring.MetricDescriptor, @@ -408,6 +431,7 @@ func (c *MonitoringCollector) reportTimeSeriesMetrics( var metricValue float64 var metricValueType prometheus.ValueType var newestTSPoint *monitoring.Point + var uniqueTimeSeries []*monitoring.TimeSeries timeSeriesMetrics, err := newTimeSeriesMetrics(metricDescriptor, ch, @@ -419,7 +443,12 @@ func (c *MonitoringCollector) reportTimeSeriesMetrics( if err != nil { return fmt.Errorf("error creating the TimeSeriesMetrics %v", err) } - for _, timeSeries := range page.TimeSeries { + + // Make sure we don't feed Prometheus duplicate time series if the + // metrics page gives us some. + uniqueTimeSeries = c.filterDuplicateTimeSeries(page.TimeSeries) + + for _, timeSeries := range uniqueTimeSeries { newestEndTime := time.Unix(0, 0) for _, point := range timeSeries.Points { endTime, err := time.Parse(time.RFC3339Nano, point.Interval.EndTime)