diff --git a/CHANGELOG.md b/CHANGELOG.md index c646ecf78b4..5199d48b670 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [Unreleased] +### Changed + +- Jaeger exporter helpers: added InstallNewPipeline and removed RegisterGlobal option instead. (#944) +- Zipkin exporter helpers: pipeline methods introduced, new exporter method adjusted. (#944) + ## [0.9.0] - 2020-07-20 ### Added diff --git a/example/jaeger/main.go b/example/jaeger/main.go index 7ef9e238933..e28592e0f60 100644 --- a/example/jaeger/main.go +++ b/example/jaeger/main.go @@ -30,7 +30,7 @@ import ( // initTracer creates a new trace provider instance and registers it as global trace provider. func initTracer() func() { // Create and install Jaeger export pipeline - _, flush, err := jaeger.NewExportPipeline( + flush, err := jaeger.InstallNewPipeline( jaeger.WithCollectorEndpoint("http://localhost:14268/api/traces"), jaeger.WithProcess(jaeger.Process{ ServiceName: "trace-demo", @@ -39,7 +39,6 @@ func initTracer() func() { kv.Float64("float", 312.23), }, }), - jaeger.RegisterAsGlobal(), jaeger.WithSDK(&sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}), ) if err != nil { diff --git a/example/zipkin/main.go b/example/zipkin/main.go index 94e0e6e2958..ed85056d39f 100644 --- a/example/zipkin/main.go +++ b/example/zipkin/main.go @@ -33,30 +33,20 @@ var logger = log.New(os.Stderr, "zipkin-example", log.Ldate|log.Ltime|log.Llongf // initTracer creates a new trace provider instance and registers it as global trace provider. func initTracer(url string) { - // Create Zipkin Exporter - exporter, err := zipkin.NewExporter( - url, - "zipkin-example", - zipkin.WithLogger(logger), - ) - if err != nil { - log.Fatal(err) - } - + // Create Zipkin Exporter and install it as a global tracer. + // // For demoing purposes, always sample. In a production application, you should - // configure this to a trace.ProbabilitySampler set at the desired + // configure the sampler to a trace.ProbabilitySampler set at the desired // probability. - tp, err := sdktrace.NewProvider( - sdktrace.WithConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}), - sdktrace.WithBatcher(exporter, - sdktrace.WithBatchTimeout(5), - sdktrace.WithMaxExportBatchSize(10), - ), + err := zipkin.InstallNewPipeline( + url, + "zipkin-test", + zipkin.WithLogger(logger), + zipkin.WithSDK(&sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}), ) if err != nil { log.Fatal(err) } - global.SetTraceProvider(tp) } func main() { @@ -73,7 +63,9 @@ func main() { bar(ctx) <-time.After(6 * time.Millisecond) span.End() - <-time.After(24 * time.Millisecond) + + // Wait for the spans to be exported. + <-time.After(5 * time.Second) } func bar(ctx context.Context) { diff --git a/exporters/trace/jaeger/jaeger.go b/exporters/trace/jaeger/jaeger.go index 778560f2eb8..9d9fd325ce2 100644 --- a/exporters/trace/jaeger/jaeger.go +++ b/exporters/trace/jaeger/jaeger.go @@ -47,10 +47,6 @@ type options struct { Config *sdktrace.Config - // RegisterGlobal is set to true if the trace provider of the new pipeline should be - // registered as Global Trace Provider - RegisterGlobal bool - Disabled bool } @@ -82,14 +78,8 @@ func WithSDK(config *sdktrace.Config) Option { } } -// RegisterAsGlobal enables the registration of the trace provider of the new pipeline -// as Global Trace Provider. -func RegisterAsGlobal() Option { - return func(o *options) { - o.RegisterGlobal = true - } -} - +// WithDisabled option will cause pipeline methods to use +// a no-op provider func WithDisabled(disabled bool) Option { return func(o *options) { o.Disabled = disabled @@ -177,13 +167,22 @@ func NewExportPipeline(endpointOption EndpointOption, opts ...Option) (apitrace. if exporter.o.Config != nil { tp.ApplyConfig(*exporter.o.Config) } - if exporter.o.RegisterGlobal { - global.SetTraceProvider(tp) - } return tp, exporter.Flush, nil } +// InstallNewPipeline instantiates a NewExportPipeline with the +// recommended configuration and registers it globally. +func InstallNewPipeline(endpointOption EndpointOption, opts ...Option) (func(), error) { + tp, flushFn, err := NewExportPipeline(endpointOption, opts...) + if err != nil { + return nil, err + } + + global.SetTraceProvider(tp) + return flushFn, nil +} + // Process contains the information exported to jaeger about the source // of the trace data. type Process struct { diff --git a/exporters/trace/jaeger/jaeger_test.go b/exporters/trace/jaeger/jaeger_test.go index 7f28a6c6fa1..df94e457444 100644 --- a/exporters/trace/jaeger/jaeger_test.go +++ b/exporters/trace/jaeger/jaeger_test.go @@ -26,10 +26,12 @@ import ( "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "google.golang.org/api/support/bundler" "google.golang.org/grpc/codes" "go.opentelemetry.io/otel/api/global" "go.opentelemetry.io/otel/api/kv" + "go.opentelemetry.io/otel/api/trace" apitrace "go.opentelemetry.io/otel/api/trace" gen "go.opentelemetry.io/otel/exporters/trace/jaeger/internal/gen-go/jaeger" ottest "go.opentelemetry.io/otel/internal/testing" @@ -38,77 +40,251 @@ import ( sdktrace "go.opentelemetry.io/otel/sdk/trace" ) -func TestNewExporterPipelineWithRegistration(t *testing.T) { - tp, fn, err := NewExportPipeline( - WithCollectorEndpoint("http://localhost:14268/api/traces"), - RegisterAsGlobal(), - ) - defer fn() - assert.NoError(t, err) - assert.Same(t, tp, global.TraceProvider()) +const ( + collectorEndpoint = "http://localhost:14268/api/traces" + agentEndpoint = "localhost:6831" +) + +func TestInstallNewPipeline(t *testing.T) { + testCases := []struct { + name string + endpoint EndpointOption + options []Option + expectedProvider trace.Provider + }{ + { + name: "simple pipeline", + endpoint: WithCollectorEndpoint(collectorEndpoint), + expectedProvider: &sdktrace.Provider{}, + }, + { + name: "with agent endpoint", + endpoint: WithAgentEndpoint(agentEndpoint), + expectedProvider: &sdktrace.Provider{}, + }, + { + name: "with disabled", + endpoint: WithCollectorEndpoint(collectorEndpoint), + options: []Option{ + WithDisabled(true), + }, + expectedProvider: &apitrace.NoopProvider{}, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + fn, err := InstallNewPipeline( + tc.endpoint, + tc.options..., + ) + defer fn() + + assert.NoError(t, err) + assert.IsType(t, tc.expectedProvider, global.TraceProvider()) + + global.SetTraceProvider(nil) + }) + } } -func TestNewExporterPipelineWithoutRegistration(t *testing.T) { - tp, fn, err := NewExportPipeline( - WithCollectorEndpoint("http://localhost:14268/api/traces"), - ) - defer fn() - assert.NoError(t, err) - assert.NotEqual(t, tp, global.TraceProvider()) +func TestNewExportPipeline(t *testing.T) { + testCases := []struct { + name string + endpoint EndpointOption + options []Option + expectedProviderType trace.Provider + testSpanSampling, spanShouldBeSampled bool + }{ + { + name: "simple pipeline", + endpoint: WithCollectorEndpoint(collectorEndpoint), + expectedProviderType: &sdktrace.Provider{}, + }, + { + name: "with disabled", + endpoint: WithCollectorEndpoint(collectorEndpoint), + options: []Option{ + WithDisabled(true), + }, + expectedProviderType: &apitrace.NoopProvider{}, + }, + { + name: "always on", + endpoint: WithCollectorEndpoint(collectorEndpoint), + options: []Option{ + WithSDK(&sdktrace.Config{ + DefaultSampler: sdktrace.AlwaysSample(), + }), + }, + expectedProviderType: &sdktrace.Provider{}, + testSpanSampling: true, + spanShouldBeSampled: true, + }, + { + name: "never", + endpoint: WithCollectorEndpoint(collectorEndpoint), + options: []Option{ + WithSDK(&sdktrace.Config{ + DefaultSampler: sdktrace.NeverSample(), + }), + }, + expectedProviderType: &sdktrace.Provider{}, + testSpanSampling: true, + spanShouldBeSampled: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + tp, fn, err := NewExportPipeline( + tc.endpoint, + tc.options..., + ) + defer fn() + + assert.NoError(t, err) + assert.NotEqual(t, tp, global.TraceProvider()) + assert.IsType(t, tc.expectedProviderType, tp) + + if tc.testSpanSampling { + _, span := tp.Tracer("jaeger test").Start(context.Background(), tc.name) + spanCtx := span.SpanContext() + assert.Equal(t, tc.spanShouldBeSampled, spanCtx.IsSampled()) + span.End() + } + }) + } } -func TestNewExporterPipelineWithSDK(t *testing.T) { - tp, fn, err := NewExportPipeline( - WithCollectorEndpoint("http://localhost:14268/api/traces"), - WithSDK(&sdktrace.Config{ - DefaultSampler: sdktrace.AlwaysSample(), - }), - ) - defer fn() - assert.NoError(t, err) - _, span := tp.Tracer("jaeger test").Start(context.Background(), "always-on") - spanCtx := span.SpanContext() - assert.True(t, spanCtx.IsSampled()) - span.End() +func TestNewExportPipelineWithDisabledFromEnv(t *testing.T) { + envStore, err := ottest.SetEnvVariables(map[string]string{ + envDisabled: "true", + }) + require.NoError(t, err) + envStore.Record(envDisabled) + defer func() { + require.NoError(t, envStore.Restore()) + }() - tp2, fn, err := NewExportPipeline( - WithCollectorEndpoint("http://localhost:14268/api/traces"), - WithSDK(&sdktrace.Config{ - DefaultSampler: sdktrace.NeverSample(), - }), + tp, fn, err := NewExportPipeline( + WithCollectorEndpoint(collectorEndpoint), ) defer fn() assert.NoError(t, err) - _, span2 := tp2.Tracer("jaeger test").Start(context.Background(), "never") - span2Ctx := span2.SpanContext() - assert.False(t, span2Ctx.IsSampled()) - span2.End() + assert.IsType(t, &apitrace.NoopProvider{}, tp) } func TestNewRawExporter(t *testing.T) { - const ( - collectorEndpoint = "http://localhost" - serviceName = "test-service" - tagKey = "key" - tagVal = "val" - ) - // Create Jaeger Exporter - exp, err := NewRawExporter( - WithCollectorEndpoint(collectorEndpoint), - WithProcess(Process{ - ServiceName: serviceName, - Tags: []kv.KeyValue{ - kv.String(tagKey, tagVal), + testCases := []struct { + name string + endpoint EndpointOption + options []Option + expectedServiceName string + expectedTagsLen, expectedBufferMaxCount, expectedBatchMaxCount int + }{ + { + name: "default exporter", + endpoint: WithCollectorEndpoint(collectorEndpoint), + expectedServiceName: defaultServiceName, + expectedBufferMaxCount: bundler.DefaultBufferedByteLimit, + expectedBatchMaxCount: bundler.DefaultBundleCountThreshold, + }, + { + name: "default exporter with agent endpoint", + endpoint: WithAgentEndpoint(agentEndpoint), + expectedServiceName: defaultServiceName, + expectedBufferMaxCount: bundler.DefaultBufferedByteLimit, + expectedBatchMaxCount: bundler.DefaultBundleCountThreshold, + }, + { + name: "with process", + endpoint: WithCollectorEndpoint(collectorEndpoint), + options: []Option{ + WithProcess( + Process{ + ServiceName: "jaeger-test", + Tags: []kv.KeyValue{ + kv.String("key", "val"), + }, + }, + ), }, - }), - ) + expectedServiceName: "jaeger-test", + expectedTagsLen: 1, + expectedBufferMaxCount: bundler.DefaultBufferedByteLimit, + expectedBatchMaxCount: bundler.DefaultBundleCountThreshold, + }, + { + name: "with buffer and batch max count", + endpoint: WithCollectorEndpoint(collectorEndpoint), + options: []Option{ + WithProcess( + Process{ + ServiceName: "jaeger-test", + }, + ), + WithBufferMaxCount(99), + WithBatchMaxCount(99), + }, + expectedServiceName: "jaeger-test", + expectedBufferMaxCount: 99, + expectedBatchMaxCount: 99, + }, + } - assert.NoError(t, err) - assert.EqualValues(t, serviceName, exp.process.ServiceName) - assert.Len(t, exp.process.Tags, 1) + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + exp, err := NewRawExporter( + tc.endpoint, + tc.options..., + ) + + assert.NoError(t, err) + assert.Equal(t, tc.expectedServiceName, exp.process.ServiceName) + assert.Len(t, exp.process.Tags, tc.expectedTagsLen) + assert.Equal(t, tc.expectedBufferMaxCount, exp.bundler.BufferedByteLimit) + assert.Equal(t, tc.expectedBatchMaxCount, exp.bundler.BundleCountThreshold) + }) + } } -func TestNewRawExporterShouldFailIfCollectorEndpointEmpty(t *testing.T) { +func TestNewRawExporterShouldFail(t *testing.T) { + testCases := []struct { + name string + endpoint EndpointOption + expectedErrMsg string + }{ + { + name: "with empty collector endpoint", + endpoint: WithCollectorEndpoint(""), + expectedErrMsg: "collectorEndpoint must not be empty", + }, + { + name: "with empty agent endpoint", + endpoint: WithAgentEndpoint(""), + expectedErrMsg: "agentEndpoint must not be empty", + }, + { + name: "with invalid agent endpoint", + endpoint: WithAgentEndpoint("localhost"), + expectedErrMsg: "address localhost: missing port in address", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + _, err := NewRawExporter( + tc.endpoint, + ) + + assert.Error(t, err) + assert.EqualError(t, err, tc.expectedErrMsg) + }) + } +} + +func TestNewRawExporterShouldFailIfCollectorUnset(t *testing.T) { // Record and restore env envStore := ottest.NewEnvStore() envStore.Record(envEndpoint) @@ -179,29 +355,6 @@ func TestExporter_ExportSpan(t *testing.T) { assert.True(t, len(tc.spansUploaded) == 1) } -func TestNewRawExporterWithAgentEndpoint(t *testing.T) { - const agentEndpoint = "localhost:6831" - // Create Jaeger Exporter - _, err := NewRawExporter( - WithAgentEndpoint(agentEndpoint), - ) - assert.NoError(t, err) -} - -func TestNewRawExporterWithAgentShouldFailIfEndpointInvalid(t *testing.T) { - //empty - _, err := NewRawExporter( - WithAgentEndpoint(""), - ) - assert.Error(t, err) - - //invalid endpoint addr - _, err = NewRawExporter( - WithAgentEndpoint("http://localhost"), - ) - assert.Error(t, err) -} - func Test_spanDataToThrift(t *testing.T) { now := time.Now() traceID, _ := apitrace.IDFromHex("0102030405060708090a0b0c0d0e0f10") @@ -319,31 +472,3 @@ func Test_spanDataToThrift(t *testing.T) { }) } } - -func TestNewExporterPipelineWithDisabled(t *testing.T) { - tp, fn, err := NewExportPipeline( - WithCollectorEndpoint("http://localhost:14268/api/traces"), - WithDisabled(true), - ) - defer fn() - assert.NoError(t, err) - assert.IsType(t, &apitrace.NoopProvider{}, tp) -} - -func TestNewExporterPipelineWithDisabledFromEnv(t *testing.T) { - envStore, err := ottest.SetEnvVariables(map[string]string{ - envDisabled: "true", - }) - require.NoError(t, err) - envStore.Record(envDisabled) - defer func() { - require.NoError(t, envStore.Restore()) - }() - - tp, fn, err := NewExportPipeline( - WithCollectorEndpoint("http://localhost:14268/api/traces"), - ) - defer fn() - assert.NoError(t, err) - assert.IsType(t, &apitrace.NoopProvider{}, tp) -} diff --git a/exporters/trace/zipkin/doc.go b/exporters/trace/zipkin/doc.go new file mode 100644 index 00000000000..fb6d363d6be --- /dev/null +++ b/exporters/trace/zipkin/doc.go @@ -0,0 +1,16 @@ +// 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 zipkin contains an OpenTelemetry tracing exporter for Zipkin. +package zipkin // import "go.opentelemetry.io/otel/exporters/trace/zipkin" diff --git a/exporters/trace/zipkin/zipkin.go b/exporters/trace/zipkin/zipkin.go index a356e5e70b6..7c16d61b5bc 100644 --- a/exporters/trace/zipkin/zipkin.go +++ b/exporters/trace/zipkin/zipkin.go @@ -18,13 +18,16 @@ import ( "bytes" "context" "encoding/json" + "errors" "fmt" "io/ioutil" "log" "net/http" "net/url" + "go.opentelemetry.io/otel/api/global" export "go.opentelemetry.io/otel/sdk/export/trace" + sdktrace "go.opentelemetry.io/otel/sdk/trace" ) // Exporter exports SpanData to the zipkin collector. It implements @@ -35,6 +38,7 @@ type Exporter struct { serviceName string client *http.Client logger *log.Logger + o options } var ( @@ -42,51 +46,97 @@ var ( ) // Options contains configuration for the exporter. -type Options struct { +type options struct { client *http.Client logger *log.Logger + config *sdktrace.Config } // Option defines a function that configures the exporter. -type Option func(*Options) +type Option func(*options) // WithLogger configures the exporter to use the passed logger. func WithLogger(logger *log.Logger) Option { - return func(opts *Options) { + return func(opts *options) { opts.logger = logger } } // WithClient configures the exporter to use the passed HTTP client. func WithClient(client *http.Client) Option { - return func(opts *Options) { + return func(opts *options) { opts.client = client } } -// NewExporter creates a new zipkin exporter. -func NewExporter(collectorURL string, serviceName string, os ...Option) (*Exporter, error) { - if _, err := url.Parse(collectorURL); err != nil { +// WithSDK sets the SDK config for the exporter pipeline. +func WithSDK(config *sdktrace.Config) Option { + return func(o *options) { + o.config = config + } +} + +// NewRawExporter creates a new Zipkin exporter. +func NewRawExporter(collectorURL, serviceName string, opts ...Option) (*Exporter, error) { + if collectorURL == "" { + return nil, errors.New("collector URL cannot be empty") + } + u, err := url.Parse(collectorURL) + if err != nil { return nil, fmt.Errorf("invalid collector URL: %v", err) } - if serviceName == "" { - return nil, fmt.Errorf("service name must be non-empty string") + if u.Scheme == "" || u.Host == "" { + return nil, errors.New("invalid collector URL") } - opts := Options{} - for _, o := range os { - o(&opts) + + o := options{} + for _, opt := range opts { + opt(&o) } - if opts.client == nil { - opts.client = http.DefaultClient + if o.client == nil { + o.client = http.DefaultClient } return &Exporter{ url: collectorURL, - client: opts.client, - logger: opts.logger, + client: o.client, + logger: o.logger, serviceName: serviceName, + o: o, }, nil } +// NewExportPipeline sets up a complete export pipeline +// with the recommended setup for trace provider +func NewExportPipeline(collectorURL, serviceName string, opts ...Option) (*sdktrace.Provider, error) { + exp, err := NewRawExporter(collectorURL, serviceName, opts...) + if err != nil { + return nil, err + } + + batcher := sdktrace.WithBatcher(exp) + tp, err := sdktrace.NewProvider(batcher) + if err != nil { + return nil, err + } + if exp.o.config != nil { + tp.ApplyConfig(*exp.o.config) + } + + return tp, err +} + +// InstallNewPipeline instantiates a NewExportPipeline with the +// recommended configuration and registers it globally. +func InstallNewPipeline(collectorURL, serviceName string, opts ...Option) error { + tp, err := NewExportPipeline(collectorURL, serviceName, opts...) + if err != nil { + return err + } + + global.SetTraceProvider(tp) + return nil +} + // ExportSpans is a part of an implementation of the SpanBatcher // interface. func (e *Exporter) ExportSpans(ctx context.Context, batch []*export.SpanData) { diff --git a/exporters/trace/zipkin/exporter_test.go b/exporters/trace/zipkin/zipkin_test.go similarity index 75% rename from exporters/trace/zipkin/exporter_test.go rename to exporters/trace/zipkin/zipkin_test.go index 7665b020ab7..c77f633b89d 100644 --- a/exporters/trace/zipkin/exporter_test.go +++ b/exporters/trace/zipkin/zipkin_test.go @@ -27,13 +27,118 @@ import ( "time" zkmodel "github.com/openzipkin/zipkin-go/model" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/grpc/codes" + "go.opentelemetry.io/otel/api/global" "go.opentelemetry.io/otel/api/trace" export "go.opentelemetry.io/otel/sdk/export/trace" + sdktrace "go.opentelemetry.io/otel/sdk/trace" ) +const ( + collectorURL = "http://localhost:9411/api/v2/spans" + serviceName = "zipkin-test" +) + +func TestInstallNewPipeline(t *testing.T) { + err := InstallNewPipeline( + collectorURL, + serviceName, + ) + assert.NoError(t, err) + assert.IsType(t, &sdktrace.Provider{}, global.TraceProvider()) +} + +func TestNewExportPipeline(t *testing.T) { + testCases := []struct { + name string + options []Option + testSpanSampling, spanShouldBeSampled bool + }{ + { + name: "simple pipeline", + }, + { + name: "always on", + options: []Option{ + WithSDK(&sdktrace.Config{ + DefaultSampler: sdktrace.AlwaysSample(), + }), + }, + testSpanSampling: true, + spanShouldBeSampled: true, + }, + { + name: "never", + options: []Option{ + WithSDK(&sdktrace.Config{ + DefaultSampler: sdktrace.NeverSample(), + }), + }, + testSpanSampling: true, + spanShouldBeSampled: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + tp, err := NewExportPipeline( + collectorURL, + serviceName, + tc.options..., + ) + assert.NoError(t, err) + assert.NotEqual(t, tp, global.TraceProvider()) + + 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) { + exp, err := NewRawExporter( + collectorURL, + serviceName, + ) + + assert.NoError(t, err) + assert.EqualValues(t, serviceName, exp.serviceName) +} + +func TestNewRawExporterShouldFailInvalidCollectorURL(t *testing.T) { + var ( + exp *Exporter + err error + ) + + // cannot be empty + exp, err = NewRawExporter( + "", + serviceName, + ) + + assert.Error(t, err) + assert.EqualError(t, err, "collector URL cannot be empty") + assert.Nil(t, exp) + + // invalid URL + exp, err = NewRawExporter( + "localhost", + serviceName, + ) + + assert.Error(t, err) + assert.EqualError(t, err, "invalid collector URL") + assert.Nil(t, exp) +} + type mockZipkinCollector struct { t *testing.T url string @@ -230,9 +335,7 @@ func TestExportSpans(t *testing.T) { defer collector.Close() ls := &logStore{T: t} logger := logStoreLogger(ls) - _, err := NewExporter(collector.url, "", WithLogger(logger)) - require.Error(t, err, "service name must be non-empty string") - exporter, err := NewExporter(collector.url, "exporter-test", WithLogger(logger)) + exporter, err := NewRawExporter(collector.url, "exporter-test", WithLogger(logger)) require.NoError(t, err) ctx := context.Background() require.Len(t, ls.Messages, 0) diff --git a/internal/testing/env.go b/internal/testing/env.go index db481ae1cba..d8458c644d7 100644 --- a/internal/testing/env.go +++ b/internal/testing/env.go @@ -29,7 +29,7 @@ type EnvStore interface { // Records the environment variable into the store. Record(key string) - // Restore recover the environment variables in the store. + // Restore recovers the environment variables in the store. Restore() error }