1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2025-07-05 00:28:58 +02:00

Refactor exporter creation functions (#1985)

* Remove InstallNewPipeline/NewExportPipeline funcs

* Rename stdout NewExporter to New

* Rename prometheus NewExporter func to New

* Rename Jaeger exporter NewRawExporter func to New

* Rename zipkin exporter NewRawExporter func to New

* Rename otlp exporter creation funcs

* Rename processortest exporter creation funcs

* Update PR number in changelog

* Fix spelling error

* Rename remaining NewUnstartedExporter in otlp

* Remove unused testing file
This commit is contained in:
Tyler Yahn
2021-06-10 16:22:47 +00:00
committed by GitHub
parent 87cc1e1fea
commit 4883cb119d
48 changed files with 237 additions and 755 deletions

View File

@ -74,6 +74,12 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- The `Get` method of the `TraceState` type from the `go.opentelemetry.io/otel/trace` package has been updated to accept a `string` instead of an `attribute.Key` type. (#1931) - The `Get` method of the `TraceState` type from the `go.opentelemetry.io/otel/trace` package has been updated to accept a `string` instead of an `attribute.Key` type. (#1931)
- The `Insert` method of the `TraceState` type from the `go.opentelemetry.io/otel/trace` package has been updated to accept a pair of `string`s instead of an `attribute.KeyValue` type. (#1931) - The `Insert` method of the `TraceState` type from the `go.opentelemetry.io/otel/trace` package has been updated to accept a pair of `string`s instead of an `attribute.KeyValue` type. (#1931)
- The `Delete` method of the `TraceState` type from the `go.opentelemetry.io/otel/trace` package has been updated to accept a `string` instead of an `attribute.Key` type. (#1931) - The `Delete` method of the `TraceState` type from the `go.opentelemetry.io/otel/trace` package has been updated to accept a `string` instead of an `attribute.Key` type. (#1931)
- Rename `NewExporter` to `New` in the `go.opentelemetry.io/otel/exporters/stdout` package. (#1985)
- Rename `NewExporter` to `New` in the `go.opentelemetry.io/otel/exporters/metric/prometheus` package. (#1985)
- Rename `NewExporter` to `New` in the `go.opentelemetry.io/otel/exporters/trace/jaeger` package. (#1985)
- Rename `NewExporter` to `New` in the `go.opentelemetry.io/otel/exporters/trace/zipkin` package. (#1985)
- Rename `NewExporter` to `New` in the `go.opentelemetry.io/otel/exporters/otlp` package. (#1985)
- Rename `NewUnstartedExporter` to `NewUnstarted` in the `go.opentelemetry.io/otel/exporters/otlp` package. (#1985)
### Deprecated ### Deprecated
@ -96,6 +102,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- The `IsEmpty` method of the `TraceState` type in the `go.opentelemetry.io/otel/trace` package is removed in favor of using the added `TraceState.Len` method. (#1931) - The `IsEmpty` method of the `TraceState` type in the `go.opentelemetry.io/otel/trace` package is removed in favor of using the added `TraceState.Len` method. (#1931)
- The `Set`, `Value`, `ContextWithValue`, `ContextWithoutValue`, and `ContextWithEmpty` functions in the `go.opentelemetry.io/otel/baggage` package are removed. - The `Set`, `Value`, `ContextWithValue`, `ContextWithoutValue`, and `ContextWithEmpty` functions in the `go.opentelemetry.io/otel/baggage` package are removed.
Handling of baggage is now done using the added `Baggage` type and related context functions (`ContextWithBaggage`, `ContextWithoutBaggage`, and `FromContext`) in that package. (TBD) Handling of baggage is now done using the added `Baggage` type and related context functions (`ContextWithBaggage`, `ContextWithoutBaggage`, and `FromContext`) in that package. (TBD)
- The `InstallNewPipeline` and `NewExportPipeline` creation functions in all the exporters (prometheus, otlp, stdout, jaeger, and zipkin) have been removed.
These functions were deemed premature attempts to provide convenience that did not achieve this aim. (#1985)
### Fixed ### Fixed

View File

@ -119,7 +119,7 @@ import (
// import logexporter "go.opencensus.io/examples/exporter" // import logexporter "go.opencensus.io/examples/exporter"
// exporter, _ := logexporter.NewLogExporter(logexporter.Options{}) // exporter, _ := logexporter.NewLogExporter(logexporter.Options{})
// Instead, we can create an equivalent using the OpenTelemetry stdout exporter: // Instead, we can create an equivalent using the OpenTelemetry stdout exporter:
openTelemetryExporter, _ := stdout.NewExporter(stdout.WithPrettyPrint()) openTelemetryExporter, _ := stdout.New(stdout.WithPrettyPrint())
exporter := opencensus.NewMetricExporter(openTelemetryExporter) exporter := opencensus.NewMetricExporter(openTelemetryExporter)
// Use the wrapped OpenTelemetry exporter like you normally would with OpenCensus // Use the wrapped OpenTelemetry exporter like you normally would with OpenCensus

View File

@ -42,7 +42,7 @@ const (
// about the application. // about the application.
func tracerProvider(url string) (*tracesdk.TracerProvider, error) { func tracerProvider(url string) (*tracesdk.TracerProvider, error) {
// Create the Jaeger exporter // Create the Jaeger exporter
exp, err := jaeger.NewRawExporter(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(url))) exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(url)))
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -38,7 +38,7 @@ var tp *sdktrace.TracerProvider
// initTracer creates and registers trace provider instance. // initTracer creates and registers trace provider instance.
func initTracer() { func initTracer() {
var err error var err error
exp, err := stdout.NewExporter(stdout.WithPrettyPrint()) exp, err := stdout.New(stdout.WithPrettyPrint())
if err != nil { if err != nil {
log.Panicf("failed to initialize stdout exporter %v\n", err) log.Panicf("failed to initialize stdout exporter %v\n", err)
return return

View File

@ -52,7 +52,7 @@ var (
func main() { func main() {
log.Println("Using OpenTelemetry stdout exporter.") log.Println("Using OpenTelemetry stdout exporter.")
otExporter, err := stdout.NewExporter(stdout.WithPrettyPrint()) otExporter, err := stdout.New(stdout.WithPrettyPrint())
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }

View File

@ -56,7 +56,7 @@ func initProvider() func() {
otlpgrpc.WithEndpoint("localhost:30080"), otlpgrpc.WithEndpoint("localhost:30080"),
otlpgrpc.WithDialOption(grpc.WithBlock()), // useful for testing otlpgrpc.WithDialOption(grpc.WithBlock()), // useful for testing
) )
exp, err := otlp.NewExporter(ctx, driver) exp, err := otlp.New(ctx, driver)
handleErr(err, "failed to create exporter") handleErr(err, "failed to create exporter")
res, err := resource.New(ctx, res, err := resource.New(ctx,

View File

@ -13,7 +13,7 @@ But the following will propagate context _and_ create new, potentially recorded
```golang ```golang
// Setup SDK // Setup SDK
exp, _ := stdout.NewExporter(stdout.WithPrettyPrint()) exp, _ := stdout.New(stdout.WithPrettyPrint())
tp = sdktrace.NewTracerProvider( tp = sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exp), sdktrace.WithBatcher(exp),
) )

View File

@ -76,7 +76,7 @@ func initPassthroughGlobals() {
// set it as the global tracer provider // set it as the global tracer provider
func nonGlobalTracer() *sdktrace.TracerProvider { func nonGlobalTracer() *sdktrace.TracerProvider {
var err error var err error
exp, err := stdout.NewExporter(stdout.WithPrettyPrint()) exp, err := stdout.New(stdout.WithPrettyPrint())
if err != nil { if err != nil {
log.Panicf("failed to initialize stdout exporter %v\n", err) log.Panicf("failed to initialize stdout exporter %v\n", err)
} }

View File

@ -52,7 +52,7 @@ func initMeter() {
otlpgrpc.WithEndpoint("localhost:30080"), otlpgrpc.WithEndpoint("localhost:30080"),
otlpgrpc.WithDialOption(grpc.WithBlock()), // useful for testing otlpgrpc.WithDialOption(grpc.WithBlock()), // useful for testing
) )
otlpExporter, err := otlp.NewExporter(ctx, driver) otlpExporter, err := otlp.New(ctx, driver)
if err != nil { if err != nil {
log.Fatal("could not initialize OTLP:", err) log.Fatal("could not initialize OTLP:", err)
@ -76,7 +76,7 @@ func initMeter() {
log.Fatal("could not start controller:", err) log.Fatal("could not start controller:", err)
} }
promExporter, err := prometheus.NewExporter(prometheus.Config{}, cont) promExporter, err := prometheus.New(prometheus.Config{}, cont)
if err != nil { if err != nil {
log.Fatal("could not initialize prometheus:", err) log.Fatal("could not initialize prometheus:", err)
} }

View File

@ -12,6 +12,8 @@ require (
go.opentelemetry.io/otel v0.20.0 go.opentelemetry.io/otel v0.20.0
go.opentelemetry.io/otel/exporters/metric/prometheus v0.20.0 go.opentelemetry.io/otel/exporters/metric/prometheus v0.20.0
go.opentelemetry.io/otel/metric v0.20.0 go.opentelemetry.io/otel/metric v0.20.0
go.opentelemetry.io/otel/sdk/export/metric v0.20.0
go.opentelemetry.io/otel/sdk/metric v0.20.0
) )
replace go.opentelemetry.io/otel/bridge/opencensus => ../../bridge/opencensus replace go.opentelemetry.io/otel/bridge/opencensus => ../../bridge/opencensus

View File

@ -26,6 +26,11 @@ import (
"go.opentelemetry.io/otel/exporters/metric/prometheus" "go.opentelemetry.io/otel/exporters/metric/prometheus"
"go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/global" "go.opentelemetry.io/otel/metric/global"
export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/metric/aggregator/histogram"
controller "go.opentelemetry.io/otel/sdk/metric/controller/basic"
processor "go.opentelemetry.io/otel/sdk/metric/processor/basic"
selector "go.opentelemetry.io/otel/sdk/metric/selector/simple"
) )
var ( var (
@ -33,10 +38,22 @@ var (
) )
func initMeter() { func initMeter() {
exporter, err := prometheus.InstallNewPipeline(prometheus.Config{}) config := prometheus.Config{}
c := controller.New(
processor.New(
selector.NewWithHistogramDistribution(
histogram.WithExplicitBoundaries(config.DefaultHistogramBoundaries),
),
export.CumulativeExportKindSelector(),
processor.WithMemory(true),
),
)
exporter, err := prometheus.New(config, c)
if err != nil { if err != nil {
log.Panicf("failed to initialize prometheus exporter %v", err) log.Panicf("failed to initialize prometheus exporter %v", err)
} }
global.SetMeterProvider(exporter.MeterProvider())
http.HandleFunc("/", exporter.ServeHTTP) http.HandleFunc("/", exporter.ServeHTTP)
go func() { go func() {
_ = http.ListenAndServe(":2222", nil) _ = http.ListenAndServe(":2222", nil)

View File

@ -40,7 +40,7 @@ func initTracer(url string) func() {
// For demoing purposes, always sample. In a production application, you should // For demoing purposes, always sample. In a production application, you should
// configure the sampler to a trace.ParentBased(trace.TraceIDRatioBased) set at the desired // configure the sampler to a trace.ParentBased(trace.TraceIDRatioBased) set at the desired
// ratio. // ratio.
exporter, err := zipkin.NewRawExporter( exporter, err := zipkin.New(
url, url,
zipkin.WithLogger(logger), zipkin.WithLogger(logger),
zipkin.WithSDKOptions(sdktrace.WithSampler(sdktrace.AlwaysSample())), zipkin.WithSDKOptions(sdktrace.WithSampler(sdktrace.AlwaysSample())),

View File

@ -1,114 +0,0 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package prometheus_test
import (
"bytes"
"context"
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/exporters/metric/prometheus"
"go.opentelemetry.io/otel/metric"
controller "go.opentelemetry.io/otel/sdk/metric/controller/basic"
"go.opentelemetry.io/otel/sdk/resource"
)
// This test demonstrates that it is relatively difficult to setup a
// Prometheus export pipeline:
//
// 1. The default boundaries are difficult to pass, should be []float instead of []number.Number
//
// TODO: Address this issue.
func ExampleNewExportPipeline() {
// Create a resource, with builtin attributes plus R=V.
res, err := resource.New(
context.Background(),
resource.WithAttributes(attribute.String("R", "V")),
)
if err != nil {
panic(err)
}
// Create a meter
exporter, err := prometheus.NewExportPipeline(
prometheus.Config{},
controller.WithResource(res),
)
if err != nil {
panic(err)
}
meter := exporter.MeterProvider().Meter("example")
ctx := context.Background()
// Use two instruments
counter := metric.Must(meter).NewInt64Counter(
"a.counter",
metric.WithDescription("Counts things"),
)
recorder := metric.Must(meter).NewInt64ValueRecorder(
"a.valuerecorder",
metric.WithDescription("Records values"),
)
counter.Add(ctx, 100, attribute.String("key", "value"))
recorder.Record(ctx, 100, attribute.String("key", "value"))
// GET the HTTP endpoint
var input bytes.Buffer
resp := httptest.NewRecorder()
req, err := http.NewRequest("GET", "/", &input)
if err != nil {
panic(err)
}
exporter.ServeHTTP(resp, req)
data, err := ioutil.ReadAll(resp.Result().Body)
if err != nil {
panic(err)
}
fmt.Print(string(data))
// Output:
// # HELP a_counter Counts things
// # TYPE a_counter counter
// a_counter{R="V",key="value"} 100
// # HELP a_valuerecorder Records values
// # TYPE a_valuerecorder histogram
// a_valuerecorder_bucket{R="V",key="value",le="+Inf"} 1
// a_valuerecorder_sum{R="V",key="value"} 100
// a_valuerecorder_count{R="V",key="value"} 1
}
func ExampleInstallNewPipeline() {
exporter, err := prometheus.InstallNewPipeline(prometheus.Config{})
if err != nil {
panic(err)
}
// Expose metrics via HTTP in your handler/muxer
http.Handle("/metrics", exporter)
// When exiting from your process, call Stop for last collection cycle.
defer func() {
err := exporter.Controller().Stop(context.TODO())
if err != nil {
panic(err)
}
}()
}

View File

@ -29,14 +29,10 @@ import (
"go.opentelemetry.io/otel" "go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/global"
"go.opentelemetry.io/otel/metric/number" "go.opentelemetry.io/otel/metric/number"
export "go.opentelemetry.io/otel/sdk/export/metric" export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation" "go.opentelemetry.io/otel/sdk/export/metric/aggregation"
"go.opentelemetry.io/otel/sdk/metric/aggregator/histogram"
controller "go.opentelemetry.io/otel/sdk/metric/controller/basic" controller "go.opentelemetry.io/otel/sdk/metric/controller/basic"
processor "go.opentelemetry.io/otel/sdk/metric/processor/basic"
selector "go.opentelemetry.io/otel/sdk/metric/selector/simple"
) )
// Exporter supports Prometheus pulls. It does not implement the // Exporter supports Prometheus pulls. It does not implement the
@ -89,9 +85,9 @@ type Config struct {
DefaultHistogramBoundaries []float64 DefaultHistogramBoundaries []float64
} }
// NewExporter returns a new Prometheus exporter using the configured // New returns a new Prometheus exporter using the configured metric
// metric controller. See controller.New(). // controller. See controller.New().
func NewExporter(config Config, controller *controller.Controller) (*Exporter, error) { func New(config Config, controller *controller.Controller) (*Exporter, error) {
if config.Registry == nil { if config.Registry == nil {
config.Registry = prometheus.NewRegistry() config.Registry = prometheus.NewRegistry()
} }
@ -121,37 +117,6 @@ func NewExporter(config Config, controller *controller.Controller) (*Exporter, e
return e, nil return e, nil
} }
// NewExportPipeline sets up a complete export pipeline with the recommended setup,
// using the recommended selector and standard processor. See the controller.Options.
func NewExportPipeline(config Config, options ...controller.Option) (*Exporter, error) {
return NewExporter(config, defaultController(config, options...))
}
// InstallNewPipeline instantiates a NewExportPipeline and registers it globally.
func InstallNewPipeline(config Config, options ...controller.Option) (*Exporter, error) {
exp, err := NewExportPipeline(config, options...)
if err != nil {
return nil, err
}
global.SetMeterProvider(exp.MeterProvider())
return exp, nil
}
// defaultController returns a standard *controller.Controller for use
// with Prometheus.
func defaultController(config Config, options ...controller.Option) *controller.Controller {
return controller.New(
processor.New(
selector.NewWithHistogramDistribution(
histogram.WithExplicitBoundaries(config.DefaultHistogramBoundaries),
),
export.CumulativeExportKindSelector(),
processor.WithMemory(true),
),
options...,
)
}
// MeterProvider returns the MeterProvider of this exporter. // MeterProvider returns the MeterProvider of this exporter.
func (e *Exporter) MeterProvider() metric.MeterProvider { func (e *Exporter) MeterProvider() metric.MeterProvider {
return e.controller.MeterProvider() return e.controller.MeterProvider()

View File

@ -27,7 +27,11 @@ import (
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/exporters/metric/prometheus" "go.opentelemetry.io/otel/exporters/metric/prometheus"
"go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric"
export "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/metric/aggregator/histogram"
controller "go.opentelemetry.io/otel/sdk/metric/controller/basic" controller "go.opentelemetry.io/otel/sdk/metric/controller/basic"
processor "go.opentelemetry.io/otel/sdk/metric/processor/basic"
selector "go.opentelemetry.io/otel/sdk/metric/selector/simple"
"go.opentelemetry.io/otel/sdk/resource" "go.opentelemetry.io/otel/sdk/resource"
) )
@ -78,8 +82,22 @@ func expectHistogram(name string, values ...string) expectedMetric {
} }
} }
func newPipeline(config prometheus.Config, options ...controller.Option) (*prometheus.Exporter, error) {
c := controller.New(
processor.New(
selector.NewWithHistogramDistribution(
histogram.WithExplicitBoundaries(config.DefaultHistogramBoundaries),
),
export.CumulativeExportKindSelector(),
processor.WithMemory(true),
),
options...,
)
return prometheus.New(config, c)
}
func TestPrometheusExporter(t *testing.T) { func TestPrometheusExporter(t *testing.T) {
exporter, err := prometheus.NewExportPipeline( exporter, err := newPipeline(
prometheus.Config{ prometheus.Config{
DefaultHistogramBoundaries: []float64{-0.5, 1}, DefaultHistogramBoundaries: []float64{-0.5, 1},
}, },
@ -155,7 +173,7 @@ func compareExport(t *testing.T, exporter *prometheus.Exporter, expected []expec
func TestPrometheusStatefulness(t *testing.T) { func TestPrometheusStatefulness(t *testing.T) {
// Create a meter // Create a meter
exporter, err := prometheus.NewExportPipeline( exporter, err := newPipeline(
prometheus.Config{}, prometheus.Config{},
controller.WithCollectPeriod(0), controller.WithCollectPeriod(0),
controller.WithResource(resource.Empty()), controller.WithResource(resource.Empty()),

View File

@ -12,4 +12,4 @@ The exporter can be installed using standard `go` functionality.
go get -u go.opentelemetry.io/otel/exporters/otlp go get -u go.opentelemetry.io/otel/exporters/otlp
``` ```
A new exporter can be created using the `NewExporter` function. A new exporter can be created using the `New` function.

View File

@ -25,7 +25,7 @@ import (
sdktrace "go.opentelemetry.io/otel/sdk/trace" sdktrace "go.opentelemetry.io/otel/sdk/trace"
) )
func ExampleNewExporter() { func ExampleNew() {
ctx := context.Background() ctx := context.Background()
// Set different endpoints for the metrics and traces collectors // Set different endpoints for the metrics and traces collectors
@ -36,7 +36,7 @@ func ExampleNewExporter() {
// Configure traces driver here // Configure traces driver here
) )
driver := otlp.NewSplitDriver(otlp.WithMetricDriver(metricsDriver), otlp.WithTraceDriver(tracesDriver)) driver := otlp.NewSplitDriver(otlp.WithMetricDriver(metricsDriver), otlp.WithTraceDriver(tracesDriver))
exporter, err := otlp.NewExporter(ctx, driver) // Configure as needed. exporter, err := otlp.New(ctx, driver) // Configure as needed.
if err != nil { if err != nil {
log.Fatalf("failed to create exporter: %v", err) log.Fatalf("failed to create exporter: %v", err)
} }

View File

@ -19,15 +19,10 @@ import (
"errors" "errors"
"sync" "sync"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric"
metricsdk "go.opentelemetry.io/otel/sdk/export/metric" metricsdk "go.opentelemetry.io/otel/sdk/export/metric"
"go.opentelemetry.io/otel/sdk/export/metric/aggregation" "go.opentelemetry.io/otel/sdk/export/metric/aggregation"
"go.opentelemetry.io/otel/sdk/metric/selector/simple"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
"go.opentelemetry.io/otel/sdk/metric/controller/basic"
processor "go.opentelemetry.io/otel/sdk/metric/processor/basic"
tracesdk "go.opentelemetry.io/otel/sdk/trace" tracesdk "go.opentelemetry.io/otel/sdk/trace"
) )
@ -48,17 +43,17 @@ type Exporter struct {
var _ tracesdk.SpanExporter = (*Exporter)(nil) var _ tracesdk.SpanExporter = (*Exporter)(nil)
var _ metricsdk.Exporter = (*Exporter)(nil) var _ metricsdk.Exporter = (*Exporter)(nil)
// NewExporter constructs a new Exporter and starts it. // New constructs a new Exporter and starts it.
func NewExporter(ctx context.Context, driver ProtocolDriver, opts ...ExporterOption) (*Exporter, error) { func New(ctx context.Context, driver ProtocolDriver, opts ...ExporterOption) (*Exporter, error) {
exp := NewUnstartedExporter(driver, opts...) exp := NewUnstarted(driver, opts...)
if err := exp.Start(ctx); err != nil { if err := exp.Start(ctx); err != nil {
return nil, err return nil, err
} }
return exp, nil return exp, nil
} }
// NewUnstartedExporter constructs a new Exporter and does not start it. // NewUnstarted constructs a new Exporter and does not start it.
func NewUnstartedExporter(driver ProtocolDriver, opts ...ExporterOption) *Exporter { func NewUnstarted(driver ProtocolDriver, opts ...ExporterOption) *Exporter {
cfg := config{ cfg := config{
// Note: the default ExportKindSelector is specified // Note: the default ExportKindSelector is specified
// as Cumulative: // as Cumulative:
@ -134,46 +129,3 @@ func (e *Exporter) ExportKindFor(desc *metric.Descriptor, kind aggregation.Kind)
func (e *Exporter) ExportSpans(ctx context.Context, spans []tracesdk.ReadOnlySpan) error { func (e *Exporter) ExportSpans(ctx context.Context, spans []tracesdk.ReadOnlySpan) error {
return e.driver.ExportTraces(ctx, spans) return e.driver.ExportTraces(ctx, spans)
} }
// NewExportPipeline sets up a complete export pipeline
// with the recommended TracerProvider setup.
func NewExportPipeline(ctx context.Context, driver ProtocolDriver, exporterOpts ...ExporterOption) (*Exporter,
*sdktrace.TracerProvider, *basic.Controller, error) {
exp, err := NewExporter(ctx, driver, exporterOpts...)
if err != nil {
return nil, nil, nil, err
}
tracerProvider := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exp),
)
cntr := basic.New(
processor.New(
simple.NewWithInexpensiveDistribution(),
exp,
),
)
return exp, tracerProvider, cntr, nil
}
// InstallNewPipeline instantiates a NewExportPipeline with the
// recommended configuration and registers it globally.
func InstallNewPipeline(ctx context.Context, driver ProtocolDriver, exporterOpts ...ExporterOption) (*Exporter,
*sdktrace.TracerProvider, *basic.Controller, error) {
exp, tp, cntr, err := NewExportPipeline(ctx, driver, exporterOpts...)
if err != nil {
return nil, nil, nil, err
}
otel.SetTracerProvider(tp)
err = cntr.Start(ctx)
if err != nil {
return nil, nil, nil, err
}
return exp, tp, cntr, err
}

View File

@ -24,7 +24,6 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/otlp" "go.opentelemetry.io/otel/exporters/otlp"
"go.opentelemetry.io/otel/exporters/otlp/internal/transform" "go.opentelemetry.io/otel/exporters/otlp/internal/transform"
metricsdk "go.opentelemetry.io/otel/sdk/export/metric" metricsdk "go.opentelemetry.io/otel/sdk/export/metric"
@ -162,7 +161,7 @@ func (m *stubTransformingProtocolDriver) Reset() {
func newExporter(t *testing.T, opts ...otlp.ExporterOption) (*otlp.Exporter, *stubTransformingProtocolDriver) { func newExporter(t *testing.T, opts ...otlp.ExporterOption) (*otlp.Exporter, *stubTransformingProtocolDriver) {
driver := &stubTransformingProtocolDriver{} driver := &stubTransformingProtocolDriver{}
exp, err := otlp.NewExporter(context.Background(), driver, opts...) exp, err := otlp.New(context.Background(), driver, opts...)
require.NoError(t, err) require.NoError(t, err)
return exp, driver return exp, driver
} }
@ -171,7 +170,7 @@ func TestExporterShutdownHonorsTimeout(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute) ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel() defer cancel()
e := otlp.NewUnstartedExporter(&stubProtocolDriver{}) e := otlp.NewUnstarted(&stubProtocolDriver{})
if err := e.Start(ctx); err != nil { if err := e.Start(ctx); err != nil {
t.Fatalf("failed to start exporter: %v", err) t.Fatalf("failed to start exporter: %v", err)
} }
@ -190,7 +189,7 @@ func TestExporterShutdownHonorsCancel(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute) ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel() defer cancel()
e := otlp.NewUnstartedExporter(&stubProtocolDriver{}) e := otlp.NewUnstarted(&stubProtocolDriver{})
if err := e.Start(ctx); err != nil { if err := e.Start(ctx); err != nil {
t.Fatalf("failed to start exporter: %v", err) t.Fatalf("failed to start exporter: %v", err)
} }
@ -209,7 +208,7 @@ func TestExporterShutdownNoError(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute) ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel() defer cancel()
e := otlp.NewUnstartedExporter(&stubProtocolDriver{}) e := otlp.NewUnstarted(&stubProtocolDriver{})
if err := e.Start(ctx); err != nil { if err := e.Start(ctx); err != nil {
t.Fatalf("failed to start exporter: %v", err) t.Fatalf("failed to start exporter: %v", err)
} }
@ -221,7 +220,7 @@ func TestExporterShutdownNoError(t *testing.T) {
func TestExporterShutdownManyTimes(t *testing.T) { func TestExporterShutdownManyTimes(t *testing.T) {
ctx := context.Background() ctx := context.Background()
e, err := otlp.NewExporter(ctx, &stubProtocolDriver{}) e, err := otlp.New(ctx, &stubProtocolDriver{})
if err != nil { if err != nil {
t.Fatalf("failed to start an exporter: %v", err) t.Fatalf("failed to start an exporter: %v", err)
} }
@ -246,43 +245,6 @@ func TestExporterShutdownManyTimes(t *testing.T) {
} }
} }
func TestInstallNewPipeline(t *testing.T) {
ctx := context.Background()
_, _, _, err := otlp.InstallNewPipeline(ctx, &stubProtocolDriver{})
assert.NoError(t, err)
assert.IsType(t, &tracesdk.TracerProvider{}, otel.GetTracerProvider())
}
func TestNewExportPipeline(t *testing.T) {
testCases := []struct {
name string
expOpts []otlp.ExporterOption
testSpanSampling bool
}{
{
name: "simple pipeline",
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
_, tp, _, err := otlp.NewExportPipeline(
context.Background(),
&stubProtocolDriver{},
tc.expOpts...,
)
assert.NoError(t, err)
assert.NotEqual(t, tp, otel.GetTracerProvider())
_, span := tp.Tracer("otlp test").Start(context.Background(), tc.name)
spanCtx := span.SpanContext()
assert.Equal(t, true, spanCtx.IsSampled())
span.End()
})
}
}
func TestSplitDriver(t *testing.T) { func TestSplitDriver(t *testing.T) {
recordCount := 5 recordCount := 5

View File

@ -36,7 +36,7 @@ import (
func Example_insecure() { func Example_insecure() {
ctx := context.Background() ctx := context.Background()
driver := otlpgrpc.NewDriver(otlpgrpc.WithInsecure()) driver := otlpgrpc.NewDriver(otlpgrpc.WithInsecure())
exp, err := otlp.NewExporter(ctx, driver) exp, err := otlp.New(ctx, driver)
if err != nil { if err != nil {
log.Fatalf("Failed to create the collector exporter: %v", err) log.Fatalf("Failed to create the collector exporter: %v", err)
} }
@ -89,7 +89,7 @@ func Example_withTLS() {
ctx := context.Background() ctx := context.Background()
driver := otlpgrpc.NewDriver(otlpgrpc.WithTLSCredentials(creds)) driver := otlpgrpc.NewDriver(otlpgrpc.WithTLSCredentials(creds))
exp, err := otlp.NewExporter(ctx, driver) exp, err := otlp.New(ctx, driver)
if err != nil { if err != nil {
log.Fatalf("failed to create the collector exporter: %v", err) log.Fatalf("failed to create the collector exporter: %v", err)
} }
@ -145,7 +145,7 @@ func Example_withDifferentSignalCollectors() {
) )
driver := otlp.NewSplitDriver(otlp.WithMetricDriver(metricsDriver), otlp.WithTraceDriver(tracesDriver)) driver := otlp.NewSplitDriver(otlp.WithMetricDriver(metricsDriver), otlp.WithTraceDriver(tracesDriver))
ctx := context.Background() ctx := context.Background()
exp, err := otlp.NewExporter(ctx, driver) exp, err := otlp.New(ctx, driver)
if err != nil { if err != nil {
log.Fatalf("failed to create the collector exporter: %v", err) log.Fatalf("failed to create the collector exporter: %v", err)
} }

View File

@ -44,7 +44,7 @@ import (
var roSpans = tracetest.SpanStubs{{Name: "Span 0"}}.Snapshots() var roSpans = tracetest.SpanStubs{{Name: "Span 0"}}.Snapshots()
func TestNewExporter_endToEnd(t *testing.T) { func TestNew_endToEnd(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
additionalOpts []otlpgrpc.Option additionalOpts []otlpgrpc.Option
@ -88,7 +88,7 @@ func newGRPCExporter(t *testing.T, ctx context.Context, endpoint string, additio
opts = append(opts, additionalOpts...) opts = append(opts, additionalOpts...)
driver := otlpgrpc.NewDriver(opts...) driver := otlpgrpc.NewDriver(opts...)
exp, err := otlp.NewExporter(ctx, driver) exp, err := otlp.New(ctx, driver)
if err != nil { if err != nil {
t.Fatalf("failed to create a new collector exporter: %v", err) t.Fatalf("failed to create a new collector exporter: %v", err)
} }
@ -117,7 +117,7 @@ func newExporterEndToEndTest(t *testing.T, additionalOpts []otlpgrpc.Option) {
otlptest.RunEndToEndTest(ctx, t, exp, mc, mc) otlptest.RunEndToEndTest(ctx, t, exp, mc, mc)
} }
func TestNewExporter_invokeStartThenStopManyTimes(t *testing.T) { func TestNew_invokeStartThenStopManyTimes(t *testing.T) {
mc := runMockCollector(t) mc := runMockCollector(t)
defer func() { defer func() {
_ = mc.stop() _ = mc.stop()
@ -149,7 +149,7 @@ func TestNewExporter_invokeStartThenStopManyTimes(t *testing.T) {
} }
} }
func TestNewExporter_collectorConnectionDiesThenReconnectsWhenInRestMode(t *testing.T) { func TestNew_collectorConnectionDiesThenReconnectsWhenInRestMode(t *testing.T) {
mc := runMockCollector(t) mc := runMockCollector(t)
reconnectionPeriod := 20 * time.Millisecond reconnectionPeriod := 20 * time.Millisecond
@ -473,7 +473,7 @@ func newThrottlingError(code codes.Code, duration time.Duration) error {
return s.Err() return s.Err()
} }
func TestNewExporter_collectorConnectionDiesThenReconnects(t *testing.T) { func TestNew_collectorConnectionDiesThenReconnects(t *testing.T) {
mc := runMockCollector(t) mc := runMockCollector(t)
reconnectionPeriod := 50 * time.Millisecond reconnectionPeriod := 50 * time.Millisecond
@ -527,7 +527,7 @@ func TestNewExporter_collectorConnectionDiesThenReconnects(t *testing.T) {
} }
// This test takes a long time to run: to skip it, run tests using: -short // This test takes a long time to run: to skip it, run tests using: -short
func TestNewExporter_collectorOnBadConnection(t *testing.T) { func TestNew_collectorOnBadConnection(t *testing.T) {
if testing.Short() { if testing.Short() {
t.Skipf("Skipping this long running test") t.Skipf("Skipping this long running test")
} }
@ -548,7 +548,7 @@ func TestNewExporter_collectorOnBadConnection(t *testing.T) {
_ = exp.Shutdown(ctx) _ = exp.Shutdown(ctx)
} }
func TestNewExporter_withEndpoint(t *testing.T) { func TestNew_withEndpoint(t *testing.T) {
mc := runMockCollector(t) mc := runMockCollector(t)
defer func() { defer func() {
_ = mc.stop() _ = mc.stop()
@ -559,7 +559,7 @@ func TestNewExporter_withEndpoint(t *testing.T) {
_ = exp.Shutdown(ctx) _ = exp.Shutdown(ctx)
} }
func TestNewExporter_withHeaders(t *testing.T) { func TestNew_withHeaders(t *testing.T) {
mc := runMockCollector(t) mc := runMockCollector(t)
defer func() { defer func() {
_ = mc.stop() _ = mc.stop()
@ -579,7 +579,7 @@ func TestNewExporter_withHeaders(t *testing.T) {
assert.Equal(t, "value1", headers.Get("header1")[0]) assert.Equal(t, "value1", headers.Get("header1")[0])
} }
func TestNewExporter_WithTimeout(t *testing.T) { func TestNew_WithTimeout(t *testing.T) {
tts := []struct { tts := []struct {
name string name string
fn func(exp *otlp.Exporter) error fn func(exp *otlp.Exporter) error
@ -663,7 +663,7 @@ func TestNewExporter_WithTimeout(t *testing.T) {
} }
} }
func TestNewExporter_withInvalidSecurityConfiguration(t *testing.T) { func TestNew_withInvalidSecurityConfiguration(t *testing.T) {
mc := runMockCollector(t) mc := runMockCollector(t)
defer func() { defer func() {
_ = mc.stop() _ = mc.stop()
@ -671,7 +671,7 @@ func TestNewExporter_withInvalidSecurityConfiguration(t *testing.T) {
ctx := context.Background() ctx := context.Background()
driver := otlpgrpc.NewDriver(otlpgrpc.WithEndpoint(mc.endpoint)) driver := otlpgrpc.NewDriver(otlpgrpc.WithEndpoint(mc.endpoint))
exp, err := otlp.NewExporter(ctx, driver) exp, err := otlp.New(ctx, driver)
if err != nil { if err != nil {
t.Fatalf("failed to create a new collector exporter: %v", err) t.Fatalf("failed to create a new collector exporter: %v", err)
} }
@ -688,7 +688,7 @@ func TestNewExporter_withInvalidSecurityConfiguration(t *testing.T) {
}() }()
} }
func TestNewExporter_withMultipleAttributeTypes(t *testing.T) { func TestNew_withMultipleAttributeTypes(t *testing.T) {
mc := runMockCollector(t) mc := runMockCollector(t)
defer func() { defer func() {
@ -903,7 +903,7 @@ func TestMultiConnectionDriver(t *testing.T) {
metricsDriver := otlpgrpc.NewDriver(optsMetrics...) metricsDriver := otlpgrpc.NewDriver(optsMetrics...)
driver := otlp.NewSplitDriver(otlp.WithMetricDriver(metricsDriver), otlp.WithTraceDriver(tracesDriver)) driver := otlp.NewSplitDriver(otlp.WithMetricDriver(metricsDriver), otlp.WithTraceDriver(tracesDriver))
ctx := context.Background() ctx := context.Background()
exp, err := otlp.NewExporter(ctx, driver) exp, err := otlp.New(ctx, driver)
if err != nil { if err != nil {
t.Fatalf("failed to create a new collector exporter: %v", err) t.Fatalf("failed to create a new collector exporter: %v", err)
} }

View File

@ -132,7 +132,7 @@ func TestEndToEnd(t *testing.T) {
allOpts = append(allOpts, tc.opts...) allOpts = append(allOpts, tc.opts...)
driver := otlphttp.NewDriver(allOpts...) driver := otlphttp.NewDriver(allOpts...)
ctx := context.Background() ctx := context.Background()
exporter, err := otlp.NewExporter(ctx, driver) exporter, err := otlp.New(ctx, driver)
if assert.NoError(t, err) { if assert.NoError(t, err) {
defer func() { defer func() {
assert.NoError(t, exporter.Shutdown(ctx)) assert.NoError(t, exporter.Shutdown(ctx))
@ -160,7 +160,7 @@ func TestRetry(t *testing.T) {
otlphttp.WithMaxAttempts(len(statuses)+1), otlphttp.WithMaxAttempts(len(statuses)+1),
) )
ctx := context.Background() ctx := context.Background()
exporter, err := otlp.NewExporter(ctx, driver) exporter, err := otlp.New(ctx, driver)
require.NoError(t, err) require.NoError(t, err)
defer func() { defer func() {
assert.NoError(t, exporter.Shutdown(ctx)) assert.NoError(t, exporter.Shutdown(ctx))
@ -182,7 +182,7 @@ func TestTimeout(t *testing.T) {
otlphttp.WithTimeout(time.Nanosecond), otlphttp.WithTimeout(time.Nanosecond),
) )
ctx := context.Background() ctx := context.Background()
exporter, err := otlp.NewExporter(ctx, driver) exporter, err := otlp.New(ctx, driver)
require.NoError(t, err) require.NoError(t, err)
defer func() { defer func() {
assert.NoError(t, exporter.Shutdown(ctx)) assert.NoError(t, exporter.Shutdown(ctx))
@ -207,7 +207,7 @@ func TestRetryFailed(t *testing.T) {
otlphttp.WithMaxAttempts(1), otlphttp.WithMaxAttempts(1),
) )
ctx := context.Background() ctx := context.Background()
exporter, err := otlp.NewExporter(ctx, driver) exporter, err := otlp.New(ctx, driver)
require.NoError(t, err) require.NoError(t, err)
defer func() { defer func() {
assert.NoError(t, exporter.Shutdown(ctx)) assert.NoError(t, exporter.Shutdown(ctx))
@ -232,7 +232,7 @@ func TestNoRetry(t *testing.T) {
otlphttp.WithMaxAttempts(len(statuses)+1), otlphttp.WithMaxAttempts(len(statuses)+1),
) )
ctx := context.Background() ctx := context.Background()
exporter, err := otlp.NewExporter(ctx, driver) exporter, err := otlp.New(ctx, driver)
require.NoError(t, err) require.NoError(t, err)
defer func() { defer func() {
assert.NoError(t, exporter.Shutdown(ctx)) assert.NoError(t, exporter.Shutdown(ctx))
@ -252,7 +252,7 @@ func TestFailedCheckpoint(t *testing.T) {
otlphttp.WithInsecure(), otlphttp.WithInsecure(),
) )
ctx := context.Background() ctx := context.Background()
exporter, err := otlp.NewExporter(ctx, driver) exporter, err := otlp.New(ctx, driver)
require.NoError(t, err) require.NoError(t, err)
defer func() { defer func() {
assert.NoError(t, exporter.Shutdown(ctx)) assert.NoError(t, exporter.Shutdown(ctx))
@ -271,7 +271,7 @@ func TestEmptyData(t *testing.T) {
otlphttp.WithInsecure(), otlphttp.WithInsecure(),
) )
ctx := context.Background() ctx := context.Background()
exporter, err := otlp.NewExporter(ctx, driver) exporter, err := otlp.New(ctx, driver)
require.NoError(t, err) require.NoError(t, err)
defer func() { defer func() {
assert.NoError(t, exporter.Shutdown(ctx)) assert.NoError(t, exporter.Shutdown(ctx))
@ -320,7 +320,7 @@ func TestUnreasonableMaxAttempts(t *testing.T) {
otlphttp.WithBackoff(time.Millisecond), otlphttp.WithBackoff(time.Millisecond),
) )
ctx := context.Background() ctx := context.Background()
exporter, err := otlp.NewExporter(ctx, driver) exporter, err := otlp.New(ctx, driver)
require.NoError(t, err) require.NoError(t, err)
defer func() { defer func() {
assert.NoError(t, exporter.Shutdown(ctx)) assert.NoError(t, exporter.Shutdown(ctx))
@ -356,7 +356,7 @@ func TestUnreasonableBackoff(t *testing.T) {
) )
ctx, cancel := context.WithTimeout(context.Background(), 3*otlphttp.DefaultBackoff) ctx, cancel := context.WithTimeout(context.Background(), 3*otlphttp.DefaultBackoff)
defer cancel() defer cancel()
exporter, err := otlp.NewExporter(ctx, driver) exporter, err := otlp.New(ctx, driver)
require.NoError(t, err) require.NoError(t, err)
defer func() { defer func() {
assert.NoError(t, exporter.Shutdown(ctx)) assert.NoError(t, exporter.Shutdown(ctx))
@ -375,7 +375,7 @@ func TestCancelledContext(t *testing.T) {
otlphttp.WithInsecure(), otlphttp.WithInsecure(),
) )
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
exporter, err := otlp.NewExporter(ctx, driver) exporter, err := otlp.New(ctx, driver)
require.NoError(t, err) require.NoError(t, err)
defer func() { defer func() {
assert.NoError(t, exporter.Shutdown(ctx)) assert.NoError(t, exporter.Shutdown(ctx))
@ -402,7 +402,7 @@ func TestDeadlineContext(t *testing.T) {
otlphttp.WithBackoff(time.Minute), otlphttp.WithBackoff(time.Minute),
) )
ctx := context.Background() ctx := context.Background()
exporter, err := otlp.NewExporter(ctx, driver) exporter, err := otlp.New(ctx, driver)
require.NoError(t, err) require.NoError(t, err)
defer func() { defer func() {
assert.NoError(t, exporter.Shutdown(ctx)) assert.NoError(t, exporter.Shutdown(ctx))
@ -430,7 +430,7 @@ func TestStopWhileExporting(t *testing.T) {
otlphttp.WithBackoff(time.Minute), otlphttp.WithBackoff(time.Minute),
) )
ctx := context.Background() ctx := context.Background()
exporter, err := otlp.NewExporter(ctx, driver) exporter, err := otlp.New(ctx, driver)
require.NoError(t, err) require.NoError(t, err)
defer func() { defer func() {
assert.NoError(t, exporter.Shutdown(ctx)) assert.NoError(t, exporter.Shutdown(ctx))

View File

@ -21,7 +21,6 @@ import (
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform" "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform"
"go.opentelemetry.io/otel"
tracesdk "go.opentelemetry.io/otel/sdk/trace" tracesdk "go.opentelemetry.io/otel/sdk/trace"
) )
@ -87,45 +86,18 @@ func (e *Exporter) Shutdown(ctx context.Context) error {
var _ tracesdk.SpanExporter = (*Exporter)(nil) var _ tracesdk.SpanExporter = (*Exporter)(nil)
// NewExporter constructs a new Exporter and starts it. // New constructs a new Exporter and starts it.
func NewExporter(ctx context.Context, client Client) (*Exporter, error) { func New(ctx context.Context, client Client) (*Exporter, error) {
exp := NewUnstartedExporter(client) exp := NewUnstarted(client)
if err := exp.Start(ctx); err != nil { if err := exp.Start(ctx); err != nil {
return nil, err return nil, err
} }
return exp, nil return exp, nil
} }
// NewUnstartedExporter constructs a new Exporter and does not start it. // NewUnstarted constructs a new Exporter and does not start it.
func NewUnstartedExporter(client Client) *Exporter { func NewUnstarted(client Client) *Exporter {
return &Exporter{ return &Exporter{
client: client, client: client,
} }
} }
// NewExportPipeline sets up a complete export pipeline
// with the recommended TracerProvider setup.
func NewExportPipeline(ctx context.Context, client Client) (*Exporter, *tracesdk.TracerProvider, error) {
exp, err := NewExporter(ctx, client)
if err != nil {
return nil, nil, err
}
tracerProvider := tracesdk.NewTracerProvider(
tracesdk.WithBatcher(exp),
)
return exp, tracerProvider, nil
}
// InstallNewPipeline instantiates a NewExportPipeline with the
// recommended configuration and registers it globally.
func InstallNewPipeline(ctx context.Context, client Client) (*Exporter, *tracesdk.TracerProvider, error) {
exp, tp, err := NewExportPipeline(ctx, client)
if err != nil {
return nil, nil, err
}
otel.SetTracerProvider(tp)
return exp, tp, err
}

View File

@ -1,66 +0,0 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package otlptrace_test
import (
"context"
"testing"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace"
"github.com/stretchr/testify/assert"
"go.opentelemetry.io/otel"
tracesdk "go.opentelemetry.io/otel/sdk/trace"
tracepb "go.opentelemetry.io/proto/otlp/trace/v1"
)
type noopClient struct {
}
var _ otlptrace.Client = (*noopClient)(nil)
func (m *noopClient) Start(_ context.Context) error {
return nil
}
func (m *noopClient) Stop(ctx context.Context) error {
select {
case <-ctx.Done():
return ctx.Err()
default:
}
return nil
}
func (m *noopClient) UploadTraces(_ context.Context, _ []*tracepb.ResourceSpans) error {
return nil
}
func (m *noopClient) Reset() {
}
func TestInstallNewPipeline(t *testing.T) {
ctx := context.Background()
_, _, err := otlptrace.InstallNewPipeline(ctx, &noopClient{})
assert.NoError(t, err)
assert.IsType(t, &tracesdk.TracerProvider{}, otel.GetTracerProvider())
}
func TestNewExportPipeline(t *testing.T) {
_, tp, err := otlptrace.NewExportPipeline(context.Background(), &noopClient{})
assert.NoError(t, err)
assert.NotEqual(t, tp, otel.GetTracerProvider())
}

View File

@ -46,7 +46,7 @@ func initializeExporter(t *testing.T, client otlptrace.Client) *otlptrace.Export
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute) ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel() defer cancel()
e, err := otlptrace.NewExporter(ctx, client) e, err := otlptrace.New(ctx, client)
if err != nil { if err != nil {
t.Fatalf("failed to create exporter") t.Fatalf("failed to create exporter")
} }

View File

@ -44,7 +44,7 @@ import (
var roSpans = tracetest.SpanStubs{{Name: "Span 0"}}.Snapshots() var roSpans = tracetest.SpanStubs{{Name: "Span 0"}}.Snapshots()
func TestNewExporter_endToEnd(t *testing.T) { func TestNew_endToEnd(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
additionalOpts []otlptracegrpc.Option additionalOpts []otlptracegrpc.Option
@ -88,7 +88,7 @@ func newGRPCExporter(t *testing.T, ctx context.Context, endpoint string, additio
opts = append(opts, additionalOpts...) opts = append(opts, additionalOpts...)
client := otlptracegrpc.NewClient(opts...) client := otlptracegrpc.NewClient(opts...)
exp, err := otlptrace.NewExporter(ctx, client) exp, err := otlptrace.New(ctx, client)
if err != nil { if err != nil {
t.Fatalf("failed to create a new collector exporter: %v", err) t.Fatalf("failed to create a new collector exporter: %v", err)
} }
@ -133,7 +133,7 @@ func TestExporterShutdown(t *testing.T) {
}) })
} }
func TestNewExporter_invokeStartThenStopManyTimes(t *testing.T) { func TestNew_invokeStartThenStopManyTimes(t *testing.T) {
mc := runMockCollector(t) mc := runMockCollector(t)
defer func() { defer func() {
_ = mc.stop() _ = mc.stop()
@ -165,7 +165,7 @@ func TestNewExporter_invokeStartThenStopManyTimes(t *testing.T) {
} }
} }
func TestNewExporter_collectorConnectionDiesThenReconnectsWhenInRestMode(t *testing.T) { func TestNew_collectorConnectionDiesThenReconnectsWhenInRestMode(t *testing.T) {
mc := runMockCollector(t) mc := runMockCollector(t)
reconnectionPeriod := 20 * time.Millisecond reconnectionPeriod := 20 * time.Millisecond
@ -489,7 +489,7 @@ func newThrottlingError(code codes.Code, duration time.Duration) error {
return s.Err() return s.Err()
} }
func TestNewExporter_collectorConnectionDiesThenReconnects(t *testing.T) { func TestNew_collectorConnectionDiesThenReconnects(t *testing.T) {
mc := runMockCollector(t) mc := runMockCollector(t)
reconnectionPeriod := 50 * time.Millisecond reconnectionPeriod := 50 * time.Millisecond
@ -543,7 +543,7 @@ func TestNewExporter_collectorConnectionDiesThenReconnects(t *testing.T) {
} }
// This test takes a long time to run: to skip it, run tests using: -short // This test takes a long time to run: to skip it, run tests using: -short
func TestNewExporter_collectorOnBadConnection(t *testing.T) { func TestNew_collectorOnBadConnection(t *testing.T) {
if testing.Short() { if testing.Short() {
t.Skipf("Skipping this long running test") t.Skipf("Skipping this long running test")
} }
@ -564,7 +564,7 @@ func TestNewExporter_collectorOnBadConnection(t *testing.T) {
_ = exp.Shutdown(ctx) _ = exp.Shutdown(ctx)
} }
func TestNewExporter_withEndpoint(t *testing.T) { func TestNew_withEndpoint(t *testing.T) {
mc := runMockCollector(t) mc := runMockCollector(t)
defer func() { defer func() {
_ = mc.stop() _ = mc.stop()
@ -575,7 +575,7 @@ func TestNewExporter_withEndpoint(t *testing.T) {
_ = exp.Shutdown(ctx) _ = exp.Shutdown(ctx)
} }
func TestNewExporter_withHeaders(t *testing.T) { func TestNew_withHeaders(t *testing.T) {
mc := runMockCollector(t) mc := runMockCollector(t)
defer func() { defer func() {
_ = mc.stop() _ = mc.stop()
@ -595,7 +595,7 @@ func TestNewExporter_withHeaders(t *testing.T) {
assert.Equal(t, "value1", headers.Get("header1")[0]) assert.Equal(t, "value1", headers.Get("header1")[0])
} }
func TestNewExporter_WithTimeout(t *testing.T) { func TestNew_WithTimeout(t *testing.T) {
tts := []struct { tts := []struct {
name string name string
fn func(exp *otlptrace.Exporter) error fn func(exp *otlptrace.Exporter) error
@ -658,7 +658,7 @@ func TestNewExporter_WithTimeout(t *testing.T) {
} }
} }
func TestNewExporter_withInvalidSecurityConfiguration(t *testing.T) { func TestNew_withInvalidSecurityConfiguration(t *testing.T) {
mc := runMockCollector(t) mc := runMockCollector(t)
defer func() { defer func() {
_ = mc.stop() _ = mc.stop()
@ -666,7 +666,7 @@ func TestNewExporter_withInvalidSecurityConfiguration(t *testing.T) {
ctx := context.Background() ctx := context.Background()
driver := otlptracegrpc.NewClient(otlptracegrpc.WithEndpoint(mc.endpoint)) driver := otlptracegrpc.NewClient(otlptracegrpc.WithEndpoint(mc.endpoint))
exp, err := otlptrace.NewExporter(ctx, driver) exp, err := otlptrace.New(ctx, driver)
if err != nil { if err != nil {
t.Fatalf("failed to create a new collector exporter: %v", err) t.Fatalf("failed to create a new collector exporter: %v", err)
} }
@ -683,7 +683,7 @@ func TestNewExporter_withInvalidSecurityConfiguration(t *testing.T) {
}() }()
} }
func TestNewExporter_withMultipleAttributeTypes(t *testing.T) { func TestNew_withMultipleAttributeTypes(t *testing.T) {
mc := runMockCollector(t) mc := runMockCollector(t)
defer func() { defer func() {

View File

@ -18,27 +18,14 @@ import (
"context" "context"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace" "go.opentelemetry.io/otel/exporters/otlp/otlptrace"
tracesdk "go.opentelemetry.io/otel/sdk/trace"
) )
// NewExporter constructs a new Exporter and starts it. // New constructs a new Exporter and starts it.
func NewExporter(ctx context.Context, opts ...Option) (*otlptrace.Exporter, error) { func New(ctx context.Context, opts ...Option) (*otlptrace.Exporter, error) {
return otlptrace.NewExporter(ctx, NewClient(opts...)) return otlptrace.New(ctx, NewClient(opts...))
} }
// NewUnstartedExporter constructs a new Exporter and does not start it. // NewUnstarted constructs a new Exporter and does not start it.
func NewUnstartedExporter(opts ...Option) *otlptrace.Exporter { func NewUnstarted(opts ...Option) *otlptrace.Exporter {
return otlptrace.NewUnstartedExporter(NewClient(opts...)) return otlptrace.NewUnstarted(NewClient(opts...))
}
// NewExportPipeline sets up a complete export pipeline
// with the recommended TracerProvider setup.
func NewExportPipeline(ctx context.Context, opts ...Option) (*otlptrace.Exporter, *tracesdk.TracerProvider, error) {
return otlptrace.NewExportPipeline(ctx, NewClient(opts...))
}
// InstallNewPipeline instantiates a NewExportPipeline with the
// recommended configuration and registers it globally.
func InstallNewPipeline(ctx context.Context, opts ...Option) (*otlptrace.Exporter, *tracesdk.TracerProvider, error) {
return otlptrace.InstallNewPipeline(ctx, NewClient(opts...))
} }

View File

@ -111,7 +111,7 @@ func TestEndToEnd(t *testing.T) {
allOpts = append(allOpts, tc.opts...) allOpts = append(allOpts, tc.opts...)
client := otlptracehttp.NewClient(allOpts...) client := otlptracehttp.NewClient(allOpts...)
ctx := context.Background() ctx := context.Background()
exporter, err := otlptrace.NewExporter(ctx, client) exporter, err := otlptrace.New(ctx, client)
if assert.NoError(t, err) { if assert.NoError(t, err) {
defer func() { defer func() {
assert.NoError(t, exporter.Shutdown(ctx)) assert.NoError(t, exporter.Shutdown(ctx))
@ -154,7 +154,7 @@ func TestRetry(t *testing.T) {
otlptracehttp.WithMaxAttempts(len(statuses)+1), otlptracehttp.WithMaxAttempts(len(statuses)+1),
) )
ctx := context.Background() ctx := context.Background()
exporter, err := otlptrace.NewExporter(ctx, client) exporter, err := otlptrace.New(ctx, client)
require.NoError(t, err) require.NoError(t, err)
defer func() { defer func() {
assert.NoError(t, exporter.Shutdown(ctx)) assert.NoError(t, exporter.Shutdown(ctx))
@ -176,7 +176,7 @@ func TestTimeout(t *testing.T) {
otlptracehttp.WithTimeout(50*time.Millisecond), otlptracehttp.WithTimeout(50*time.Millisecond),
) )
ctx := context.Background() ctx := context.Background()
exporter, err := otlptrace.NewExporter(ctx, client) exporter, err := otlptrace.New(ctx, client)
require.NoError(t, err) require.NoError(t, err)
defer func() { defer func() {
assert.NoError(t, exporter.Shutdown(ctx)) assert.NoError(t, exporter.Shutdown(ctx))
@ -201,7 +201,7 @@ func TestRetryFailed(t *testing.T) {
otlptracehttp.WithMaxAttempts(1), otlptracehttp.WithMaxAttempts(1),
) )
ctx := context.Background() ctx := context.Background()
exporter, err := otlptrace.NewExporter(ctx, driver) exporter, err := otlptrace.New(ctx, driver)
require.NoError(t, err) require.NoError(t, err)
defer func() { defer func() {
assert.NoError(t, exporter.Shutdown(ctx)) assert.NoError(t, exporter.Shutdown(ctx))
@ -226,7 +226,7 @@ func TestNoRetry(t *testing.T) {
otlptracehttp.WithMaxAttempts(len(statuses)+1), otlptracehttp.WithMaxAttempts(len(statuses)+1),
) )
ctx := context.Background() ctx := context.Background()
exporter, err := otlptrace.NewExporter(ctx, driver) exporter, err := otlptrace.New(ctx, driver)
require.NoError(t, err) require.NoError(t, err)
defer func() { defer func() {
assert.NoError(t, exporter.Shutdown(ctx)) assert.NoError(t, exporter.Shutdown(ctx))
@ -246,7 +246,7 @@ func TestEmptyData(t *testing.T) {
otlptracehttp.WithInsecure(), otlptracehttp.WithInsecure(),
) )
ctx := context.Background() ctx := context.Background()
exporter, err := otlptrace.NewExporter(ctx, driver) exporter, err := otlptrace.New(ctx, driver)
require.NoError(t, err) require.NoError(t, err)
defer func() { defer func() {
assert.NoError(t, exporter.Shutdown(ctx)) assert.NoError(t, exporter.Shutdown(ctx))
@ -293,7 +293,7 @@ func TestUnreasonableMaxAttempts(t *testing.T) {
otlptracehttp.WithBackoff(time.Millisecond), otlptracehttp.WithBackoff(time.Millisecond),
) )
ctx := context.Background() ctx := context.Background()
exporter, err := otlptrace.NewExporter(ctx, driver) exporter, err := otlptrace.New(ctx, driver)
require.NoError(t, err) require.NoError(t, err)
defer func() { defer func() {
assert.NoError(t, exporter.Shutdown(ctx)) assert.NoError(t, exporter.Shutdown(ctx))
@ -329,7 +329,7 @@ func TestUnreasonableBackoff(t *testing.T) {
) )
ctx, cancel := context.WithTimeout(context.Background(), 3*(300*time.Millisecond)) ctx, cancel := context.WithTimeout(context.Background(), 3*(300*time.Millisecond))
defer cancel() defer cancel()
exporter, err := otlptrace.NewExporter(ctx, driver) exporter, err := otlptrace.New(ctx, driver)
require.NoError(t, err) require.NoError(t, err)
defer func() { defer func() {
assert.NoError(t, exporter.Shutdown(context.Background())) assert.NoError(t, exporter.Shutdown(context.Background()))
@ -348,7 +348,7 @@ func TestCancelledContext(t *testing.T) {
otlptracehttp.WithInsecure(), otlptracehttp.WithInsecure(),
) )
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
exporter, err := otlptrace.NewExporter(ctx, driver) exporter, err := otlptrace.New(ctx, driver)
require.NoError(t, err) require.NoError(t, err)
defer func() { defer func() {
assert.NoError(t, exporter.Shutdown(context.Background())) assert.NoError(t, exporter.Shutdown(context.Background()))
@ -375,7 +375,7 @@ func TestDeadlineContext(t *testing.T) {
otlptracehttp.WithBackoff(time.Minute), otlptracehttp.WithBackoff(time.Minute),
) )
ctx := context.Background() ctx := context.Background()
exporter, err := otlptrace.NewExporter(ctx, driver) exporter, err := otlptrace.New(ctx, driver)
require.NoError(t, err) require.NoError(t, err)
defer func() { defer func() {
assert.NoError(t, exporter.Shutdown(context.Background())) assert.NoError(t, exporter.Shutdown(context.Background()))
@ -403,7 +403,7 @@ func TestStopWhileExporting(t *testing.T) {
otlptracehttp.WithBackoff(time.Minute), otlptracehttp.WithBackoff(time.Minute),
) )
ctx := context.Background() ctx := context.Background()
exporter, err := otlptrace.NewExporter(ctx, driver) exporter, err := otlptrace.New(ctx, driver)
require.NoError(t, err) require.NoError(t, err)
defer func() { defer func() {
assert.NoError(t, exporter.Shutdown(ctx)) assert.NoError(t, exporter.Shutdown(ctx))

View File

@ -18,27 +18,14 @@ import (
"context" "context"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace" "go.opentelemetry.io/otel/exporters/otlp/otlptrace"
tracesdk "go.opentelemetry.io/otel/sdk/trace"
) )
// NewExporter constructs a new Exporter and starts it. // New constructs a new Exporter and starts it.
func NewExporter(ctx context.Context, opts ...Option) (*otlptrace.Exporter, error) { func New(ctx context.Context, opts ...Option) (*otlptrace.Exporter, error) {
return otlptrace.NewExporter(ctx, NewClient(opts...)) return otlptrace.New(ctx, NewClient(opts...))
} }
// NewUnstartedExporter constructs a new Exporter and does not start it. // NewUnstarted constructs a new Exporter and does not start it.
func NewUnstartedExporter(opts ...Option) *otlptrace.Exporter { func NewUnstarted(opts ...Option) *otlptrace.Exporter {
return otlptrace.NewUnstartedExporter(NewClient(opts...)) return otlptrace.NewUnstarted(NewClient(opts...))
}
// NewExportPipeline sets up a complete export pipeline
// with the recommended TracerProvider setup.
func NewExportPipeline(ctx context.Context, opts ...Option) (*otlptrace.Exporter, *tracesdk.TracerProvider, error) {
return otlptrace.NewExportPipeline(ctx, NewClient(opts...))
}
// InstallNewPipeline instantiates a NewExportPipeline with the
// recommended configuration and registers it globally.
func InstallNewPipeline(ctx context.Context, opts ...Option) (*otlptrace.Exporter, *tracesdk.TracerProvider, error) {
return otlptrace.InstallNewPipeline(ctx, NewClient(opts...))
} }

View File

@ -6,7 +6,6 @@ require (
github.com/stretchr/testify v1.7.0 github.com/stretchr/testify v1.7.0
go.opentelemetry.io/otel v0.20.0 go.opentelemetry.io/otel v0.20.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace v0.0.0-00010101000000-000000000000 go.opentelemetry.io/otel/exporters/otlp/otlptrace v0.0.0-00010101000000-000000000000
go.opentelemetry.io/otel/sdk v0.20.0
go.opentelemetry.io/proto/otlp v0.9.0 go.opentelemetry.io/proto/otlp v0.9.0
google.golang.org/protobuf v1.26.0 google.golang.org/protobuf v1.26.0
) )

View File

@ -23,6 +23,12 @@ import (
"go.opentelemetry.io/otel/exporters/stdout" "go.opentelemetry.io/otel/exporters/stdout"
"go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/global" "go.opentelemetry.io/otel/metric/global"
controller "go.opentelemetry.io/otel/sdk/metric/controller/basic"
processor "go.opentelemetry.io/otel/sdk/metric/processor/basic"
"go.opentelemetry.io/otel/sdk/metric/selector/simple"
"go.opentelemetry.io/otel/sdk/resource"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
"go.opentelemetry.io/otel/semconv"
"go.opentelemetry.io/otel/trace" "go.opentelemetry.io/otel/trace"
) )
@ -77,23 +83,54 @@ func multiply(ctx context.Context, x, y int64) int64 {
return x * y return x * y
} }
func Example() { func Resource() *resource.Resource {
exportOpts := []stdout.Option{ return resource.NewWithAttributes(
stdout.WithPrettyPrint(), semconv.SchemaURL,
} semconv.ServiceNameKey.String("stdout-example"),
// Registers both a trace and meter Provider globally. semconv.ServiceVersionKey.String("0.0.1"),
tracerProvider, pusher, err := stdout.InstallNewPipeline(exportOpts, nil) )
}
func InstallExportPipeline(ctx context.Context) func() {
exporter, err := stdout.New(stdout.WithPrettyPrint())
if err != nil { if err != nil {
log.Fatal("Could not initialize stdout exporter:", err) log.Fatalf("creating stdout exporter: %v", err)
} }
ctx := context.Background()
log.Println("the answer is", add(ctx, multiply(ctx, multiply(ctx, 2, 2), 10), 2)) tracerProvider := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exporter),
sdktrace.WithResource(Resource()),
)
otel.SetTracerProvider(tracerProvider)
pusher := controller.New(
processor.New(
simple.NewWithInexpensiveDistribution(),
exporter,
),
controller.WithExporter(exporter),
)
if err = pusher.Start(ctx); err != nil {
log.Fatalf("starting push controller: %v", err)
}
global.SetMeterProvider(pusher.MeterProvider())
return func() {
if err := pusher.Stop(ctx); err != nil { if err := pusher.Stop(ctx); err != nil {
log.Fatal("Could not stop stdout exporter:", err) log.Fatalf("stopping push controller: %v", err)
} }
if err := tracerProvider.Shutdown(ctx); err != nil { if err := tracerProvider.Shutdown(ctx); err != nil {
log.Fatal("Could not stop stdout tracer:", err) log.Fatalf("stopping tracer provider: %v", err)
}
} }
} }
func Example() {
ctx := context.Background()
// Registers both a tracer and meter Provider globally.
cleanup := InstallExportPipeline(ctx)
defer cleanup()
log.Println("the answer is", add(ctx, multiply(ctx, multiply(ctx, 2, 2), 10), 2))
}

View File

@ -15,14 +15,7 @@
package stdout // import "go.opentelemetry.io/otel/exporters/stdout" package stdout // import "go.opentelemetry.io/otel/exporters/stdout"
import ( import (
"context"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/metric/global"
"go.opentelemetry.io/otel/sdk/export/metric" "go.opentelemetry.io/otel/sdk/export/metric"
controller "go.opentelemetry.io/otel/sdk/metric/controller/basic"
processor "go.opentelemetry.io/otel/sdk/metric/processor/basic"
"go.opentelemetry.io/otel/sdk/metric/selector/simple"
sdktrace "go.opentelemetry.io/otel/sdk/trace" sdktrace "go.opentelemetry.io/otel/sdk/trace"
) )
@ -36,8 +29,8 @@ var (
_ sdktrace.SpanExporter = &Exporter{} _ sdktrace.SpanExporter = &Exporter{}
) )
// NewExporter creates an Exporter with the passed options. // New creates an Exporter with the passed options.
func NewExporter(options ...Option) (*Exporter, error) { func New(options ...Option) (*Exporter, error) {
cfg, err := newConfig(options...) cfg, err := newConfig(options...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -47,50 +40,3 @@ func NewExporter(options ...Option) (*Exporter, error) {
metricExporter: metricExporter{cfg}, metricExporter: metricExporter{cfg},
}, nil }, nil
} }
// NewExportPipeline creates a complete export pipeline with the default
// selectors, processors, and trace registration. It is the responsibility
// of the caller to stop the returned tracer provider and push Controller.
func NewExportPipeline(exportOpts []Option, pushOpts []controller.Option) (*sdktrace.TracerProvider, *controller.Controller, error) {
exporter, err := NewExporter(exportOpts...)
if err != nil {
return nil, nil, err
}
tp := sdktrace.NewTracerProvider(sdktrace.WithBatcher(exporter))
pusher := controller.New(
processor.New(
simple.NewWithInexpensiveDistribution(),
exporter,
),
append(
pushOpts,
controller.WithExporter(exporter),
)...,
)
err = pusher.Start(context.Background())
return tp, pusher, err
}
// InstallNewPipeline creates a complete export pipelines with defaults and
// registers it globally. It is the responsibility of the caller to stop the
// returned tracer provider and push Controller.
//
// Typically this is called as:
//
// pipeline, err := stdout.InstallNewPipeline(stdout.Config{...})
// if err != nil {
// ...
// }
// defer pipeline.Stop()
// ... Done
func InstallNewPipeline(exportOpts []Option, pushOpts []controller.Option) (*sdktrace.TracerProvider, *controller.Controller, error) {
tracerProvider, controller, err := NewExportPipeline(exportOpts, pushOpts)
if err != nil {
return tracerProvider, controller, err
}
otel.SetTracerProvider(tracerProvider)
global.SetMeterProvider(controller.MeterProvider())
return tracerProvider, controller, err
}

View File

@ -52,7 +52,7 @@ func newFixture(t *testing.T, opts ...stdout.Option) testFixture {
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
opts = append(opts, stdout.WithWriter(buf)) opts = append(opts, stdout.WithWriter(buf))
opts = append(opts, stdout.WithoutTimestamps()) opts = append(opts, stdout.WithoutTimestamps())
exp, err := stdout.NewExporter(opts...) exp, err := stdout.New(opts...)
if err != nil { if err != nil {
t.Fatal("Error building fixture: ", err) t.Fatal("Error building fixture: ", err)
} }
@ -77,7 +77,7 @@ func (fix testFixture) Export(checkpointSet export.CheckpointSet) {
func TestStdoutTimestamp(t *testing.T) { func TestStdoutTimestamp(t *testing.T) {
var buf bytes.Buffer var buf bytes.Buffer
exporter, err := stdout.NewExporter( exporter, err := stdout.New(
stdout.WithWriter(&buf), stdout.WithWriter(&buf),
) )
if err != nil { if err != nil {

View File

@ -37,7 +37,7 @@ import (
func TestExporter_ExportSpan(t *testing.T) { func TestExporter_ExportSpan(t *testing.T) {
// write to buffer for testing // write to buffer for testing
var b bytes.Buffer var b bytes.Buffer
ex, err := stdout.NewExporter(stdout.WithWriter(&b), stdout.WithPrettyPrint()) ex, err := stdout.New(stdout.WithWriter(&b), stdout.WithPrettyPrint())
if err != nil { if err != nil {
t.Errorf("Error constructing stdout exporter %s", err) t.Errorf("Error constructing stdout exporter %s", err)
} }
@ -183,7 +183,7 @@ func TestExporterShutdownHonorsTimeout(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute) ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel() defer cancel()
e, err := stdout.NewExporter() e, err := stdout.New()
if err != nil { if err != nil {
t.Fatalf("failed to create exporter: %v", err) t.Fatalf("failed to create exporter: %v", err)
} }
@ -202,7 +202,7 @@ func TestExporterShutdownHonorsCancel(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute) ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel() defer cancel()
e, err := stdout.NewExporter() e, err := stdout.New()
if err != nil { if err != nil {
t.Fatalf("failed to create exporter: %v", err) t.Fatalf("failed to create exporter: %v", err)
} }
@ -217,7 +217,7 @@ func TestExporterShutdownHonorsCancel(t *testing.T) {
} }
func TestExporterShutdownNoError(t *testing.T) { func TestExporterShutdownNoError(t *testing.T) {
e, err := stdout.NewExporter() e, err := stdout.New()
if err != nil { if err != nil {
t.Fatalf("failed to create exporter: %v", err) t.Fatalf("failed to create exporter: %v", err)
} }

View File

@ -121,7 +121,7 @@ func TestJaegerAgentUDPLimitBatching(t *testing.T) {
n := 1500 n := 1500
s := make(tracetest.SpanStubs, n).Snapshots() s := make(tracetest.SpanStubs, n).Snapshots()
exp, err := NewRawExporter( exp, err := New(
WithAgentEndpoint(WithAgentHost(host), WithAgentPort(port)), WithAgentEndpoint(WithAgentHost(host), WithAgentPort(port)),
) )
require.NoError(t, err) require.NoError(t, err)
@ -153,7 +153,7 @@ func TestSpanExceedsMaxPacketLimit(t *testing.T) {
largeSpans := tracetest.SpanStubs{generateALargeSpan(), {}}.Snapshots() largeSpans := tracetest.SpanStubs{generateALargeSpan(), {}}.Snapshots()
normalSpans := tracetest.SpanStubs{{}, {}}.Snapshots() normalSpans := tracetest.SpanStubs{{}, {}}.Snapshots()
exp, err := NewRawExporter( exp, err := New(
WithAgentEndpoint(WithAgentHost(host), WithAgentPort(port), WithMaxPacketSize(maxSize+1)), WithAgentEndpoint(WithAgentHost(host), WithAgentPort(port), WithMaxPacketSize(maxSize+1)),
) )
require.NoError(t, err) require.NoError(t, err)
@ -177,7 +177,7 @@ func TestEmitBatchWithMultipleErrors(t *testing.T) {
largeSpans := tracetest.SpanStubs{span, span}.Snapshots() largeSpans := tracetest.SpanStubs{span, span}.Snapshots()
// make max packet size smaller than span // make max packet size smaller than span
maxSize := len(span.Name) maxSize := len(span.Name)
exp, err := NewRawExporter( exp, err := New(
WithAgentEndpoint(WithAgentHost(host), WithAgentPort(port), WithMaxPacketSize(maxSize)), WithAgentEndpoint(WithAgentHost(host), WithAgentPort(port), WithMaxPacketSize(maxSize)),
) )
require.NoError(t, err) require.NoError(t, err)

View File

@ -32,7 +32,7 @@ func TestNewRawExporterWithDefault(t *testing.T) {
) )
// Create Jaeger Exporter with default values // Create Jaeger Exporter with default values
exp, err := NewRawExporter( exp, err := New(
WithCollectorEndpoint(), WithCollectorEndpoint(),
) )
@ -63,7 +63,7 @@ func TestNewRawExporterWithEnv(t *testing.T) {
}() }()
// Create Jaeger Exporter with environment variables // Create Jaeger Exporter with environment variables
exp, err := NewRawExporter( exp, err := New(
WithCollectorEndpoint(), WithCollectorEndpoint(),
) )
@ -95,7 +95,7 @@ func TestNewRawExporterWithPassedOption(t *testing.T) {
}() }()
// Create Jaeger Exporter with passed endpoint option, should be used over envEndpoint // Create Jaeger Exporter with passed endpoint option, should be used over envEndpoint
exp, err := NewRawExporter( exp, err := New(
WithCollectorEndpoint(WithEndpoint(optionEndpoint)), WithCollectorEndpoint(WithEndpoint(optionEndpoint)),
) )

View File

@ -21,7 +21,6 @@ import (
"fmt" "fmt"
"sync" "sync"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/codes"
gen "go.opentelemetry.io/otel/exporters/trace/jaeger/internal/gen-go/jaeger" gen "go.opentelemetry.io/otel/exporters/trace/jaeger/internal/gen-go/jaeger"
@ -42,9 +41,9 @@ const (
keyEventName = "event" keyEventName = "event"
) )
// NewRawExporter returns an OTel Exporter implementation that exports the // New returns an OTel Exporter implementation that exports the collected
// collected spans to Jaeger. // spans to Jaeger.
func NewRawExporter(endpointOption EndpointOption) (*Exporter, error) { func New(endpointOption EndpointOption) (*Exporter, error) {
uploader, err := endpointOption.newBatchUploader() uploader, err := endpointOption.newBatchUploader()
if err != nil { if err != nil {
return nil, err return nil, err
@ -69,30 +68,6 @@ func NewRawExporter(endpointOption EndpointOption) (*Exporter, error) {
return e, nil return e, nil
} }
// NewExportPipeline sets up a complete export pipeline
// with the recommended setup for trace provider
func NewExportPipeline(endpointOption EndpointOption) (*sdktrace.TracerProvider, error) {
exporter, err := NewRawExporter(endpointOption)
if err != nil {
return nil, err
}
tp := sdktrace.NewTracerProvider(sdktrace.WithBatcher(exporter))
return tp, nil
}
// InstallNewPipeline instantiates a NewExportPipeline with the
// recommended configuration and registers it globally.
func InstallNewPipeline(endpointOption EndpointOption) (*sdktrace.TracerProvider, error) {
tp, err := NewExportPipeline(endpointOption)
if err != nil {
return tp, err
}
otel.SetTracerProvider(tp)
return tp, nil
}
// Exporter exports OpenTelemetry spans to a Jaeger agent or collector. // Exporter exports OpenTelemetry spans to a Jaeger agent or collector.
type Exporter struct { type Exporter struct {
uploader batchUploader uploader batchUploader

View File

@ -72,7 +72,7 @@ func spans(n int) []tracesdk.ReadOnlySpan {
func benchmarkExportSpans(b *testing.B, o EndpointOption, i int) { func benchmarkExportSpans(b *testing.B, o EndpointOption, i int) {
ctx := context.Background() ctx := context.Background()
s := spans(i) s := spans(i)
exp, err := NewRawExporter(o) exp, err := New(o)
if err != nil { if err != nil {
b.Fatal(err) b.Fatal(err)
} }

View File

@ -17,7 +17,6 @@ package jaeger
import ( import (
"context" "context"
"encoding/binary" "encoding/binary"
"errors"
"fmt" "fmt"
"os" "os"
"sort" "sort"
@ -28,7 +27,6 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/codes"
gen "go.opentelemetry.io/otel/exporters/trace/jaeger/internal/gen-go/jaeger" gen "go.opentelemetry.io/otel/exporters/trace/jaeger/internal/gen-go/jaeger"
@ -41,52 +39,6 @@ import (
"go.opentelemetry.io/otel/trace" "go.opentelemetry.io/otel/trace"
) )
const (
collectorEndpoint = "http://localhost:14268/api/traces"
)
func TestInstallNewPipeline(t *testing.T) {
tp, err := InstallNewPipeline(WithCollectorEndpoint(WithEndpoint(collectorEndpoint)))
require.NoError(t, err)
// Ensure InstallNewPipeline sets the global TracerProvider. By default
// the global tracer provider will be a NoOp implementation, this checks
// if that has been overwritten.
assert.IsType(t, tp, otel.GetTracerProvider())
}
func TestNewExportPipelinePassthroughError(t *testing.T) {
for _, testcase := range []struct {
name string
failing bool
epo EndpointOption
}{
{
name: "failing underlying NewRawExporter",
failing: true,
epo: endpointOptionFunc(func() (batchUploader, error) {
return nil, errors.New("error")
}),
},
{
name: "with default agent endpoint",
epo: WithAgentEndpoint(),
},
{
name: "with collector endpoint",
epo: WithCollectorEndpoint(WithEndpoint(collectorEndpoint)),
},
} {
t.Run(testcase.name, func(t *testing.T) {
_, err := NewExportPipeline(testcase.epo)
if testcase.failing {
require.Error(t, err)
return
}
require.NoError(t, err)
})
}
}
func TestNewRawExporter(t *testing.T) { func TestNewRawExporter(t *testing.T) {
testCases := []struct { testCases := []struct {
name string name string
@ -104,7 +56,7 @@ func TestNewRawExporter(t *testing.T) {
for _, tc := range testCases { for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
_, err := NewRawExporter(tc.endpoint) _, err := New(tc.endpoint)
assert.NoError(t, err) assert.NoError(t, err)
}) })
} }
@ -120,7 +72,7 @@ func TestNewRawExporterUseEnvVarIfOptionUnset(t *testing.T) {
// If the user sets the environment variable OTEL_EXPORTER_JAEGER_ENDPOINT, endpoint will always get a value. // If the user sets the environment variable OTEL_EXPORTER_JAEGER_ENDPOINT, endpoint will always get a value.
require.NoError(t, os.Unsetenv(envEndpoint)) require.NoError(t, os.Unsetenv(envEndpoint))
_, err := NewRawExporter( _, err := New(
WithCollectorEndpoint(), WithCollectorEndpoint(),
) )
@ -162,7 +114,7 @@ func TestExporterExportSpan(t *testing.T) {
) )
testCollector := &testCollectorEndpoint{} testCollector := &testCollectorEndpoint{}
exp, err := NewRawExporter(withTestCollectorEndpointInjected(testCollector)) exp, err := New(withTestCollectorEndpointInjected(testCollector))
require.NoError(t, err) require.NoError(t, err)
tp := sdktrace.NewTracerProvider( tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exp), sdktrace.WithBatcher(exp),
@ -471,7 +423,7 @@ func TestExporterShutdownHonorsCancel(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
cancel() cancel()
e, err := NewRawExporter(withTestCollectorEndpoint()) e, err := New(withTestCollectorEndpoint())
require.NoError(t, err) require.NoError(t, err)
assert.EqualError(t, e.Shutdown(ctx), context.Canceled.Error()) assert.EqualError(t, e.Shutdown(ctx), context.Canceled.Error())
} }
@ -480,21 +432,21 @@ func TestExporterShutdownHonorsTimeout(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Nanosecond) ctx, cancel := context.WithTimeout(context.Background(), 1*time.Nanosecond)
<-ctx.Done() <-ctx.Done()
e, err := NewRawExporter(withTestCollectorEndpoint()) e, err := New(withTestCollectorEndpoint())
require.NoError(t, err) require.NoError(t, err)
assert.EqualError(t, e.Shutdown(ctx), context.DeadlineExceeded.Error()) assert.EqualError(t, e.Shutdown(ctx), context.DeadlineExceeded.Error())
cancel() cancel()
} }
func TestErrorOnExportShutdownExporter(t *testing.T) { func TestErrorOnExportShutdownExporter(t *testing.T) {
e, err := NewRawExporter(withTestCollectorEndpoint()) e, err := New(withTestCollectorEndpoint())
require.NoError(t, err) require.NoError(t, err)
assert.NoError(t, e.Shutdown(context.Background())) assert.NoError(t, e.Shutdown(context.Background()))
assert.NoError(t, e.ExportSpans(context.Background(), nil)) assert.NoError(t, e.ExportSpans(context.Background(), nil))
} }
func TestExporterExportSpansHonorsCancel(t *testing.T) { func TestExporterExportSpansHonorsCancel(t *testing.T) {
e, err := NewRawExporter(withTestCollectorEndpoint()) e, err := New(withTestCollectorEndpoint())
require.NoError(t, err) require.NoError(t, err)
now := time.Now() now := time.Now()
ss := tracetest.SpanStubs{ ss := tracetest.SpanStubs{
@ -524,7 +476,7 @@ func TestExporterExportSpansHonorsCancel(t *testing.T) {
} }
func TestExporterExportSpansHonorsTimeout(t *testing.T) { func TestExporterExportSpansHonorsTimeout(t *testing.T) {
e, err := NewRawExporter(withTestCollectorEndpoint()) e, err := New(withTestCollectorEndpoint())
require.NoError(t, err) require.NoError(t, err)
now := time.Now() now := time.Now()
ss := tracetest.SpanStubs{ ss := tracetest.SpanStubs{

View File

@ -27,7 +27,6 @@ import (
"net/url" "net/url"
"sync" "sync"
"go.opentelemetry.io/otel"
sdktrace "go.opentelemetry.io/otel/sdk/trace" sdktrace "go.opentelemetry.io/otel/sdk/trace"
) )
@ -85,8 +84,8 @@ func WithSDKOptions(tpOpts ...sdktrace.TracerProviderOption) Option {
}) })
} }
// NewRawExporter creates a new Zipkin exporter. // New creates a new Zipkin exporter.
func NewRawExporter(collectorURL string, opts ...Option) (*Exporter, error) { func New(collectorURL string, opts ...Option) (*Exporter, error) {
if collectorURL == "" { if collectorURL == "" {
return nil, errors.New("collector URL cannot be empty") return nil, errors.New("collector URL cannot be empty")
} }
@ -113,32 +112,6 @@ func NewRawExporter(collectorURL string, opts ...Option) (*Exporter, error) {
}, nil }, nil
} }
// NewExportPipeline sets up a complete export pipeline
// with the recommended setup for trace provider
func NewExportPipeline(collectorURL string, opts ...Option) (*sdktrace.TracerProvider, error) {
exporter, err := NewRawExporter(collectorURL, opts...)
if err != nil {
return nil, err
}
tpOpts := append(exporter.config.tpOpts, sdktrace.WithBatcher(exporter))
tp := sdktrace.NewTracerProvider(tpOpts...)
return tp, err
}
// InstallNewPipeline instantiates a NewExportPipeline with the
// recommended configuration and registers it globally.
func InstallNewPipeline(collectorURL string, opts ...Option) error {
tp, err := NewExportPipeline(collectorURL, opts...)
if err != nil {
return err
}
otel.SetTracerProvider(tp)
return nil
}
// ExportSpans exports spans to a Zipkin receiver. // ExportSpans exports spans to a Zipkin receiver.
func (e *Exporter) ExportSpans(ctx context.Context, spans []sdktrace.ReadOnlySpan) error { func (e *Exporter) ExportSpans(ctx context.Context, spans []sdktrace.ReadOnlySpan) error {
e.stoppedMu.RLock() e.stoppedMu.RLock()

View File

@ -30,7 +30,6 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/sdk/resource" "go.opentelemetry.io/otel/sdk/resource"
sdktrace "go.opentelemetry.io/otel/sdk/trace" sdktrace "go.opentelemetry.io/otel/sdk/trace"
@ -43,62 +42,8 @@ const (
collectorURL = "http://localhost:9411/api/v2/spans" collectorURL = "http://localhost:9411/api/v2/spans"
) )
func TestInstallNewPipeline(t *testing.T) {
err := InstallNewPipeline(
collectorURL,
)
assert.NoError(t, err)
assert.IsType(t, &sdktrace.TracerProvider{}, otel.GetTracerProvider())
}
func TestNewExportPipeline(t *testing.T) {
testCases := []struct {
name string
options []Option
testSpanSampling, spanShouldBeSampled bool
}{
{
name: "simple pipeline",
},
{
name: "always on",
options: []Option{
WithSDKOptions(sdktrace.WithSampler(sdktrace.AlwaysSample())),
},
testSpanSampling: true,
spanShouldBeSampled: true,
},
{
name: "never",
options: []Option{
WithSDKOptions(sdktrace.WithSampler(sdktrace.NeverSample())),
},
testSpanSampling: true,
spanShouldBeSampled: false,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
tp, err := NewExportPipeline(
collectorURL,
tc.options...,
)
assert.NoError(t, err)
assert.NotEqual(t, tp, otel.GetTracerProvider())
if tc.testSpanSampling {
_, span := tp.Tracer("zipkin test").Start(context.Background(), tc.name)
spanCtx := span.SpanContext()
assert.Equal(t, tc.spanShouldBeSampled, spanCtx.IsSampled())
span.End()
}
})
}
}
func TestNewRawExporter(t *testing.T) { func TestNewRawExporter(t *testing.T) {
_, err := NewRawExporter( _, err := New(
collectorURL, collectorURL,
) )
@ -112,7 +57,7 @@ func TestNewRawExporterShouldFailInvalidCollectorURL(t *testing.T) {
) )
// cannot be empty // cannot be empty
exp, err = NewRawExporter( exp, err = New(
"", "",
) )
@ -121,7 +66,7 @@ func TestNewRawExporterShouldFailInvalidCollectorURL(t *testing.T) {
assert.Nil(t, exp) assert.Nil(t, exp)
// invalid URL // invalid URL
exp, err = NewRawExporter( exp, err = New(
"localhost", "localhost",
) )
@ -339,7 +284,7 @@ func TestExportSpans(t *testing.T) {
defer collector.Close() defer collector.Close()
ls := &logStore{T: t} ls := &logStore{T: t}
logger := logStoreLogger(ls) logger := logStoreLogger(ls)
exporter, err := NewRawExporter(collector.url, WithLogger(logger)) exporter, err := New(collector.url, WithLogger(logger))
require.NoError(t, err) require.NoError(t, err)
ctx := context.Background() ctx := context.Background()
require.Len(t, ls.Messages, 0) require.Len(t, ls.Messages, 0)
@ -364,7 +309,7 @@ func TestExporterShutdownHonorsTimeout(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute) ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel() defer cancel()
exp, err := NewRawExporter(collectorURL) exp, err := New(collectorURL)
require.NoError(t, err) require.NoError(t, err)
innerCtx, innerCancel := context.WithTimeout(ctx, time.Nanosecond) innerCtx, innerCancel := context.WithTimeout(ctx, time.Nanosecond)
@ -377,7 +322,7 @@ func TestExporterShutdownHonorsCancel(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute) ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel() defer cancel()
exp, err := NewRawExporter(collectorURL) exp, err := New(collectorURL)
require.NoError(t, err) require.NoError(t, err)
innerCtx, innerCancel := context.WithCancel(ctx) innerCtx, innerCancel := context.WithCancel(ctx)
@ -386,39 +331,8 @@ func TestExporterShutdownHonorsCancel(t *testing.T) {
} }
func TestErrorOnExportShutdownExporter(t *testing.T) { func TestErrorOnExportShutdownExporter(t *testing.T) {
exp, err := NewRawExporter(collectorURL) exp, err := New(collectorURL)
require.NoError(t, err) require.NoError(t, err)
assert.NoError(t, exp.Shutdown(context.Background())) assert.NoError(t, exp.Shutdown(context.Background()))
assert.NoError(t, exp.ExportSpans(context.Background(), nil)) assert.NoError(t, exp.ExportSpans(context.Background(), nil))
} }
func TestNewExportPipelineWithOptions(t *testing.T) {
const eventCountLimit = 10
collector := startMockZipkinCollector(t)
defer collector.Close()
tp, err := NewExportPipeline(collector.url,
WithSDKOptions(
sdktrace.WithResource(resource.NewSchemaless(
semconv.ServiceNameKey.String("zipkin-test"),
)),
sdktrace.WithSpanLimits(sdktrace.SpanLimits{
EventCountLimit: eventCountLimit,
}),
),
)
require.NoError(t, err)
otel.SetTracerProvider(tp)
_, span := otel.Tracer("zipkin-tracer").Start(context.Background(), "test-span")
for i := 0; i < eventCountLimit*2; i++ {
span.AddEvent(fmt.Sprintf("event-%d", i))
}
span.End()
require.NoError(t, tp.Shutdown(context.Background()))
require.Equal(t, 1, collector.ModelsLen())
model := collector.StealModels()[0]
require.Equal(t, len(model.Annotations), eventCountLimit)
}

View File

@ -261,7 +261,7 @@ type blockingExporter struct {
func newBlockingExporter() *blockingExporter { func newBlockingExporter() *blockingExporter {
return &blockingExporter{ return &blockingExporter{
exporter: processortest.NewExporter( exporter: processortest.New(
export.CumulativeExportKindSelector(), export.CumulativeExportKindSelector(),
attribute.DefaultEncoder(), attribute.DefaultEncoder(),
), ),
@ -342,7 +342,7 @@ func TestExportTimeout(t *testing.T) {
} }
func TestCollectAfterStopThenStartAgain(t *testing.T) { func TestCollectAfterStopThenStartAgain(t *testing.T) {
exp := processortest.NewExporter( exp := processortest.New(
export.CumulativeExportKindSelector(), export.CumulativeExportKindSelector(),
attribute.DefaultEncoder(), attribute.DefaultEncoder(),
) )

View File

@ -66,7 +66,7 @@ func init() {
} }
func newExporter() *processortest.Exporter { func newExporter() *processortest.Exporter {
return processortest.NewExporter( return processortest.New(
export.StatelessExportKindSelector(), export.StatelessExportKindSelector(),
attribute.DefaultEncoder(), attribute.DefaultEncoder(),
) )

View File

@ -500,7 +500,7 @@ func TestSumObserverEndToEnd(t *testing.T) {
accum.Collect(ctx) accum.Collect(ctx)
require.NoError(t, proc.FinishCollection()) require.NoError(t, proc.FinishCollection())
exporter := processortest.NewExporter(eselector, attribute.DefaultEncoder()) exporter := processortest.New(eselector, attribute.DefaultEncoder())
require.NoError(t, exporter.Export(ctx, data)) require.NoError(t, exporter.Export(ctx, data))
require.EqualValues(t, map[string]float64{ require.EqualValues(t, map[string]float64{

View File

@ -309,7 +309,7 @@ func (o *Output) AddAccumulation(acc export.Accumulation) error {
) )
} }
// NewExporter returns a new testing Exporter implementation. // New returns a new testing Exporter implementation.
// Verify exporter outputs using Values(), e.g.,: // Verify exporter outputs using Values(), e.g.,:
// //
// require.EqualValues(t, map[string]float64{ // require.EqualValues(t, map[string]float64{
@ -318,7 +318,7 @@ func (o *Output) AddAccumulation(acc export.Accumulation) error {
// //
// Where in the example A=1,B=2 is the encoded labels and R=V is the // Where in the example A=1,B=2 is the encoded labels and R=V is the
// encoded resource value. // encoded resource value.
func NewExporter(selector export.ExportKindSelector, encoder attribute.Encoder) *Exporter { func New(selector export.ExportKindSelector, encoder attribute.Encoder) *Exporter {
return &Exporter{ return &Exporter{
ExportKindSelector: selector, ExportKindSelector: selector,
output: NewOutput(encoder), output: NewOutput(encoder),

View File

@ -73,7 +73,7 @@ func TestProcessorTesting(t *testing.T) {
require.EqualValues(t, expect, testProc.Values()) require.EqualValues(t, expect, testProc.Values())
// Export the data and validate it again. // Export the data and validate it again.
exporter := processorTest.NewExporter( exporter := processorTest.New(
export.StatelessExportKindSelector(), export.StatelessExportKindSelector(),
attribute.DefaultEncoder(), attribute.DefaultEncoder(),
) )

View File

@ -94,7 +94,7 @@ func TestFilterBasicProcessor(t *testing.T) {
reducer.New(testFilter{}, basicProc), reducer.New(testFilter{}, basicProc),
resource.NewSchemaless(attribute.String("R", "V")), resource.NewSchemaless(attribute.String("R", "V")),
) )
exporter := processorTest.NewExporter(basicProc, attribute.DefaultEncoder()) exporter := processorTest.New(basicProc, attribute.DefaultEncoder())
generateData(accum) generateData(accum)

View File

@ -51,7 +51,7 @@ To initialize the console exporter, add the following code to the file your `mai
```go ```go
func main() { func main() {
exporter, err := stdout.NewExporter( exporter, err := stdout.New(
stdout.WithPrettyPrint(), stdout.WithPrettyPrint(),
) )
if err != nil { if err != nil {
@ -202,7 +202,3 @@ In this snippet, we're doing a few things. First, we're asking the global trace
Inside our function, we're creating a new span by calling `tracer.Start` with the context we just created, and a name. Passing the context will set our span as 'active' in it, which is used in our inner function to make a new child span. The name is important - every span needs a name, and these names are the primary method of indicating what a span represents. Calling `defer span.End()` ensures that our span will complete once this function has finished its work. Spans can have attributes and events, which are metadata and log statements that help you interpret traces after-the-fact. Finally, in this code snippet we can see an example of creating a new function and propagating the span to it inside our code. When you run this program, you'll see that the 'Sub operation...' span has been created as a child of the 'operation' span. Inside our function, we're creating a new span by calling `tracer.Start` with the context we just created, and a name. Passing the context will set our span as 'active' in it, which is used in our inner function to make a new child span. The name is important - every span needs a name, and these names are the primary method of indicating what a span represents. Calling `defer span.End()` ensures that our span will complete once this function has finished its work. Spans can have attributes and events, which are metadata and log statements that help you interpret traces after-the-fact. Finally, in this code snippet we can see an example of creating a new function and propagating the span to it inside our code. When you run this program, you'll see that the 'Sub operation...' span has been created as a child of the 'operation' span.
We also record some measurements. Recording measurements with asynchronous instruments is controlled by SDK and the controller we use, so we do not need to do anything else after creating the instrument and passing the callback to it. For synchronous instruments there are two ways of recording measurements - either through the instrument, bounded or not (in our case it's a value recorder, so we use the `Record` function), or by making a batched measurement (with `meter.RecordBatch`). Batched measurements allow you to use multiple instruments to create measurement and record them once. We also record some measurements. Recording measurements with asynchronous instruments is controlled by SDK and the controller we use, so we do not need to do anything else after creating the instrument and passing the callback to it. For synchronous instruments there are two ways of recording measurements - either through the instrument, bounded or not (in our case it's a value recorder, so we use the `Record` function), or by making a batched measurement (with `meter.RecordBatch`). Batched measurements allow you to use multiple instruments to create measurement and record them once.
# Final notes
You may have noticed that setting up a tracing and metric pipeline can be a bit involved (create an exporter, a batcher, a tracer provider, a selector, a processor and a controller, and then start the controller, then use the controller to get a meter provider, so it can be registered as a global instance together with the trace provider we got earlier). Some exporters provide a utility functions simplifying these steps. For example the stdout exporter used in this document provides a `NewExportPipeline` that creates all the necessary items, and a `InstallNewPipeline` function that also registers the tracer and meter providers globally.