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

[outputs/stackdriver] Allow to group metrics to bypass MetricDescriptor quota (500) #5567

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions plugins/outputs/stackdriver/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ Additional resource labels can be configured by `resource_labels`. By default th
## Custom resource type
# resource_type = "generic_node"

## Compact by type
# group_metrics = false

## Additonal resource labels
# [outputs.stackdriver.resource_labels]
# node_id = "$HOSTNAME"
Expand Down
39 changes: 38 additions & 1 deletion plugins/outputs/stackdriver/stackdriver.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package stackdriver

import (
"bytes"
"context"
"fmt"
"hash/fnv"
Expand All @@ -22,6 +23,7 @@ import (
type Stackdriver struct {
Project string
Namespace string
GroupMetrics bool `toml:"group_metrics"`
ResourceType string `toml:"resource_type"`
ResourceLabels map[string]string `toml:"resource_labels"`

Expand Down Expand Up @@ -59,6 +61,9 @@ var sampleConfig = `
## Custom resource type
# resource_type = "generic_node"

## Compact by type
# GroupMetrics = false

## Additonal resource labels
# [outputs.stackdriver.resource_labels]
# node_id = "$HOSTNAME"
Expand Down Expand Up @@ -169,10 +174,20 @@ func (s *Stackdriver) Write(metrics []telegraf.Metric) error {
Value: value,
}

metricType := path.Join("custom.googleapis.com", s.Namespace, m.Name(), f.Key)
if s.GroupMetrics {
var buffer bytes.Buffer
buffer.WriteString(m.Name())
buffer.WriteString("-")
buffer.WriteString(f.Key)
m.AddTag("name", buffer.String())
metricType = path.Join("custom.googleapis.com", s.Namespace, getStackdriverMetricGroupName(m.Type(), f.Value))
}

// Prepare time series.
timeSeries := &monitoringpb.TimeSeries{
Metric: &metricpb.Metric{
Type: path.Join("custom.googleapis.com", s.Namespace, m.Name(), f.Key),
Type: metricType,
Labels: getStackdriverLabels(m.TagList()),
},
MetricKind: metricKind,
Expand Down Expand Up @@ -265,6 +280,28 @@ func getStackdriverTimeInterval(
}
}

func getStackdriverMetricGroupName(vt telegraf.ValueType, value interface{}) string {
switch vt {
case telegraf.Untyped:
switch value.(type) {
case uint64:
return "counter"
case int64:
return "counter"
case float64:
return "gauge"
default:
return "untag"
}
case telegraf.Gauge:
return "gauge"
case telegraf.Counter:
return "derive"
default:
return "unspecified"
}
}

func getStackdriverMetricKind(vt telegraf.ValueType) (metricpb.MetricDescriptor_MetricKind, error) {
switch vt {
case telegraf.Untyped:
Expand Down