@ -24,7 +24,7 @@ import (
"net/url"
"net/url"
"os"
"os"
"path/filepath"
"path/filepath"
" reflec t"
" so rt"
"strconv"
"strconv"
"strings"
"strings"
"time"
"time"
@ -48,6 +48,7 @@ import (
_ "github.com/prometheus/prometheus/discovery/install" // Register service discovery implementations.
_ "github.com/prometheus/prometheus/discovery/install" // Register service discovery implementations.
"github.com/prometheus/prometheus/discovery/kubernetes"
"github.com/prometheus/prometheus/discovery/kubernetes"
"github.com/prometheus/prometheus/discovery/targetgroup"
"github.com/prometheus/prometheus/discovery/targetgroup"
"github.com/prometheus/prometheus/pkg/labels"
"github.com/prometheus/prometheus/pkg/rulefmt"
"github.com/prometheus/prometheus/pkg/rulefmt"
"github.com/prometheus/prometheus/promql"
"github.com/prometheus/prometheus/promql"
)
)
@ -471,8 +472,8 @@ func checkRules(filename string) (int, []error) {
fmt . Printf ( "%d duplicate rule(s) found.\n" , len ( dRules ) )
fmt . Printf ( "%d duplicate rule(s) found.\n" , len ( dRules ) )
for _ , n := range dRules {
for _ , n := range dRules {
fmt . Printf ( "Metric: %s\nLabel(s):\n" , n . metric )
fmt . Printf ( "Metric: %s\nLabel(s):\n" , n . metric )
for i , l := range n . label {
for _ , l := range n . label {
fmt . Printf ( "\t%s: %s\n" , i, l )
fmt . Printf ( "\t%s: %s\n" , l. Name , l . Value )
}
}
}
}
fmt . Println ( "Might cause inconsistency while recording expressions." )
fmt . Println ( "Might cause inconsistency while recording expressions." )
@ -483,29 +484,52 @@ func checkRules(filename string) (int, []error) {
type compareRuleType struct {
type compareRuleType struct {
metric string
metric string
label map [ string ] string
label labels . Labels
}
type compareRuleTypes [ ] compareRuleType
func ( c compareRuleTypes ) Len ( ) int { return len ( c ) }
func ( c compareRuleTypes ) Swap ( i , j int ) { c [ i ] , c [ j ] = c [ j ] , c [ i ] }
func ( c compareRuleTypes ) Less ( i , j int ) bool { return compare ( c [ i ] , c [ j ] ) < 0 }
func compare ( a , b compareRuleType ) int {
if res := strings . Compare ( a . metric , b . metric ) ; res != 0 {
return res
}
return labels . Compare ( a . label , b . label )
}
}
func checkDuplicates ( groups [ ] rulefmt . RuleGroup ) [ ] compareRuleType {
func checkDuplicates ( groups [ ] rulefmt . RuleGroup ) [ ] compareRuleType {
var duplicates [ ] compareRuleType
var duplicates [ ] compareRuleType
var rules compareRuleTypes
for _ , group := range groups {
for _ , group := range groups {
for index , rule := range group . Rules {
inst := compareRuleType {
for _ , rule := range group . Rules {
rules = append ( rules , compareRuleType {
metric : ruleMetric ( rule ) ,
metric : ruleMetric ( rule ) ,
label : rule . Labels ,
label : labels . FromMap ( rule . Labels ) ,
}
} )
for i := 0 ; i < index ; i ++ {
}
t := compareRuleType {
}
metric : ruleMetric ( group . Rules [ i ] ) ,
if len ( rules ) < 2 {
label : group . Rules [ i ] . Labels ,
return duplicates
}
}
if reflect . DeepEqual ( t , inst ) {
sort . Sort ( rules )
duplicates = append ( duplicates , t )
}
last := rules [ 0 ]
for i := 1 ; i < len ( rules ) ; i ++ {
if compare ( last , rules [ i ] ) == 0 {
// Don't add a duplicated rule multiple times.
if len ( duplicates ) == 0 || compare ( last , duplicates [ len ( duplicates ) - 1 ] ) != 0 {
duplicates = append ( duplicates , rules [ i ] )
}
}
}
}
last = rules [ i ]
}
}
return duplicates
return duplicates
}
}