@@ -18,6 +18,8 @@ import (
1818 "encoding/json"
1919 "log/slog"
2020 "time"
21+ "fmt"
22+ "strings"
2123
2224 "github.com/prometheus-community/json_exporter/config"
2325 "github.com/prometheus/client_golang/prometheus"
@@ -48,6 +50,7 @@ func (mc JSONMetricCollector) Describe(ch chan<- *prometheus.Desc) {
4850
4951func (mc JSONMetricCollector ) Collect (ch chan <- prometheus.Metric ) {
5052 for _ , m := range mc .JSONMetrics {
53+ seen := make (map [string ]struct {})
5154 switch m .Type {
5255 case config .ValueScrape :
5356 value , err := extractValue (mc .Logger , mc .Data , m .KeyJSONPath , false )
@@ -91,11 +94,18 @@ func (mc JSONMetricCollector) Collect(ch chan<- prometheus.Metric) {
9194 }
9295
9396 if floatValue , err := SanitizeValue (value ); err == nil {
97+ labels := extractLabels (mc .Logger , jdata , m .LabelsJSONPaths )
98+ labelKey := strings .Join (labels , "\x00 " )
99+ if _ , exists := seen [labelKey ]; exists {
100+ mc .Logger .Warn ("Skipping duplicate metric with identical labels" , "metric" , m .Desc , "labels" , fmt .Sprintf ("%v" , labels ))
101+ continue
102+ }
103+ seen [labelKey ] = struct {}{}
94104 metric := prometheus .MustNewConstMetric (
95105 m .Desc ,
96106 m .ValueType ,
97107 floatValue ,
98- extractLabels ( mc . Logger , jdata , m . LabelsJSONPaths ) ... ,
108+ labels ... ,
99109 )
100110 ch <- timestampMetric (mc .Logger , m , jdata , metric )
101111 } else {
@@ -176,4 +186,4 @@ func timestampMetric(logger *slog.Logger, m JSONMetric, data []byte, pm promethe
176186 }
177187 timestamp := time .UnixMilli (epochTime )
178188 return prometheus .NewMetricWithTimestamp (timestamp , pm )
179- }
189+ }
0 commit comments