You've already forked opentelemetry-go
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:
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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),
|
||||||
)
|
)
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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())),
|
||||||
|
@ -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)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
@ -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()
|
||||||
|
@ -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()),
|
||||||
|
@ -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.
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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
|
|
||||||
}
|
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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))
|
||||||
|
@ -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
|
|
||||||
}
|
|
||||||
|
@ -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())
|
|
||||||
}
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
@ -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() {
|
||||||
|
@ -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...))
|
|
||||||
}
|
}
|
||||||
|
@ -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))
|
||||||
|
@ -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...))
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
)
|
)
|
||||||
|
@ -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))
|
||||||
|
}
|
||||||
|
@ -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
|
|
||||||
}
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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)),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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{
|
||||||
|
@ -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()
|
||||||
|
@ -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)
|
|
||||||
}
|
|
||||||
|
@ -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(),
|
||||||
)
|
)
|
||||||
|
@ -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(),
|
||||||
)
|
)
|
||||||
|
@ -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{
|
||||||
|
@ -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),
|
||||||
|
@ -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(),
|
||||||
)
|
)
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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.
|
|
||||||
|
Reference in New Issue
Block a user