Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add monitoring.filters flag #133

Merged
merged 16 commits into from
Feb 6, 2022
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ If you are still using the legacy [Access scopes][access-scopes], the `https://w
| `monitoring.metrics-type-prefixes`<br />`STACKDRIVER_EXPORTER_MONITORING_METRICS_TYPE_PREFIXES` | Yes | | Comma separated Google Stackdriver Monitoring Metric Type prefixes (see [example][metrics-prefix-example] and [available metrics][metrics-list]) |
| `monitoring.metrics-interval`<br />`STACKDRIVER_EXPORTER_MONITORING_METRICS_INTERVAL` | No | `5m` | Metric's timestamp interval to request from the Google Stackdriver Monitoring Metrics API. Only the most recent data point is used |
| `monitoring.metrics-offset`<br />`STACKDRIVER_EXPORTER_MONITORING_METRICS_OFFSET` | No | `0s` | Offset (into the past) for the metric's timestamp interval to request from the Google Stackdriver Monitoring Metrics API, to handle latency in published metrics |
| `monitoring.filters`| No | Empty list | Formatted string to allow filtering on certain metrics type |
| `web.listen-address`<br />`STACKDRIVER_EXPORTER_WEB_LISTEN_ADDRESS` | No | `:9255` | Address to listen on for web interface and telemetry |
| `web.telemetry-path`<br />`STACKDRIVER_EXPORTER_WEB_TELEMETRY_PATH` | No | `/metrics` | Path under which to expose Prometheus metrics |

Expand Down Expand Up @@ -107,6 +108,15 @@ stackdriver_exporter \
--monitoring.metrics-type-prefixes "compute.googleapis.com/instance/cpu,compute.googleapis.com/instance/disk"
```

Using extra filters:

```
stackdriver_exporter \
--google.project-id my-test-project \
--monitoring.metrics-type-prefixes='pubsub.googleapis.com/subscription' \
--monitoring.metrics-extra-filter='pubsub.googleapis.com/subscription:resource.labels.subscription_id=monitoring.regex.full_match("us-west4.*my-team-subs.*")'
```

## Filtering enabled collectors

The `stackdriver_exporter` collects all metrics type prefixes by default.
Expand Down
28 changes: 28 additions & 0 deletions collectors/monitoring_collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,20 @@ var (
monitoringDropDelegatedProjects = kingpin.Flag(
"monitoring.drop-delegated-projects", "Drop metrics from attached projects and fetch `project_id` only ($STACKDRIVER_EXPORTER_DROP_DELEGATED_PROJECTS).",
).Envar("STACKDRIVER_EXPORTER_DROP_DELEGATED_PROJECTS").Default("false").Bool()

monitoringMetricsExtraFilter = kingpin.Flag(
"monitoring.filters", "Filters. i.e: pubsub.googleapis.com/subscription:resource.labels.subscription_id=monitoring.regex.full_match(\"my-subs-prefix.*\")").Strings()
)

type MetricFilter struct {
Prefix string
Modifier string
}

type MonitoringCollector struct {
projectID string
metricsTypePrefixes []string
metricsFilters []MetricFilter
metricsInterval time.Duration
metricsOffset time.Duration
monitoringService *monitoring.Service
Expand Down Expand Up @@ -145,10 +154,22 @@ func NewMonitoringCollector(projectID string, monitoringService *monitoring.Serv
}
}
}
var extraFilters []MetricFilter
for _, ef := range *monitoringMetricsExtraFilter {
efPrefix, efModifier := utils.GetExtraFilterModifiers(ef, ":")
if efPrefix != "" {
extraFilter := MetricFilter{
Prefix: efPrefix,
Modifier: efModifier,
}
extraFilters = append(extraFilters, extraFilter)
}
}

monitoringCollector := &MonitoringCollector{
projectID: projectID,
metricsTypePrefixes: filteredPrefixes,
metricsFilters: extraFilters,
metricsInterval: *monitoringMetricsInterval,
metricsOffset: *monitoringMetricsOffset,
monitoringService: monitoringService,
Expand Down Expand Up @@ -238,6 +259,13 @@ func (c *MonitoringCollector) reportMonitoringMetrics(ch chan<- prometheus.Metri
c.projectID,
metricDescriptor.Type)
}
for _, ef := range c.metricsFilters {
if strings.Contains(metricDescriptor.Type, ef.Prefix) {
filter = fmt.Sprintf("%s AND (%s)", filter, ef.Modifier)
}
}

level.Debug(c.logger).Log("msg", "retrieving Google Stackdriver Monitoring metrics with filter", "filter", filter)
timeSeriesListCall := c.monitoringService.Projects.TimeSeries.List(utils.ProjectResource(c.projectID)).
Filter(filter).
IntervalStartTime(startTime.Format(time.RFC3339Nano)).
Expand Down
8 changes: 8 additions & 0 deletions utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ func NormalizeMetricName(metricName string) string {
return strings.Join(normalizedMetricName, "_")
}

func GetExtraFilterModifiers(extraFilter string, separator string) (string, string) {
mPrefix := strings.Split(extraFilter, separator)
if mPrefix[0] == extraFilter {
return "", ""
}
return mPrefix[0], strings.Join(mPrefix[1:], "")
}

func ProjectResource(projectID string) string {
return "projects/" + projectID
}