From 73d1afa5a1e3e27eaed02cfe23116e1c213656a4 Mon Sep 17 00:00:00 2001 From: kisieland Date: Mon, 22 Mar 2021 16:30:55 +0100 Subject: [PATCH] Add host.name label is hostname is present in node. (#2711) Fixes: #2710 **Testing:** I've run `go test ./...` in the changed exporter --- exporter/googlecloudexporter/googlecloud.go | 18 +++- .../googlecloudexporter/googlecloud_test.go | 96 ++++++++++++++++--- 2 files changed, 100 insertions(+), 14 deletions(-) diff --git a/exporter/googlecloudexporter/googlecloud.go b/exporter/googlecloudexporter/googlecloud.go index 3be29f306214..6f05b536b967 100644 --- a/exporter/googlecloudexporter/googlecloud.go +++ b/exporter/googlecloudexporter/googlecloud.go @@ -28,6 +28,7 @@ import ( "go.opentelemetry.io/collector/consumer/consumererror" "go.opentelemetry.io/collector/consumer/pdata" "go.opentelemetry.io/collector/exporter/exporterhelper" + "go.opentelemetry.io/collector/translator/conventions" "go.opentelemetry.io/collector/translator/internaldata" traceexport "go.opentelemetry.io/otel/sdk/export/trace" "google.golang.org/api/option" @@ -182,7 +183,7 @@ func newGoogleCloudMetricsExporter(cfg *Config, params component.ExporterCreateP func (me *metricsExporter) pushMetrics(ctx context.Context, m pdata.Metrics) error { // PushMetricsProto doesn't bundle subsequent calls, so we need to // combine the data here to avoid generating too many RPC calls. - mds := internaldata.MetricsToOC(m) + mds := exportAdditionalLabels(internaldata.MetricsToOC(m)) count := 0 for _, md := range mds { count += len(md.Metrics) @@ -208,6 +209,21 @@ func (me *metricsExporter) pushMetrics(ctx context.Context, m pdata.Metrics) err return err } +func exportAdditionalLabels(mds []internaldata.MetricsData) []internaldata.MetricsData { + for _, md := range mds { + if md.Resource == nil || + md.Resource.Labels == nil || + md.Node == nil || + md.Node.Identifier == nil || + len(md.Node.Identifier.HostName) == 0 { + continue + } + // MetricsToOC removes `host.name` label and writes it to node indentifier, here we reintroduce it. + md.Resource.Labels[conventions.AttributeHostName] = md.Node.Identifier.HostName + } + return mds +} + // pushTraces calls texporter.ExportSpan for each span in the given traces func (te *traceExporter) pushTraces(ctx context.Context, td pdata.Traces) error { var errs []error diff --git a/exporter/googlecloudexporter/googlecloud_test.go b/exporter/googlecloudexporter/googlecloud_test.go index 52ab0bd0715c..27c864c4380f 100644 --- a/exporter/googlecloudexporter/googlecloud_test.go +++ b/exporter/googlecloudexporter/googlecloud_test.go @@ -206,9 +206,12 @@ func TestGoogleCloudMetricExport(t *testing.T) { md := internaldata.MetricsData{ Resource: &resourcepb.Resource{ - Type: "test", + Type: "host", Labels: map[string]string{ - "attr": "attr_value", + "cloud.zone": "us-central1", + "host.name": "foo", + "k8s.cluster.name": "test", + "contrib.opencensus.io/exporter/stackdriver/project_id": "1234567", }, }, Metrics: []*metricspb.Metric{ @@ -233,8 +236,40 @@ func TestGoogleCloudMetricExport(t *testing.T) { time.Now(), []string{"v0", "v1", "v2"}, metricstestutil.Double(time.Now(), 123))), + metricstestutil.Gauge( + "test_gauge4", + []string{"k0", "k1", "k2", "k3"}, + metricstestutil.Timeseries( + time.Now(), + []string{"v0", "v1", "v2", "v3"}, + metricstestutil.Double(time.Now(), 1234))), + metricstestutil.Gauge( + "test_gauge5", + []string{"k4", "k5"}, + metricstestutil.Timeseries( + time.Now(), + []string{"v4", "v5"}, + metricstestutil.Double(time.Now(), 34))), + }, + } + md.Metrics[2].Resource = &resourcepb.Resource{ + Type: "host", + Labels: map[string]string{ + "cloud.zone": "us-central1", + "host.name": "bar", + "k8s.cluster.name": "test", + "contrib.opencensus.io/exporter/stackdriver/project_id": "1234567", + }, + } + md.Metrics[3].Resource = &resourcepb.Resource{ + Type: "host", + Labels: map[string]string{ + "contrib.opencensus.io/exporter/stackdriver/project_id": "1234567", }, } + md.Metrics[4].Resource = &resourcepb.Resource{ + Type: "test", + } assert.NoError(t, sde.ConsumeMetrics(context.Background(), internaldata.OCToMetrics(md)), err) @@ -242,8 +277,10 @@ func TestGoogleCloudMetricExport(t *testing.T) { "projects/idk/metricDescriptors/custom.googleapis.com/opencensus/test_gauge1": {}, "projects/idk/metricDescriptors/custom.googleapis.com/opencensus/test_gauge2": {}, "projects/idk/metricDescriptors/custom.googleapis.com/opencensus/test_gauge3": {}, + "projects/idk/metricDescriptors/custom.googleapis.com/opencensus/test_gauge4": {}, + "projects/idk/metricDescriptors/custom.googleapis.com/opencensus/test_gauge5": {}, } - for i := 0; i < 3; i++ { + for i := 0; i < 5; i++ { drm := <-descriptorReqCh assert.Regexp(t, "MyAgent v0\\.0\\.1", drm.metadata["user-agent"]) dr := drm.req.(*cloudmonitoringpb.CreateMetricDescriptorRequest) @@ -254,30 +291,63 @@ func TestGoogleCloudMetricExport(t *testing.T) { trm := <-timeSeriesReqCh assert.Regexp(t, "MyAgent v0\\.0\\.1", trm.metadata["user-agent"]) tr := trm.req.(*cloudmonitoringpb.CreateTimeSeriesRequest) - require.Len(t, tr.TimeSeries, 3) + require.Len(t, tr.TimeSeries, 5) + + resourceFoo := map[string]string{ + "node_name": "foo", + "cluster_name": "test", + "location": "us-central1", + "project_id": "1234567", + } + + resourceBar := map[string]string{ + "node_name": "bar", + "cluster_name": "test", + "location": "us-central1", + "project_id": "1234567", + } + + resourceProjectID := map[string]string{ + "project_id": "1234567", + } expectedTimeSeries := map[string]struct { - value float64 - labels map[string]string + value float64 + labels map[string]string + resourceLabels map[string]string }{ "custom.googleapis.com/opencensus/test_gauge1": { - value: float64(1), - labels: map[string]string{"k0": "v0"}, + value: float64(1), + labels: map[string]string{"k0": "v0"}, + resourceLabels: resourceFoo, }, "custom.googleapis.com/opencensus/test_gauge2": { - value: float64(12), - labels: map[string]string{"k0": "v0", "k1": "v1"}, + value: float64(12), + labels: map[string]string{"k0": "v0", "k1": "v1"}, + resourceLabels: resourceFoo, }, "custom.googleapis.com/opencensus/test_gauge3": { - value: float64(123), - labels: map[string]string{"k0": "v0", "k1": "v1", "k2": "v2"}, + value: float64(123), + labels: map[string]string{"k0": "v0", "k1": "v1", "k2": "v2"}, + resourceLabels: resourceBar, + }, + "custom.googleapis.com/opencensus/test_gauge4": { + value: float64(1234), + labels: map[string]string{"k0": "v0", "k1": "v1", "k2": "v2", "k3": "v3"}, + resourceLabels: resourceProjectID, + }, + "custom.googleapis.com/opencensus/test_gauge5": { + value: float64(34), + labels: map[string]string{"k4": "v4", "k5": "v5"}, + resourceLabels: nil, }, } - for i := 0; i < 3; i++ { + for i := 0; i < 5; i++ { require.Contains(t, expectedTimeSeries, tr.TimeSeries[i].Metric.Type) ts := expectedTimeSeries[tr.TimeSeries[i].Metric.Type] assert.Equal(t, ts.labels, tr.TimeSeries[i].Metric.Labels) require.Len(t, tr.TimeSeries[i].Points, 1) assert.Equal(t, ts.value, tr.TimeSeries[i].Points[0].Value.GetDoubleValue()) + assert.Equal(t, ts.resourceLabels, tr.TimeSeries[i].Resource.Labels) } }