diff --git a/plugins/outputs/stackdriver/stackdriver.go b/plugins/outputs/stackdriver/stackdriver.go index a16d78aa5..d9eab15e4 100644 --- a/plugins/outputs/stackdriver/stackdriver.go +++ b/plugins/outputs/stackdriver/stackdriver.go @@ -223,7 +223,10 @@ func (s *Stackdriver) sendBatch(batch []telegraf.Metric) error { // Convert any declared tag to a resource label and remove it from // the metric - resourceLabels := s.ResourceLabels + resourceLabels := make(map[string]string, len(s.ResourceLabels)+len(s.TagsAsResourceLabels)) + for k, v := range s.ResourceLabels { + resourceLabels[k] = v + } for _, tag := range s.TagsAsResourceLabels { if val, ok := m.GetTag(tag); ok { resourceLabels[tag] = val diff --git a/plugins/outputs/stackdriver/stackdriver_test.go b/plugins/outputs/stackdriver/stackdriver_test.go index 817468d37..1ab69f5fc 100644 --- a/plugins/outputs/stackdriver/stackdriver_test.go +++ b/plugins/outputs/stackdriver/stackdriver_test.go @@ -155,6 +155,70 @@ func TestWriteResourceTypeAndLabels(t *testing.T) { require.Equal(t, request.TimeSeries[0].Resource.Labels["mylabel"], "myvalue") } +func TestWriteTagsAsResourceLabels(t *testing.T) { + expectedResponse := &emptypb.Empty{} + mockMetric.err = nil + mockMetric.reqs = nil + mockMetric.resps = append(mockMetric.resps[:0], expectedResponse) + + c, err := monitoring.NewMetricClient(context.Background(), clientOpt) + if err != nil { + t.Fatal(err) + } + + s := &Stackdriver{ + Project: fmt.Sprintf("projects/%s", "[PROJECT]"), + Namespace: "test", + ResourceType: "foo", + TagsAsResourceLabels: []string{"job_name"}, + ResourceLabels: map[string]string{ + "mylabel": "myvalue", + }, + Log: testutil.Logger{}, + client: c, + } + + metrics := []telegraf.Metric{ + testutil.MustMetric("cpu", + map[string]string{ + "job_name": "cpu", + "mytag": "foo", + }, + map[string]interface{}{ + "value": 42, + }, + time.Unix(2, 0), + ), + testutil.MustMetric("mem", + map[string]string{ + "job_name": "mem", + "mytag": "bar", + }, + map[string]interface{}{ + "value": 42, + }, + time.Unix(2, 0), + ), + } + + require.NoError(t, s.Connect()) + require.NoError(t, s.Write(metrics)) + require.Len(t, mockMetric.reqs, 1) + + request := mockMetric.reqs[0].(*monitoringpb.CreateTimeSeriesRequest) + require.Len(t, request.TimeSeries, 2) + for _, ts := range request.TimeSeries { + switch ts.Metric.Type { + case "test_mem_value/unknown": + require.Equal(t, "mem", ts.Resource.Labels["job_name"]) + case "test_cpu_value/unknown": + require.Equal(t, "cpu", ts.Resource.Labels["job_name"]) + default: + require.False(t, true, "Unknown metric type") + } + } +} + func TestWriteAscendingTime(t *testing.T) { expectedResponse := &emptypb.Empty{} mockMetric.err = nil