From 269311d02eaf6825c63042b9aa950561c2189cc2 Mon Sep 17 00:00:00 2001 From: Charles Korn Date: Sun, 17 May 2020 18:05:50 +1000 Subject: [PATCH 1/4] Fix 'rpc error: code = InvalidArgument desc = Invalid parent id!' errors. The parent span ID was being formatted incorrectly, which meant all spans except the root span were rejected by the GCP tracing API. If clients did not have error logging hooked up to WithOnError, this would cause child spans to be silently dropped. The documentation says the parent span ID should be formatted as a 64-bit integer encoded as a string, but appears to accept the hexadecimal format returned by SpanID.String(). --- exporter/trace/trace_proto.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exporter/trace/trace_proto.go b/exporter/trace/trace_proto.go index ba626ee2a..d0bc9f228 100644 --- a/exporter/trace/trace_proto.go +++ b/exporter/trace/trace_proto.go @@ -84,7 +84,7 @@ func protoFromSpanData(s *export.SpanData, projectID string) *tracepb.Span { SameProcessAsParentSpan: &wrapperspb.BoolValue{Value: !s.HasRemoteParent}, } if s.ParentSpanID != s.SpanContext.SpanID && s.ParentSpanID.IsValid() { - sp.ParentSpanId = fmt.Sprintf("%.16x", s.ParentSpanID) + sp.ParentSpanId = s.ParentSpanID.String() } if s.StatusCode != codes.OK { sp.Status = &statuspb.Status{Code: int32(s.StatusCode)} From da35184e4247f60b584ca7c2e79f76b674e43b33 Mon Sep 17 00:00:00 2001 From: YANYZP Date: Wed, 24 Jun 2020 17:23:01 -0400 Subject: [PATCH 2/4] res label copy --- exporter/metric/metric.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/exporter/metric/metric.go b/exporter/metric/metric.go index 23f4e591f..637b89540 100644 --- a/exporter/metric/metric.go +++ b/exporter/metric/metric.go @@ -21,6 +21,7 @@ import ( "log" "strings" "time" + "sync" "go.opentelemetry.io/otel/api/global" apimetric "go.opentelemetry.io/otel/api/metric" @@ -45,6 +46,8 @@ const ( var ( errBlankProjectID = errors.New("expecting a non-blank ProjectID") + monitoredResLabelMap = make(map[string]string) + once sync.Once ) type errUnsupportedAggregation struct { @@ -239,6 +242,8 @@ func (me *metricExporter) recordToTspb(r *export.Record, res *resource.Resource) m := me.recordToMpb(r) mr := me.resourceToMonitoredResourcepb(res) + generateMonitoredResLabelMap(mr.Labels) + tv, t, err := recordToTypedValueAndTimestamp(r) if err != nil { return nil, err @@ -256,6 +261,24 @@ func (me *metricExporter) recordToTspb(r *export.Record, res *resource.Resource) }, nil } +// generateMonitoredResLabelMap renders the monitoredResLabelMap for once +// since the monitored resource labels are static +func generateMonitoredResLabelMap(input map[string]string) { + once.Do(func() { + fmt.Println("****** copying res labels *****") + for k,v := range input { + fmt.Println(k, v) + monitoredResLabelMap[k] = v + } + }) +} + + +// ExportMonitoredResLabels exports the map of monitored resources labels +func (me *metricExporter) ExportMonitoredResLabels() map[string]string { + return monitoredResLabelMap +} + // descToMetricType converts descriptor to MetricType proto type. // Basically this returns default value ("custom.googleapis.com/opentelemetry/[metric type]") func (me *metricExporter) descToMetricType(desc *apimetric.Descriptor) string { From 287619a02e8969ffded377c16d7ceee587125080 Mon Sep 17 00:00:00 2001 From: YANYZP Date: Wed, 24 Jun 2020 17:39:23 -0400 Subject: [PATCH 3/4] encapsulation --- exporter/metric/cloudmonitoring.go | 5 +++++ exporter/metric/metric.go | 9 ++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/exporter/metric/cloudmonitoring.go b/exporter/metric/cloudmonitoring.go index 76e7147f1..caa2b2270 100644 --- a/exporter/metric/cloudmonitoring.go +++ b/exporter/metric/cloudmonitoring.go @@ -83,3 +83,8 @@ func NewRawExporter(opts ...Option) (*Exporter, error) { func (e *Exporter) Export(ctx context.Context, cps export.CheckpointSet) error { return e.metricExporter.ExportMetrics(ctx, cps) } + +// ExportMonitoredResLabels exports the labels of monitored resources. +func (e *Exporter) ExportMonitoredResLabels() map[string]string { + return e.metricExporter.ExportMonitoredResLabels() +} \ No newline at end of file diff --git a/exporter/metric/metric.go b/exporter/metric/metric.go index 637b89540..772ce206b 100644 --- a/exporter/metric/metric.go +++ b/exporter/metric/metric.go @@ -265,9 +265,7 @@ func (me *metricExporter) recordToTspb(r *export.Record, res *resource.Resource) // since the monitored resource labels are static func generateMonitoredResLabelMap(input map[string]string) { once.Do(func() { - fmt.Println("****** copying res labels *****") for k,v := range input { - fmt.Println(k, v) monitoredResLabelMap[k] = v } }) @@ -276,7 +274,12 @@ func generateMonitoredResLabelMap(input map[string]string) { // ExportMonitoredResLabels exports the map of monitored resources labels func (me *metricExporter) ExportMonitoredResLabels() map[string]string { - return monitoredResLabelMap + outputMap := make(map[string]string) + // Do deep copy to protect the label map + for k,v := range monitoredResLabelMap { + outputMap[k] = v + } + return outputMap } // descToMetricType converts descriptor to MetricType proto type. From 9a776943aeb0226c1a749cc8bde7b584008d6ab9 Mon Sep 17 00:00:00 2001 From: YANYZP Date: Fri, 26 Jun 2020 11:14:01 -0400 Subject: [PATCH 4/4] extract res labels --- exporter/metric/metric.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/exporter/metric/metric.go b/exporter/metric/metric.go index 772ce206b..c1b9d7da1 100644 --- a/exporter/metric/metric.go +++ b/exporter/metric/metric.go @@ -21,7 +21,6 @@ import ( "log" "strings" "time" - "sync" "go.opentelemetry.io/otel/api/global" apimetric "go.opentelemetry.io/otel/api/metric" @@ -47,7 +46,6 @@ const ( var ( errBlankProjectID = errors.New("expecting a non-blank ProjectID") monitoredResLabelMap = make(map[string]string) - once sync.Once ) type errUnsupportedAggregation struct { @@ -130,6 +128,7 @@ func InstallNewPipeline(opts []Option, popts ...push.Option) (*push.Controller, // chaining a NewRawExporter into the recommended selectors and integrators. func NewExportPipeline(opts []Option, popts ...push.Option) (*push.Controller, error) { selector := simple.NewWithExactDistribution() + extractResourceLabels(popts...) exporter, err := NewRawExporter(opts...) if err != nil { return nil, err @@ -242,8 +241,6 @@ func (me *metricExporter) recordToTspb(r *export.Record, res *resource.Resource) m := me.recordToMpb(r) mr := me.resourceToMonitoredResourcepb(res) - generateMonitoredResLabelMap(mr.Labels) - tv, t, err := recordToTypedValueAndTimestamp(r) if err != nil { return nil, err @@ -261,14 +258,17 @@ func (me *metricExporter) recordToTspb(r *export.Record, res *resource.Resource) }, nil } -// generateMonitoredResLabelMap renders the monitoredResLabelMap for once -// since the monitored resource labels are static -func generateMonitoredResLabelMap(input map[string]string) { - once.Do(func() { - for k,v := range input { - monitoredResLabelMap[k] = v +// extractResourceLabels extracts resources from the construction option +func extractResourceLabels(popts ...push.Option) { + for _, popt := range popts { + var config push.Config + popt.Apply(&config) + if config.Resource.Len() > 0 { + for _, ele := range config.Resource.Attributes() { + monitoredResLabelMap[string(ele.Key)] = ele.Value.AsString() + } } - }) + } }