Skip to content

Commit 157cf40

Browse files
authored
Replace comma-delimited string flags with repeatable flags (#355)
* Replace comma-delimited string flags with repeatable flags Signed-off-by: Tommy Li <[email protected]> * preserve old flags but mark them as deprecated Signed-off-by: Tommy Li <[email protected]> --------- Signed-off-by: Tommy Li <[email protected]>
1 parent 166886a commit 157cf40

File tree

2 files changed

+60
-27
lines changed

2 files changed

+60
-27
lines changed

README.md

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,11 @@ If you are still using the legacy [Access scopes][access-scopes], the `https://w
7878

7979
| Flag | Required | Default | Description |
8080
| ----------------------------------- | -------- |---------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
81-
| `google.project-id` | No | GCloud SDK auto-discovery | Comma seperated list of Google Project IDs |
81+
| `google.project-ids` | No | GCloud SDK auto-discovery | Repeatable flag of Google Project IDs |
8282
| `google.projects.filter` | No | | GCloud projects filter expression. See more [here](https://cloud.google.com/sdk/gcloud/reference/projects/list). |
8383
| `monitoring.metrics-ingest-delay` | No | | Offsets metric collection by a delay appropriate for each metric type, e.g. because bigquery metrics are slow to appear |
8484
| `monitoring.drop-delegated-projects` | No | No | Drop metrics from attached projects and fetch `project_id` only. |
85-
| `monitoring.metrics-type-prefixes` | Yes | | Comma separated Google Stackdriver Monitoring Metric Type prefixes (see [example][metrics-prefix-example] and [available metrics][metrics-list]) |
85+
| `monitoring.metrics-prefixes` | Yes | | Repeatable flag of 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 |
8888
| `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. |
@@ -143,8 +143,9 @@ If we want to get all `CPU` (`compute.googleapis.com/instance/cpu`) and `Disk` (
143143

144144
```
145145
stackdriver_exporter \
146-
--google.project-id=my-test-project \
147-
--monitoring.metrics-type-prefixes "compute.googleapis.com/instance/cpu,compute.googleapis.com/instance/disk"
146+
--google.project-ids=my-test-project \
147+
--monitoring.metrics-prefixes "compute.googleapis.com/instance/cpu"
148+
--monitoring.metrics-prefixes "compute.googleapis.com/instance/disk"
148149
```
149150

150151
### Using filters
@@ -163,16 +164,17 @@ Example: \
163164
pubsub.googleapis.com/subscription/num_undelivered_messages (apply to only the specific subscription metric) \
164165

165166
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+
167168
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
168169

169170
Full example
170171
```
171172
stackdriver_exporter \
172-
--google.project-id=my-test-project \
173-
--monitoring.metrics-type-prefixes='pubsub.googleapis.com/subscription,compute.googleapis.com/instance/cpu' \
173+
--google.project-ids=my-test-project \
174+
--monitoring.metrics-prefixes='pubsub.googleapis.com/subscription' \
175+
--monitoring.metrics-prefixes='compute.googleapis.com/instance/cpu' \
174176
--monitoring.filters='pubsub.googleapis.com/subscription:resource.labels.subscription_id=monitoring.regex.full_match("us-west4.*my-team-subs.*")' \
175-
--monitoring.filters='compute.googleapis.com/instance/cpu:resource.labels.instance=monitoring.regex.full_match("us-west4.*my-team-subs.*")'
177+
--monitoring.filters='compute.googleapis.com/instance/cpu:resource.labels.instance=monitoring.regex.full_match("us-west4.*my-team-subs.*")'
176178
```
177179

178180
Using projects filter:

stackdriver_exporter.go

Lines changed: 50 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,13 @@ var (
5858
).Default("/metrics").String()
5959

6060
projectID = kingpin.Flag(
61-
"google.project-id", "Comma seperated list of Google Project IDs.",
61+
"google.project-id", "DEPRECATED - Comma seperated list of Google Project IDs. Use 'google.project-ids' instead.",
6262
).String()
6363

64+
projectIDs = kingpin.Flag(
65+
"google.project-ids", "Repeatable flag of Google Project IDs",
66+
).Strings()
67+
6468
projectsFilter = kingpin.Flag(
6569
"google.projects.filter", "Google projects search filter.",
6670
).String()
@@ -86,10 +90,13 @@ var (
8690
).Default("503").Ints()
8791

8892
// Monitoring collector flags
89-
9093
monitoringMetricsTypePrefixes = kingpin.Flag(
91-
"monitoring.metrics-type-prefixes", "Comma separated Google Stackdriver Monitoring Metric Type prefixes.",
92-
).Required().String()
94+
"monitoring.metrics-type-prefixes", "DEPRECATED - Comma separated Google Stackdriver Monitoring Metric Type prefixes. Use 'monitoring.metrics-prefixes' instead.",
95+
).String()
96+
97+
monitoringMetricsPrefixes = kingpin.Flag(
98+
"monitoring.metrics-prefixes", "Google Stackdriver Monitoring Metric Type prefixes. Repeat this flag to scrape multiple prefixes.",
99+
).Strings()
93100

94101
monitoringMetricsInterval = kingpin.Flag(
95102
"monitoring.metrics-interval", "Interval to request the Google Stackdriver Monitoring Metrics for. Only the most recent data point is used.",
@@ -269,16 +276,29 @@ func main() {
269276
kingpin.Parse()
270277

271278
logger := promlog.New(promlogConfig)
279+
if *projectID != "" {
280+
level.Warn(logger).Log("msg", "The google.project-id flag is deprecated and will be replaced by google.project-ids.")
281+
}
282+
if *monitoringMetricsTypePrefixes != "" {
283+
level.Warn(logger).Log("msg", "The monitoring.metrics-type-prefixes flag is deprecated and will be replaced by monitoring.metrics-prefix.")
284+
}
285+
if *monitoringMetricsTypePrefixes == "" && len(*monitoringMetricsPrefixes) == 0 {
286+
level.Error(logger).Log("msg", "At least one GCP monitoring prefix is required.")
287+
os.Exit(1)
288+
}
272289

273290
ctx := context.Background()
274-
if *projectID == "" && *projectsFilter == "" {
275-
level.Info(logger).Log("msg", "Neither projectID nor projectsFilter was provided. Trying to discover it")
291+
var discoveredProjectIDs []string
292+
293+
if len(*projectIDs) == 0 && *projectID == "" && *projectsFilter == "" {
294+
level.Info(logger).Log("msg", "Neither projectIDs nor projectsFilter was provided. Trying to discover it")
276295
var err error
277-
projectID, err = getDefaultGCPProject(ctx)
296+
defaultProject, err := getDefaultGCPProject(ctx)
278297
if err != nil {
279-
level.Error(logger).Log("msg", "no explicit projectID and error trying to discover default GCloud project", "err", err)
298+
level.Error(logger).Log("msg", "no explicit projectIDs and error trying to discover default GCloud project", "err", err)
280299
os.Exit(1)
281300
}
301+
discoveredProjectIDs = append(discoveredProjectIDs, *defaultProject)
282302
}
283303

284304
monitoringService, err := createMonitoringService(ctx)
@@ -287,43 +307,54 @@ func main() {
287307
os.Exit(1)
288308
}
289309

290-
var projectIDs []string
291-
292310
if *projectsFilter != "" {
293-
projectIDs, err = utils.GetProjectIDsFromFilter(ctx, *projectsFilter)
311+
projectIDsFromFilter, err := utils.GetProjectIDsFromFilter(ctx, *projectsFilter)
294312
if err != nil {
295313
level.Error(logger).Log("msg", "failed to get project IDs from filter", "err", err)
296314
os.Exit(1)
297315
}
316+
discoveredProjectIDs = append(discoveredProjectIDs, projectIDsFromFilter...)
298317
}
299318

319+
if len(*projectIDs) > 0 {
320+
discoveredProjectIDs = append(discoveredProjectIDs, *projectIDs...)
321+
}
300322
if *projectID != "" {
301-
projectIDs = append(projectIDs, strings.Split(*projectID, ",")...)
323+
discoveredProjectIDs = append(discoveredProjectIDs, strings.Split(*projectID, ",")...)
324+
}
325+
326+
var metricsPrefixes []string
327+
if len(*monitoringMetricsPrefixes) > 0 {
328+
metricsPrefixes = append(metricsPrefixes, *monitoringMetricsPrefixes...)
329+
}
330+
if *monitoringMetricsTypePrefixes != "" {
331+
metricsPrefixes = append(metricsPrefixes, strings.Split(*monitoringMetricsTypePrefixes, ",")...)
302332
}
303333

304334
level.Info(logger).Log(
305335
"msg", "Starting stackdriver_exporter",
306336
"version", version.Info(),
307337
"build_context", version.BuildContext(),
308-
"projects", *projectID,
309-
"metric_prefixes", *monitoringMetricsTypePrefixes,
338+
"metric_prefixes", fmt.Sprintf("%v", metricsPrefixes),
310339
"extra_filters", strings.Join(*monitoringMetricsExtraFilter, ","),
311-
"projectIDs", fmt.Sprintf("%v", projectIDs),
340+
"projectIDs", fmt.Sprintf("%v", discoveredProjectIDs),
312341
"projectsFilter", *projectsFilter,
313342
)
314343

315-
inputPrefixes := strings.Split(*monitoringMetricsTypePrefixes, ",")
316-
metricsTypePrefixes := parseMetricTypePrefixes(inputPrefixes)
344+
parsedMetricsPrefixes := parseMetricTypePrefixes(metricsPrefixes)
317345
metricExtraFilters := parseMetricExtraFilters()
346+
// drop duplicate projects
347+
slices.Sort(discoveredProjectIDs)
348+
uniqueProjectIds := slices.Compact(discoveredProjectIDs)
318349

319350
if *metricsPath == *stackdriverMetricsPath {
320351
handler := newHandler(
321-
projectIDs, metricsTypePrefixes, metricExtraFilters, monitoringService, logger, prometheus.DefaultGatherer)
352+
uniqueProjectIds, parsedMetricsPrefixes, metricExtraFilters, monitoringService, logger, prometheus.DefaultGatherer)
322353
http.Handle(*metricsPath, promhttp.InstrumentMetricHandler(prometheus.DefaultRegisterer, handler))
323354
} else {
324355
level.Info(logger).Log("msg", "Serving Stackdriver metrics at separate path", "path", *stackdriverMetricsPath)
325356
handler := newHandler(
326-
projectIDs, metricsTypePrefixes, metricExtraFilters, monitoringService, logger, nil)
357+
uniqueProjectIds, parsedMetricsPrefixes, metricExtraFilters, monitoringService, logger, nil)
327358
http.Handle(*stackdriverMetricsPath, promhttp.InstrumentMetricHandler(prometheus.DefaultRegisterer, handler))
328359
http.Handle(*metricsPath, promhttp.Handler())
329360
}

0 commit comments

Comments
 (0)