Skip to content

Commit 8a1d6a8

Browse files
authored
Add more info about filters to docs and rename struct fields (#198)
* Add more info about filters to docs and rename struct fields * Single startup log with more context * ToLower extra fitler prefixes to avoid casing issues with user config * Switch extra filters to apply by prefix instead of contains --------- Signed-off-by: Kyle Eckhart <[email protected]>
1 parent 1538e27 commit 8a1d6a8

File tree

4 files changed

+45
-18
lines changed

4 files changed

+45
-18
lines changed

README.md

+23-3
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ If you are still using the legacy [Access scopes][access-scopes], the `https://w
8585
| `monitoring.metrics-type-prefixes` | Yes | | Comma separated Google Stackdriver Monitoring Metric Type prefixes (see [example][metrics-prefix-example] and [available metrics][metrics-list]) |
8686
| `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 |
8787
| `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 |
88-
| `monitoring.filters` | No | | Formatted string to allow filtering on certain metrics type |
88+
| `monitoring.filters` | No | | Additonal filters to be sent on the Monitoring API call. Add multiple filters by providing this parameter multiple times. See [monitoring.filters](#using-filters) for more info. |
8989
| `monitoring.aggregate-deltas` | No | | If enabled will treat all DELTA metrics as an in-memory counter instead of a gauge. Be sure to read [what to know about aggregating DELTA metrics](#what-to-know-about-aggregating-delta-metrics) |
9090
| `monitoring.aggregate-deltas-ttl` | No | `30m` | How long should a delta metric continue to be exported and stored after GCP stops producing it. Read [slow moving metrics](#slow-moving-metrics) to understand the problem this attempts to solve |
9191
| `monitoring.descriptor-cache-ttl` | No | `0s` | How long should the metric descriptors for a prefixed be cached for |
@@ -147,13 +147,33 @@ stackdriver_exporter \
147147
--monitoring.metrics-type-prefixes "compute.googleapis.com/instance/cpu,compute.googleapis.com/instance/disk"
148148
```
149149

150-
Using extra filters:
150+
### Using filters
151151

152+
The structure for a filter is `<targeted_metric_prefix>:<filter_query>`
153+
154+
The `targeted_metric_prefix` is used to ensure the filter is only applied to the metric_prefix(es) where it makes sense.
155+
It does not explicitly have to match a value from `metric_prefixes` but the `targeted_metric_prefix` must be at least a prefix to one or more `metric_prefixes`
156+
157+
Example: \
158+
metrics_prefixes = pubsub.googleapis.com/snapshot, pubsub.googleapis.com/subscription/num_undelivered_messages \
159+
targeted_metric_prefix options would be \
160+
pubsub.googleapis.com (apply to all defined prefixes) \
161+
pubsub.googleapis.com/snapshot (apply to only snapshot metrics) \
162+
pubsub.googleapis.com/subscription (apply to only subscription metrics) \
163+
pubsub.googleapis.com/subscription/num_undelivered_messages (apply to only the specific subscription metric) \
164+
165+
The `filter_query` will be applied to a final metrics API query when querying for metric data. You can read more about the metric API filter options in GCPs documentation https://cloud.google.com/monitoring/api/v3/filters
166+
167+
The final query sent to the metrics API already includes filters for project and metric type. Each applicable `filter_query` will be appended to the query with an AND
168+
169+
Full example
152170
```
153171
stackdriver_exporter \
154172
--google.project-id=my-test-project \
155173
--monitoring.metrics-type-prefixes='pubsub.googleapis.com/subscription' \
156-
--monitoring.filters='pubsub.googleapis.com/subscription:resource.labels.subscription_id=monitoring.regex.full_match("us-west4.*my-team-subs.*")'
174+
--monitoring.metrics-type-prefixes='compute.googleapis.com/instance/cpu' \
175+
--monitoring.filters='pubsub.googleapis.com/subscription:resource.labels.subscription_id=monitoring.regex.full_match("us-west4.*my-team-subs.*")' \
176+
--monitoring.filters='compute.googleapis.com/instance/cpu:resource.labels.instance=monitoring.regex.full_match("us-west4.*my-team-subs.*")'
157177
```
158178

159179
Using projects filter:

collectors/monitoring_collector.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ import (
3333
const namespace = "stackdriver"
3434

3535
type MetricFilter struct {
36-
Prefix string
37-
Modifier string
36+
TargetedMetricPrefix string
37+
FilterQuery string
3838
}
3939

4040
type MonitoringCollector struct {
@@ -306,8 +306,8 @@ func (c *MonitoringCollector) reportMonitoringMetrics(ch chan<- prometheus.Metri
306306
}
307307

308308
for _, ef := range c.metricsFilters {
309-
if strings.Contains(metricDescriptor.Type, ef.Prefix) {
310-
filter = fmt.Sprintf("%s AND (%s)", filter, ef.Modifier)
309+
if strings.HasPrefix(metricDescriptor.Type, ef.TargetedMetricPrefix) {
310+
filter = fmt.Sprintf("%s AND (%s)", filter, ef.FilterQuery)
311311
}
312312
}
313313

stackdriver_exporter.go

+17-10
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,9 @@ var (
110110
).Default("false").Bool()
111111

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

115117
monitoringMetricsAggregateDeltas = kingpin.Flag(
116118
"monitoring.aggregate-deltas", "If enabled will treat all DELTA metrics as an in-memory counter instead of a gauge",
@@ -277,9 +279,6 @@ func main() {
277279
}
278280
}
279281

280-
level.Info(logger).Log("msg", "Starting stackdriver_exporter", "version", version.Info())
281-
level.Info(logger).Log("msg", "Build context", "build_context", version.BuildContext())
282-
283282
monitoringService, err := createMonitoringService(ctx)
284283
if err != nil {
285284
level.Error(logger).Log("msg", "failed to create monitoring service", "err", err)
@@ -289,7 +288,6 @@ func main() {
289288
var projectIDs []string
290289

291290
if *projectsFilter != "" {
292-
level.Info(logger).Log("msg", "Using Google Cloud Projects Filter", "projectsFilter", *projectsFilter)
293291
projectIDs, err = utils.GetProjectIDsFromFilter(ctx, *projectsFilter)
294292
if err != nil {
295293
level.Error(logger).Log("msg", "failed to get project IDs from filter", "err", err)
@@ -301,7 +299,16 @@ func main() {
301299
projectIDs = append(projectIDs, strings.Split(*projectID, ",")...)
302300
}
303301

304-
level.Info(logger).Log("msg", "Using Google Cloud Project IDs", "projectIDs", fmt.Sprintf("%v", projectIDs))
302+
level.Info(logger).Log(
303+
"msg", "Starting stackdriver_exporter",
304+
"version", version.Info(),
305+
"build_context", version.BuildContext(),
306+
"projects", *projectID,
307+
"metric_prefixes", *monitoringMetricsTypePrefixes,
308+
"extra_filters", strings.Join(*monitoringMetricsExtraFilter, ","),
309+
"projectIDs", fmt.Sprintf("%v", projectIDs),
310+
"projectsFilter", *projectsFilter,
311+
)
305312

306313
metricsTypePrefixes := strings.Split(*monitoringMetricsTypePrefixes, ",")
307314
metricExtraFilters := parseMetricExtraFilters()
@@ -356,11 +363,11 @@ func main() {
356363
func parseMetricExtraFilters() []collectors.MetricFilter {
357364
var extraFilters []collectors.MetricFilter
358365
for _, ef := range *monitoringMetricsExtraFilter {
359-
efPrefix, efModifier := utils.GetExtraFilterModifiers(ef, ":")
360-
if efPrefix != "" {
366+
targetedMetricPrefix, filterQuery := utils.SplitExtraFilter(ef, ":")
367+
if targetedMetricPrefix != "" {
361368
extraFilter := collectors.MetricFilter{
362-
Prefix: efPrefix,
363-
Modifier: efModifier,
369+
TargetedMetricPrefix: strings.ToLower(targetedMetricPrefix),
370+
FilterQuery: filterQuery,
364371
}
365372
extraFilters = append(extraFilters, extraFilter)
366373
}

utils/utils.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func NormalizeMetricName(metricName string) string {
4141
return strings.Join(normalizedMetricName, "_")
4242
}
4343

44-
func GetExtraFilterModifiers(extraFilter string, separator string) (string, string) {
44+
func SplitExtraFilter(extraFilter string, separator string) (string, string) {
4545
mPrefix := strings.Split(extraFilter, separator)
4646
if mPrefix[0] == extraFilter {
4747
return "", ""

0 commit comments

Comments
 (0)