diff --git a/metrics.go b/metrics.go index 8a185b9..0ec9325 100644 --- a/metrics.go +++ b/metrics.go @@ -64,6 +64,7 @@ func (se *statsExporter) ExportMetrics(ctx context.Context, metrics []*metricdat func (se *statsExporter) handleMetricsUpload(metrics []*metricdata.Metric) { err := se.uploadMetrics(metrics) + se.o.handleExportResult(err) if err != nil { se.o.handleError(err) } diff --git a/stackdriver.go b/stackdriver.go index 1e253f9..e7f5701 100644 --- a/stackdriver.go +++ b/stackdriver.go @@ -102,6 +102,13 @@ type Options struct { // Optional. OnError func(err error) + // OnExport is the hook to be called when an export happened. If the export + // is a success, the err will be nil. + // By default this is set to nil. + // Note OnError is used in places when no export happens, whereas OnExport + // is only called when export happens. + OnExport func(err error) + // MonitoringClientOptions are additional options to be passed // to the underlying Stackdriver Monitoring API client. // Optional. @@ -469,6 +476,12 @@ func (e *Exporter) Flush() { e.traceExporter.Flush() } +func (o Options) handleExportResult(err error) { + if o.OnExport != nil { + o.OnExport(err) + } +} + func (o Options) handleError(err error) { if o.OnError != nil { o.OnError(err) diff --git a/stackdriver_test.go b/stackdriver_test.go index 3d6fdf9..fac24ae 100644 --- a/stackdriver_test.go +++ b/stackdriver_test.go @@ -138,7 +138,14 @@ func TestGRPC(t *testing.T) { } func TestUserAgent(t *testing.T) { - e, err := NewExporter(Options{UserAgent: "OpenCensus Service"}) + projectID, ok := os.LookupEnv("STACKDRIVER_TEST_PROJECT_ID") + if !ok { + t.Skip("STACKDRIVER_TEST_PROJECT_ID not set") + } + e, err := NewExporter(Options{ + UserAgent: "OpenCensus Service", + ProjectID: projectID, + }) if err != nil { t.Fatal(err) } diff --git a/stats.go b/stats.go index 895945b..c96d62e 100644 --- a/stats.go +++ b/stats.go @@ -167,6 +167,7 @@ func (e *statsExporter) ExportView(vd *view.Data) { return } err := e.viewDataBundler.Add(vd, 1) + e.o.handleExportResult(err) switch err { case nil: return @@ -190,7 +191,9 @@ func getTaskValue() string { // handleUpload handles uploading a slice // of Data, as well as error handling. func (e *statsExporter) handleUpload(vds ...*view.Data) { - if err := e.uploadStats(vds); err != nil { + err := e.uploadStats(vds) + e.o.handleExportResult(err) + if err != nil { e.o.handleError(err) } } diff --git a/trace.go b/trace.go index a106613..8fd8065 100644 --- a/trace.go +++ b/trace.go @@ -101,6 +101,7 @@ func (e *traceExporter) ExportSpan(s *trace.SpanData) { protoSpan := protoFromSpanData(s, e.projectID, e.o.Resource, e.o.UserAgent) protoSize := proto.Size(protoSpan) err := e.bundler.Add(protoSpan, protoSize) + e.o.handleExportResult(err) switch err { case nil: return @@ -174,6 +175,7 @@ func (e *traceExporter) uploadSpans(spans []*tracepb.Span) { span.AddAttributes(trace.Int64Attribute("num_spans", int64(len(spans)))) err := e.client.BatchWriteSpans(ctx, &req) + e.o.handleExportResult(err) if err != nil { span.SetStatus(trace.Status{Code: 2, Message: err.Error()}) e.o.handleError(err)