Skip to content

Commit

Permalink
fix: high cardinality policy_violations metrics (#1)
Browse files Browse the repository at this point in the history
* fix: high cardinality policy_violations metrics

The exporter initialises all possible labels of dependency_track_project_policy_violations
metrics which adds 72 metrics for each project.

jetstack#53 has details of the rational but there are usecases where
it is desirable to only have non-zero values of the metrics available.

This change adds a new argument that enables only non-zero value metrics to be returned.
This flag defaults to the current behaviour so is an opt in feature.

* docs: add flag to readme
  • Loading branch information
dwalker-sabiogroup authored Aug 3, 2024
1 parent b4b3d3c commit 5c03ea7
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 33 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ Flags:
Dependency-Track server address (default: http://localhost:8080 or $DEPENDENCY_TRACK_ADDR)
--dtrack.api-key=DTRACK.API-KEY
Dependency-Track API key (default: $DEPENDENCY_TRACK_API_KEY)
--[no-]exporter.reduce-policy-cardinality
Initialize all policy_violations metric label values (can also be set with $EXPORTER_REDUCE_POLICY_CARDINALITY)
--log.level=info Only log messages with the given severity or above. One of: [debug, info, warn, error]
--log.format=logfmt Output format of log messages. One of: [logfmt, json]
--version Show application version.
Expand Down
51 changes: 27 additions & 24 deletions internal/exporter/exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ const (

// Exporter exports metrics from a Dependency-Track server
type Exporter struct {
Client *dtrack.Client
Logger log.Logger
Client *dtrack.Client
Logger log.Logger
ReducePolicyCardinality bool
}

// HandlerFunc handles requests to /metrics
Expand Down Expand Up @@ -235,28 +236,30 @@ func (e *Exporter) collectProjectMetrics(ctx context.Context, registry *promethe

// Initialize all the possible violation series with a 0 value so that it
// properly records increments from 0 -> 1
for _, possibleType := range []string{"LICENSE", "OPERATIONAL", "SECURITY"} {
for _, possibleState := range []string{"INFO", "WARN", "FAIL"} {
for _, possibleAnalysis := range []dtrack.ViolationAnalysisState{
dtrack.ViolationAnalysisStateApproved,
dtrack.ViolationAnalysisStateRejected,
dtrack.ViolationAnalysisStateNotSet,
// If there isn't any analysis for a policy
// violation then the value in the UI is
// actually empty. So let's represent that in
// these metrics as a possible analysis state.
"",
} {
for _, possibleSuppressed := range []string{"true", "false"} {
policyViolations.With(prometheus.Labels{
"uuid": project.UUID.String(),
"name": project.Name,
"version": project.Version,
"type": possibleType,
"state": possibleState,
"analysis": string(possibleAnalysis),
"suppressed": possibleSuppressed,
})
if e.ReducePolicyCardinality {
for _, possibleType := range []string{"LICENSE", "OPERATIONAL", "SECURITY"} {
for _, possibleState := range []string{"INFO", "WARN", "FAIL"} {
for _, possibleAnalysis := range []dtrack.ViolationAnalysisState{
dtrack.ViolationAnalysisStateApproved,
dtrack.ViolationAnalysisStateRejected,
dtrack.ViolationAnalysisStateNotSet,
// If there isn't any analysis for a policy
// violation then the value in the UI is
// actually empty. So let's represent that in
// these metrics as a possible analysis state.
"",
} {
for _, possibleSuppressed := range []string{"true", "false"} {
policyViolations.With(prometheus.Labels{
"uuid": project.UUID.String(),
"name": project.Name,
"version": project.Version,
"type": possibleType,
"state": possibleState,
"analysis": string(possibleAnalysis),
"suppressed": possibleSuppressed,
})
}
}
}
}
Expand Down
21 changes: 12 additions & 9 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ import (
)

const (
envAddress string = "DEPENDENCY_TRACK_ADDR"
envAPIKey string = "DEPENDENCY_TRACK_API_KEY"
envAddress string = "DEPENDENCY_TRACK_ADDR"
envAPIKey string = "DEPENDENCY_TRACK_API_KEY"
envExporterReducePolicyCardinality string = "EXPORTER_REDUCE_POLICY_CARDINALITY"
)

func init() {
Expand All @@ -30,11 +31,12 @@ func init() {

func main() {
var (
webConfig = webflag.AddFlags(kingpin.CommandLine, ":9916")
metricsPath = kingpin.Flag("web.metrics-path", "Path under which to expose metrics").Default("/metrics").String()
dtAddress = kingpin.Flag("dtrack.address", fmt.Sprintf("Dependency-Track server address (can also be set with $%s)", envAddress)).Default("http://localhost:8080").Envar(envAddress).String()
dtAPIKey = kingpin.Flag("dtrack.api-key", fmt.Sprintf("Dependency-Track API key (can also be set with $%s)", envAPIKey)).Envar(envAPIKey).Required().String()
promlogConfig = promlog.Config{}
webConfig = webflag.AddFlags(kingpin.CommandLine, ":9916")
metricsPath = kingpin.Flag("web.metrics-path", "Path under which to expose metrics").Default("/metrics").String()
dtAddress = kingpin.Flag("dtrack.address", fmt.Sprintf("Dependency-Track server address (can also be set with $%s)", envAddress)).Default("http://localhost:8080").Envar(envAddress).String()
dtAPIKey = kingpin.Flag("dtrack.api-key", fmt.Sprintf("Dependency-Track API key (can also be set with $%s)", envAPIKey)).Envar(envAPIKey).Required().String()
exporterReducePolicyCardinality = kingpin.Flag("exporter.reduce-policy-cardinality", fmt.Sprintf("Initialize all policy_violations metric label values (can also be set with $%s)", envExporterReducePolicyCardinality)).Envar(envExporterReducePolicyCardinality).Default("true").Bool()
promlogConfig = promlog.Config{}
)

flag.AddFlags(kingpin.CommandLine, &promlogConfig)
Expand All @@ -54,8 +56,9 @@ func main() {
}

e := exporter.Exporter{
Client: c,
Logger: logger,
Client: c,
Logger: logger,
ReducePolicyCardinality: *exporterReducePolicyCardinality,
}

http.HandleFunc(*metricsPath, e.HandlerFunc())
Expand Down

0 comments on commit 5c03ea7

Please sign in to comment.