44package query
55
66import (
7+ "strings"
78 "time"
89
910 "github.com/go-kit/log"
1011 "github.com/go-kit/log/level"
11- "github.com/gobwas/glob"
1212 "github.com/prometheus/client_golang/prometheus"
1313 "github.com/prometheus/client_golang/prometheus/promauto"
1414 "github.com/prometheus/prometheus/model/labels"
1515)
1616
1717const (
18- aggregationLabelName = "__rollup__"
19- aggregatedMetricNameGlobPattern = "{*:aggr,*:sum,*:count,*:avg,*:min,*:max}"
18+ aggregationLabelName = "__rollup__"
2019)
2120
2221type AggregationLabelRewriter struct {
@@ -25,8 +24,6 @@ type AggregationLabelRewriter struct {
2524
2625 enabled bool
2726 desiredLabelValue string
28-
29- aggregatedMetricNameGlob glob.Glob
3027}
3128
3229type aggregationLabelRewriterMetrics struct {
@@ -36,6 +33,15 @@ type aggregationLabelRewriterMetrics struct {
3633 aggregationLabelRewriterRuntimeSeconds * prometheus.HistogramVec
3734}
3835
36+ func isAggregatedMetric (metricName string ) bool {
37+ return strings .HasSuffix (metricName , ":aggr" ) ||
38+ strings .HasSuffix (metricName , ":avg" ) ||
39+ strings .HasSuffix (metricName , ":count" ) ||
40+ strings .HasSuffix (metricName , ":sum" ) ||
41+ strings .HasSuffix (metricName , ":min" ) ||
42+ strings .HasSuffix (metricName , ":max" )
43+ }
44+
3945func newAggregationLabelRewriterMetrics (reg prometheus.Registerer , desiredLabelValue string ) * aggregationLabelRewriterMetrics {
4046 m := & aggregationLabelRewriterMetrics {}
4147
@@ -54,8 +60,9 @@ func newAggregationLabelRewriterMetrics(reg prometheus.Registerer, desiredLabelV
5460 ConstLabels : prometheus.Labels {"new_value" : desiredLabelValue },
5561 })
5662 m .aggregationLabelRewriterRuntimeSeconds = promauto .With (reg ).NewHistogramVec (prometheus.HistogramOpts {
57- Name : "total_runtime_seconds" ,
58- Help : "Runtime of aggregation-label-rewriter in seconds" ,
63+ Name : "total_runtime_seconds" ,
64+ Help : "Runtime of aggregation-label-rewriter in seconds" ,
65+ Buckets : []float64 {0.0001 , 0.00025 , 0.0005 , 0.001 , 0.005 , 0.01 , 0.1 , 1.0 , 10.0 },
5966 }, []string {"is_rewritten" })
6067
6168 return m
@@ -71,67 +78,75 @@ func NewAggregationLabelRewriter(logger log.Logger, reg prometheus.Registerer, d
7178 if logger == nil {
7279 logger = log .NewNopLogger ()
7380 }
74- g := glob .MustCompile (aggregatedMetricNameGlobPattern )
7581 return & AggregationLabelRewriter {
76- enabled : desiredLabelValue != "" ,
77- logger : logger ,
78- metrics : newAggregationLabelRewriterMetrics (reg , desiredLabelValue ),
79- desiredLabelValue : desiredLabelValue ,
80- aggregatedMetricNameGlob : g ,
82+ enabled : desiredLabelValue != "" ,
83+ logger : logger ,
84+ metrics : newAggregationLabelRewriterMetrics (reg , desiredLabelValue ),
85+ desiredLabelValue : desiredLabelValue ,
8186 }
8287}
8388
8489func (a * AggregationLabelRewriter ) Rewrite (ms []* labels.Matcher ) []* labels.Matcher {
85- if a .enabled {
86- startOfRun := time .Now ()
87- needsRewrite := false
88- skipReason := "no-name-matcher"
89- var aggregationLabelMatcher * labels.Matcher
90- aggregationLabelIndex := - 1
91- for i := 0 ; i < len (ms ); i ++ {
92- m := ms [i ]
93- if ! needsRewrite && m .Name == labels .MetricName {
94- if m .Type == labels .MatchEqual {
95- if a .aggregatedMetricNameGlob .Match (m .Value ) {
96- needsRewrite = true
97- } else {
98- skipReason = "not-aggregated-metric"
99- }
90+ if ! a .enabled {
91+ return ms
92+ }
93+
94+ startOfRun := time .Now ()
95+ needsRewrite := false
96+ skipReason := "no-name-matcher"
97+ var aggregationLabelMatcher * labels.Matcher
98+ aggregationLabelIndex := - 1
99+ for i := 0 ; i < len (ms ); i ++ {
100+ // If we already know we need to rewrite, and we found the aggregation label
101+ // we don't need to loop further, break
102+ if needsRewrite && aggregationLabelMatcher != nil {
103+ break
104+ }
105+ m := ms [i ]
106+ // If we are not sure if we need rewrite, and see a name matcher
107+ // We check if this is an aggregated metric and decide needsRewrite
108+ if ! needsRewrite && m .Name == labels .MetricName {
109+ if m .Type == labels .MatchEqual {
110+ if isAggregatedMetric (m .Value ) {
111+ needsRewrite = true
100112 } else {
101- skipReason = "not-using-equal-name-match"
102- level .Debug (a .logger ).Log ("msg" , "skipped due to not using equal in name matcher" , "matcher" , m )
103- break
113+ skipReason = "not-aggregated-metric"
104114 }
105- } else if needsRewrite && aggregationLabelMatcher != nil {
115+ } else {
116+ skipReason = "not-using-equal-name-match"
117+ level .Debug (a .logger ).Log ("msg" , "skipped due to not using equal in name matcher" , "matcher" , m )
106118 break
107- } else if m .Name == aggregationLabelName {
108- aggregationLabelMatcher = m
109- aggregationLabelIndex = i
110119 }
120+ // In any case, if we see an aggregation label, we store that for later use
121+ } else if m .Name == aggregationLabelName {
122+ aggregationLabelMatcher = m
123+ aggregationLabelIndex = i
111124 }
112- if needsRewrite {
113- newMatcher := & labels.Matcher {
114- Name : aggregationLabelName ,
115- Type : labels .MatchEqual ,
116- Value : a .desiredLabelValue ,
117- }
118- if aggregationLabelMatcher != nil {
119- a .metrics .aggregationLabelRewrittenCount .WithLabelValues (aggregationLabelMatcher .Value ).Inc ()
120- ms [aggregationLabelIndex ] = newMatcher
121- } else {
122- a .metrics .aggregationLabelAddedCount .Inc ()
123- ms = append (ms , newMatcher )
124- }
125- a .metrics .aggregationLabelRewriterRuntimeSeconds .WithLabelValues ("true" ).Observe (
126- time .Since (startOfRun ).Seconds (),
127- )
125+ }
126+ // After the for loop, if needsRewrite is false, no need to do anything
127+ // but if it is true, we either append or modify an aggregation label
128+ if needsRewrite {
129+ newMatcher := & labels.Matcher {
130+ Name : aggregationLabelName ,
131+ Type : labels .MatchEqual ,
132+ Value : a .desiredLabelValue ,
133+ }
134+ if aggregationLabelMatcher != nil {
135+ a .metrics .aggregationLabelRewrittenCount .WithLabelValues (aggregationLabelMatcher .Value ).Inc ()
136+ ms [aggregationLabelIndex ] = newMatcher
128137 } else {
129- a .metrics .aggregationLabelRewriteSkippedCount .WithLabelValues (skipReason ).Inc ()
130- a .metrics .aggregationLabelRewriterRuntimeSeconds .WithLabelValues ("false" ).Observe (
131- time .Since (startOfRun ).Seconds (),
132- )
138+ a .metrics .aggregationLabelAddedCount .Inc ()
139+ ms = append (ms , newMatcher )
133140 }
134-
141+ a .metrics .aggregationLabelRewriterRuntimeSeconds .WithLabelValues ("true" ).Observe (
142+ time .Since (startOfRun ).Seconds (),
143+ )
144+ } else {
145+ a .metrics .aggregationLabelRewriteSkippedCount .WithLabelValues (skipReason ).Inc ()
146+ a .metrics .aggregationLabelRewriterRuntimeSeconds .WithLabelValues ("false" ).Observe (
147+ time .Since (startOfRun ).Seconds (),
148+ )
135149 }
150+
136151 return ms
137152}
0 commit comments