diff --git a/defaults/defaults.go b/defaults/defaults.go
index 4c7fac2f5c6..99dad5b8cb8 100644
--- a/defaults/defaults.go
+++ b/defaults/defaults.go
@@ -17,6 +17,7 @@ package defaults
import (
"github.com/open-telemetry/opentelemetry-service/exporter"
+ "github.com/open-telemetry/opentelemetry-service/exporter/jaeger/jaegergrpcexporter"
"github.com/open-telemetry/opentelemetry-service/exporter/loggingexporter"
"github.com/open-telemetry/opentelemetry-service/exporter/opencensusexporter"
"github.com/open-telemetry/opentelemetry-service/exporter/prometheusexporter"
@@ -60,6 +61,7 @@ func Components() (
&prometheusexporter.Factory{},
&loggingexporter.Factory{},
&zipkinexporter.Factory{},
+ &jaegergrpcexporter.Factory{},
)
if err != nil {
errs = append(errs, err)
diff --git a/defaults/defaults_test.go b/defaults/defaults_test.go
index 0c389644a9e..e3238b4217f 100644
--- a/defaults/defaults_test.go
+++ b/defaults/defaults_test.go
@@ -23,6 +23,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/open-telemetry/opentelemetry-service/exporter"
+ "github.com/open-telemetry/opentelemetry-service/exporter/jaeger/jaegergrpcexporter"
"github.com/open-telemetry/opentelemetry-service/exporter/loggingexporter"
"github.com/open-telemetry/opentelemetry-service/exporter/opencensusexporter"
"github.com/open-telemetry/opentelemetry-service/exporter/prometheusexporter"
@@ -55,10 +56,11 @@ func TestDefaultComponents(t *testing.T) {
"batch": &nodebatcher.Factory{},
}
expectedExporters := map[string]exporter.Factory{
- "opencensus": &opencensusexporter.Factory{},
- "prometheus": &prometheusexporter.Factory{},
- "logging": &loggingexporter.Factory{},
- "zipkin": &zipkinexporter.Factory{},
+ "opencensus": &opencensusexporter.Factory{},
+ "prometheus": &prometheusexporter.Factory{},
+ "logging": &loggingexporter.Factory{},
+ "zipkin": &zipkinexporter.Factory{},
+ "jaeger-grpc": &jaegergrpcexporter.Factory{},
}
receivers, processors, exporters, err := Components()
diff --git a/examples/demotrace/docker-compose.yaml b/examples/demotrace/docker-compose.yaml
index 58e8fe3efb8..9a09f503545 100644
--- a/examples/demotrace/docker-compose.yaml
+++ b/examples/demotrace/docker-compose.yaml
@@ -3,10 +3,11 @@ services:
# Jaeger
jaeger-all-in-one:
- image: jaegertracing/all-in-one:1.8
+ image: jaegertracing/all-in-one:latest
ports:
- "16686:16686"
- "14268"
+ - "14250"
# Zipkin
zipkin-all-in-one:
diff --git a/examples/demotrace/otel-collector-config.yaml b/examples/demotrace/otel-collector-config.yaml
index 373089bcc84..7128b1fbae8 100644
--- a/examples/demotrace/otel-collector-config.yaml
+++ b/examples/demotrace/otel-collector-config.yaml
@@ -7,18 +7,12 @@ receivers:
exporters:
logging:
+
zipkin:
url: "http://zipkin-all-in-one:9411/api/v2/spans"
-# TODO: enable jaeger exporter when it is implemented in otelsvc
-# jaeger:
-# num-workers: 4
-# queue-size: 100
-# retry-on-failure: true
-# sender-type: jaeger-thrift-http
-# jaeger-thrift-http:
-# collector-endpoint: http://jaeger-all-in-one:14268/api/traces
-# timeout: 5s
+ jaeger-grpc:
+ endpoint: jaeger-all-in-one:14250
processors:
batch:
@@ -27,5 +21,5 @@ processors:
pipelines:
traces:
receivers: [opencensus]
- exporters: [logging, zipkin]
+ exporters: [logging, zipkin, jaeger-grpc]
processors: [batch, queued-retry]
diff --git a/exporter/README.md b/exporter/README.md
index d938b54ab93..8db864bcb8a 100644
--- a/exporter/README.md
+++ b/exporter/README.md
@@ -1,6 +1,6 @@
# Exporters
-A variety of exporters are available to the OpenTelemetry Service:
+Below is the list of exporters directly supported by the OpenTelemetry Service.
* [Jaeger](#jaeger)
* [Logging](#logging)
@@ -8,8 +8,33 @@ A variety of exporters are available to the OpenTelemetry Service:
* [Prometheus](#prometheus)
* [Zipkin](#zipkin)
+The [contributors repository](https://github.com/open-telemetry/opentelemetry-service-contrib)
+ has more exporters that can be added to custom builds of the service.
+
## Jaeger
-TODO: document settings
+
+Exports trace data to [Jaeger](https://www.jaegertracing.io/) collectors
+accepting one of the following protocols:
+
+* [gRPC](#jaeger-grpc)
+
+### Configuration
+
+Each different supported protocol has its own configuration settings.
+
+#### gRPC
+
+* `endpoint:` target to which the exporter is going to send Jaeger trace data,
+using the gRPC protocol. The valid syntax is described at
+https://github.com/grpc/grpc/blob/master/doc/naming.md
+
+Example:
+
+```yaml
+exporters:
+ jaeger-grpc:
+ endpoint: jaeger-all-in-one:14250
+```
## Logging
TODO: document settings
@@ -21,7 +46,7 @@ TODO: document settings
TODO: document settings
## Zipkin
-Exports trace data to a [Zipkin](https://zipkin.io/) endpoint.
+Exports trace data to a [Zipkin](https://zipkin.io/) back-end.
### Configuration
diff --git a/exporter/jaegerexporter/empty_test.go b/exporter/jaeger/empty_test.go
similarity index 96%
rename from exporter/jaegerexporter/empty_test.go
rename to exporter/jaeger/empty_test.go
index b3de29862f7..dd05aefd580 100644
--- a/exporter/jaegerexporter/empty_test.go
+++ b/exporter/jaeger/empty_test.go
@@ -12,6 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package jaegerexporter
+package jaeger
// TODO: Delete me when tests are added.
diff --git a/exporter/jaegerexporter/jaeger_thrift_http_sender.go b/exporter/jaeger/jaeger_thrift_http_sender.go
similarity index 86%
rename from exporter/jaegerexporter/jaeger_thrift_http_sender.go
rename to exporter/jaeger/jaeger_thrift_http_sender.go
index 984f7a95dfd..92599ba9691 100644
--- a/exporter/jaegerexporter/jaeger_thrift_http_sender.go
+++ b/exporter/jaeger/jaeger_thrift_http_sender.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package jaegerexporter
+package jaeger
import (
"bytes"
@@ -35,29 +35,29 @@ import (
// Default timeout for http request in seconds
const defaultHTTPTimeout = time.Second * 5
-// JaegerThriftHTTPSender forwards spans encoded in the jaeger thrift
+// ThriftHTTPSender forwards spans encoded in the jaeger thrift
// format to a http server
-type JaegerThriftHTTPSender struct {
+type ThriftHTTPSender struct {
url string
headers map[string]string
client *http.Client
logger *zap.Logger
}
-var _ consumer.TraceConsumer = (*JaegerThriftHTTPSender)(nil)
+var _ consumer.TraceConsumer = (*ThriftHTTPSender)(nil)
// HTTPOption sets a parameter for the HttpCollector
-type HTTPOption func(s *JaegerThriftHTTPSender)
+type HTTPOption func(s *ThriftHTTPSender)
// HTTPTimeout sets maximum timeout for http request.
func HTTPTimeout(duration time.Duration) HTTPOption {
- return func(s *JaegerThriftHTTPSender) { s.client.Timeout = duration }
+ return func(s *ThriftHTTPSender) { s.client.Timeout = duration }
}
// HTTPRoundTripper configures the underlying Transport on the *http.Client
// that is used
func HTTPRoundTripper(transport http.RoundTripper) HTTPOption {
- return func(s *JaegerThriftHTTPSender) {
+ return func(s *ThriftHTTPSender) {
s.client.Transport = transport
}
}
@@ -70,8 +70,8 @@ func NewJaegerThriftHTTPSender(
headers map[string]string,
zlogger *zap.Logger,
options ...HTTPOption,
-) *JaegerThriftHTTPSender {
- s := &JaegerThriftHTTPSender{
+) *ThriftHTTPSender {
+ s := &ThriftHTTPSender{
url: url,
headers: headers,
client: &http.Client{Timeout: defaultHTTPTimeout},
@@ -85,7 +85,7 @@ func NewJaegerThriftHTTPSender(
}
// ConsumeTraceData sends the received data to the configured Jaeger Thrift end-point.
-func (s *JaegerThriftHTTPSender) ConsumeTraceData(ctx context.Context, td consumerdata.TraceData) error {
+func (s *ThriftHTTPSender) ConsumeTraceData(ctx context.Context, td consumerdata.TraceData) error {
// TODO: (@pjanotti) In case of failure the translation to Jaeger Thrift is going to be remade, cache it somehow.
tBatch, err := jaegertranslator.OCProtoToJaegerThrift(td)
if err != nil {
diff --git a/exporter/jaegerexporter/jaeger_thrift_tchannel_sender.go b/exporter/jaeger/jaeger_thrift_tchannel_sender.go
similarity index 82%
rename from exporter/jaegerexporter/jaeger_thrift_tchannel_sender.go
rename to exporter/jaeger/jaeger_thrift_tchannel_sender.go
index 1e1a4e7ee96..233a1035635 100644
--- a/exporter/jaegerexporter/jaeger_thrift_tchannel_sender.go
+++ b/exporter/jaeger/jaeger_thrift_tchannel_sender.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package jaegerexporter
+package jaeger
import (
"context"
@@ -26,28 +26,28 @@ import (
jaegertranslator "github.com/open-telemetry/opentelemetry-service/translator/trace/jaeger"
)
-// JaegerThriftTChannelSender takes span batches and sends them
+// ThriftTChannelSender takes span batches and sends them
// out on tchannel in thrift encoding
-type JaegerThriftTChannelSender struct {
+type ThriftTChannelSender struct {
logger *zap.Logger
reporter reporter.Reporter
}
-var _ consumer.TraceConsumer = (*JaegerThriftTChannelSender)(nil)
+var _ consumer.TraceConsumer = (*ThriftTChannelSender)(nil)
// NewJaegerThriftTChannelSender creates new TChannel-based sender.
func NewJaegerThriftTChannelSender(
reporter reporter.Reporter,
zlogger *zap.Logger,
-) *JaegerThriftTChannelSender {
- return &JaegerThriftTChannelSender{
+) *ThriftTChannelSender {
+ return &ThriftTChannelSender{
logger: zlogger,
reporter: reporter,
}
}
// ConsumeTraceData sends the received data to the configured Jaeger Thrift end-point.
-func (s *JaegerThriftTChannelSender) ConsumeTraceData(ctx context.Context, td consumerdata.TraceData) error {
+func (s *ThriftTChannelSender) ConsumeTraceData(ctx context.Context, td consumerdata.TraceData) error {
// TODO: (@pjanotti) In case of failure the translation to Jaeger Thrift is going to be remade, cache it somehow.
tBatch, err := jaegertranslator.OCProtoToJaegerThrift(td)
if err != nil {
diff --git a/exporter/jaeger/jaegergrpcexporter/config.go b/exporter/jaeger/jaegergrpcexporter/config.go
new file mode 100644
index 00000000000..2e7c775a8c6
--- /dev/null
+++ b/exporter/jaeger/jaegergrpcexporter/config.go
@@ -0,0 +1,25 @@
+// Copyright 2019, 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 jaegergrpcexporter
+
+import (
+ "github.com/open-telemetry/opentelemetry-service/config/configmodels"
+)
+
+// Config defines configuration for Jaeger gRPC exporter.
+type Config struct {
+ configmodels.ExporterSettings `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct.
+ Endpoint string `mapstructure:"endpoint"`
+}
diff --git a/exporter/jaeger/jaegergrpcexporter/config_test.go b/exporter/jaeger/jaegergrpcexporter/config_test.go
new file mode 100644
index 00000000000..36d2a029457
--- /dev/null
+++ b/exporter/jaeger/jaegergrpcexporter/config_test.go
@@ -0,0 +1,53 @@
+// Copyright 2019, 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 jaegergrpcexporter
+
+import (
+ "path"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+ "go.uber.org/zap"
+
+ "github.com/open-telemetry/opentelemetry-service/config"
+)
+
+func TestLoadConfig(t *testing.T) {
+ receivers, processors, exporters, err := config.ExampleComponents()
+ assert.Nil(t, err)
+
+ factory := &Factory{}
+ exporters[typeStr] = factory
+ cfg, err := config.LoadConfigFile(
+ t, path.Join(".", "testdata", "config.yaml"), receivers, processors, exporters,
+ )
+
+ require.NoError(t, err)
+ require.NotNil(t, cfg)
+
+ e0 := cfg.Exporters["jaeger-grpc"]
+
+ // Endpoint doesn't have a default value so set it directly.
+ defaultCfg := factory.CreateDefaultConfig().(*Config)
+ defaultCfg.Endpoint = "some.target:55678"
+ assert.Equal(t, defaultCfg, e0)
+
+ e1 := cfg.Exporters["jaeger-grpc/2"]
+ assert.Equal(t, "jaeger-grpc/2", e1.(*Config).Name())
+ assert.Equal(t, "a.new.target:1234", e1.(*Config).Endpoint)
+ _, _, err = factory.CreateTraceExporter(zap.NewNop(), e1)
+ require.NoError(t, err)
+}
diff --git a/exporter/jaegerexporter/doc.go b/exporter/jaeger/jaegergrpcexporter/doc.go
similarity index 71%
rename from exporter/jaegerexporter/doc.go
rename to exporter/jaeger/jaegergrpcexporter/doc.go
index 0cae7fb1779..6bd6ac8a620 100644
--- a/exporter/jaegerexporter/doc.go
+++ b/exporter/jaeger/jaegergrpcexporter/doc.go
@@ -12,7 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-// Package jaegerexporter contains a specialized Jaeger exporter. Unlike client
-// library exporters they do not buffer or attempt to resend failed batches, all
-// of that is delegated to the callers of the exporter.
-package jaegerexporter
+// Package jaegergrpcexporter implements an exporter that sends trace data to
+// a Jaeger collector gRPC endpoint.
+package jaegergrpcexporter
diff --git a/exporter/jaegerexporter/jaeger_proto_grpc_sender.go b/exporter/jaeger/jaegergrpcexporter/exporter.go
similarity index 52%
rename from exporter/jaegerexporter/jaeger_proto_grpc_sender.go
rename to exporter/jaeger/jaegergrpcexporter/exporter.go
index 8800e9c71b4..3c5fea2df0d 100644
--- a/exporter/jaegerexporter/jaeger_proto_grpc_sender.go
+++ b/exporter/jaeger/jaegergrpcexporter/exporter.go
@@ -12,58 +12,67 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package jaegerexporter
+package jaegergrpcexporter
import (
"context"
- "go.uber.org/zap"
- "google.golang.org/grpc"
-
jaegerproto "github.com/jaegertracing/jaeger/proto-gen/api_v2"
+ "google.golang.org/grpc"
- "github.com/open-telemetry/opentelemetry-service/consumer"
"github.com/open-telemetry/opentelemetry-service/consumer/consumerdata"
"github.com/open-telemetry/opentelemetry-service/consumer/consumererror"
+ "github.com/open-telemetry/opentelemetry-service/exporter"
+ "github.com/open-telemetry/opentelemetry-service/exporter/exporterhelper"
jaegertranslator "github.com/open-telemetry/opentelemetry-service/translator/trace/jaeger"
)
-// JaegerProtoGRPCSender forwards spans encoded in the jaeger proto
-// format, to a grpc server.
-type JaegerProtoGRPCSender struct {
- client jaegerproto.CollectorServiceClient
- logger *zap.Logger
-}
-
-var _ consumer.TraceConsumer = (*JaegerThriftHTTPSender)(nil)
-
-// NewJaegerProtoGRPCSender returns a new GRPC-backend span sender.
-// The collector endpoint should be of the form "hostname:14250".
-func NewJaegerProtoGRPCSender(collectorEndpoint string, zlogger *zap.Logger) *JaegerProtoGRPCSender {
+// New returns a new Jaeger gRPC exporter.
+// The exporter name is the name to be used in the observability of the exporter.
+// The collectorEndpoint should be of the form "hostname:14250" (a gRPC target).
+func New(exporterName, collectorEndpoint string) (exporter.TraceExporter, error) {
client, err := grpc.Dial(collectorEndpoint, grpc.WithInsecure())
- zlogger.Fatal("Failed to dail grpc connection", zap.Error(err))
+ if err != nil {
+ return nil, err
+ }
+
collectorServiceClient := jaegerproto.NewCollectorServiceClient(client)
- s := &JaegerProtoGRPCSender{
+ s := &protoGRPCSender{
client: collectorServiceClient,
- logger: zlogger,
}
- return s
+ exp, err := exporterhelper.NewTraceExporter(
+ exporterName,
+ s.pushTraceData,
+ exporterhelper.WithSpanName("otelsvc.exporter."+exporterName+".ConsumeTraceData"),
+ exporterhelper.WithRecordMetrics(true))
+
+ return exp, err
}
-// ConsumeTraceData receives consumerdata.TraceData for processing by the JaegerProtoGRPCSender.
-func (s *JaegerProtoGRPCSender) ConsumeTraceData(ctx context.Context, td consumerdata.TraceData) error {
+// protoGRPCSender forwards spans encoded in the jaeger proto
+// format, to a grpc server.
+type protoGRPCSender struct {
+ client jaegerproto.CollectorServiceClient
+}
+
+func (s *protoGRPCSender) pushTraceData(
+ ctx context.Context,
+ td consumerdata.TraceData,
+) (droppedSpans int, err error) {
+
protoBatch, err := jaegertranslator.OCProtoToJaegerProto(td)
if err != nil {
- s.logger.Warn("Error translating OC proto batch to Jaeger proto", zap.Error(err))
- return consumererror.Permanent(err)
+ return len(td.Spans), consumererror.Permanent(err)
}
- _, err = s.client.PostSpans(context.Background(), &jaegerproto.PostSpansRequest{Batch: *protoBatch})
+ _, err = s.client.PostSpans(
+ context.Background(),
+ &jaegerproto.PostSpansRequest{Batch: *protoBatch})
+
if err != nil {
- s.logger.Warn("Error sending grpc batch", zap.Error(err))
- return err
+ droppedSpans = len(protoBatch.Spans)
}
- return nil
+ return droppedSpans, err
}
diff --git a/exporter/jaeger/jaegergrpcexporter/exporter_test.go b/exporter/jaeger/jaegergrpcexporter/exporter_test.go
new file mode 100644
index 00000000000..764d0c52e3c
--- /dev/null
+++ b/exporter/jaeger/jaegergrpcexporter/exporter_test.go
@@ -0,0 +1,67 @@
+// Copyright 2019, 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 jaegergrpcexporter
+
+import (
+ "context"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+
+ "github.com/open-telemetry/opentelemetry-service/consumer/consumerdata"
+)
+
+func TestNew(t *testing.T) {
+ type args struct {
+ exporterName string
+ collectorEndpoint string
+ }
+ tests := []struct {
+ name string
+ args args
+ wantErr bool
+ }{
+ {
+ name: "empty_exporterName",
+ args: args{
+ collectorEndpoint: "127.0.0.1:55678",
+ },
+ wantErr: true,
+ },
+ {
+ name: "createExporter",
+ args: args{
+ exporterName: typeStr,
+ collectorEndpoint: "some.non.existent:55678",
+ },
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ got, err := New(tt.args.exporterName, tt.args.collectorEndpoint)
+ if (err != nil) != tt.wantErr {
+ t.Errorf("New() error = %v, wantErr %v", err, tt.wantErr)
+ return
+ }
+ if got == nil {
+ return
+ }
+
+ // This is expected to fail.
+ err = got.ConsumeTraceData(context.Background(), consumerdata.TraceData{})
+ assert.Error(t, err)
+ })
+ }
+}
diff --git a/exporter/jaeger/jaegergrpcexporter/factory.go b/exporter/jaeger/jaegergrpcexporter/factory.go
new file mode 100644
index 00000000000..abc80c294fd
--- /dev/null
+++ b/exporter/jaeger/jaegergrpcexporter/factory.go
@@ -0,0 +1,81 @@
+// Copyright 2019, 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 jaegergrpcexporter
+
+import (
+ "fmt"
+
+ "go.uber.org/zap"
+
+ "github.com/open-telemetry/opentelemetry-service/config/configerror"
+ "github.com/open-telemetry/opentelemetry-service/config/configmodels"
+ "github.com/open-telemetry/opentelemetry-service/consumer"
+ "github.com/open-telemetry/opentelemetry-service/exporter"
+)
+
+const (
+ // The value of "type" key in configuration.
+ typeStr = "jaeger-grpc"
+)
+
+// Factory is the factory for Jaeger gRPC exporter.
+type Factory struct {
+}
+
+// Type gets the type of the Exporter config created by this factory.
+func (f *Factory) Type() string {
+ return typeStr
+}
+
+// CreateDefaultConfig creates the default configuration for exporter.
+func (f *Factory) CreateDefaultConfig() configmodels.Exporter {
+ return &Config{
+ ExporterSettings: configmodels.ExporterSettings{
+ TypeVal: typeStr,
+ NameVal: typeStr,
+ },
+ }
+}
+
+// CreateTraceExporter creates a trace exporter based on this config.
+func (f *Factory) CreateTraceExporter(
+ logger *zap.Logger,
+ config configmodels.Exporter,
+) (consumer.TraceConsumer, exporter.StopFunc, error) {
+
+ expCfg := config.(*Config)
+ if expCfg.Endpoint == "" {
+ // TODO: Improve error message, see #215
+ err := fmt.Errorf(
+ "%q config requires a non-empty \"endpoint\"",
+ expCfg.Name())
+ return nil, nil, err
+ }
+
+ exp, err := New(expCfg.Name(), expCfg.Endpoint)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ return exp, nil, nil
+}
+
+// CreateMetricsExporter creates a metrics exporter based on this config.
+func (f *Factory) CreateMetricsExporter(
+ logger *zap.Logger,
+ cfg configmodels.Exporter,
+) (consumer.MetricsConsumer, exporter.StopFunc, error) {
+ return nil, nil, configerror.ErrDataTypeIsNotSupported
+}
diff --git a/exporter/jaeger/jaegergrpcexporter/factory_test.go b/exporter/jaeger/jaegergrpcexporter/factory_test.go
new file mode 100644
index 00000000000..e96ca4f22f2
--- /dev/null
+++ b/exporter/jaeger/jaegergrpcexporter/factory_test.go
@@ -0,0 +1,65 @@
+// Copyright 2019, 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 jaegergrpcexporter
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "go.uber.org/zap"
+
+ "github.com/open-telemetry/opentelemetry-service/config/configerror"
+)
+
+func TestCreateDefaultConfig(t *testing.T) {
+ factory := Factory{}
+ cfg := factory.CreateDefaultConfig()
+ assert.NotNil(t, cfg, "failed to create default config")
+}
+
+func TestCreateMetricsExporter(t *testing.T) {
+ factory := Factory{}
+ cfg := factory.CreateDefaultConfig()
+
+ _, _, err := factory.CreateMetricsExporter(zap.NewNop(), cfg)
+ assert.Error(t, err, configerror.ErrDataTypeIsNotSupported)
+}
+
+func TestCreateInstanceViaFactory(t *testing.T) {
+ factory := Factory{}
+
+ cfg := factory.CreateDefaultConfig()
+
+ // Default config doesn't have default endpoint so creating from it should
+ // fail.
+ exp, expStopFn, err := factory.CreateTraceExporter(
+ zap.NewNop(),
+ cfg)
+ assert.Error(t, err)
+ assert.Nil(t, exp)
+ assert.Nil(t, expStopFn)
+
+ // Endpoint doesn't have a default value so set it directly.
+ expCfg := cfg.(*Config)
+ expCfg.Endpoint = "some.target.org:12345"
+ exp, expStopFn, err = factory.CreateTraceExporter(
+ zap.NewNop(),
+ cfg)
+ assert.NoError(t, err)
+ assert.NotNil(t, exp)
+
+ // Currently this exporter doesn't have a stop function.
+ assert.Nil(t, expStopFn)
+}
diff --git a/exporter/jaeger/jaegergrpcexporter/testdata/config.yaml b/exporter/jaeger/jaegergrpcexporter/testdata/config.yaml
new file mode 100644
index 00000000000..c7672dd0022
--- /dev/null
+++ b/exporter/jaeger/jaegergrpcexporter/testdata/config.yaml
@@ -0,0 +1,17 @@
+receivers:
+ examplereceiver:
+
+processors:
+ exampleprocessor:
+
+exporters:
+ jaeger-grpc:
+ endpoint: "some.target:55678"
+ jaeger-grpc/2:
+ endpoint: "a.new.target:1234"
+
+pipelines:
+ traces:
+ receivers: [examplereceiver]
+ processors: [exampleprocessor]
+ exporters: [jaeger-grpc, jaeger-grpc/2]
\ No newline at end of file