forked from open-telemetry/opentelemetry-collector-contrib
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
opentelemetry collector trace exporter (#497)
* opentelemetry collector exporter - missing load test - missing resources * fix review comments. * add test for each SpanKind and Attribute Type. * rename otelcol to otlp * move exporter/trace/otlp to exporters/otlp * more review comments. * add alignment test. * pass context to uploadSpans
- Loading branch information
Showing
13 changed files
with
1,688 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# OpenTelemetry Collector Go Exporter | ||
|
||
[![GoDoc][godoc-image]][godoc-url] | ||
|
||
|
||
This exporter converts OpenTelemetry [SpanData](https://github.com/open-telemetry/opentelemetry-go/blob/6769330394f78192df01cb59299e9e0f2e5e977b/sdk/export/trace/trace.go#L49) | ||
to OpenTelemetry Protocol [Span](https://github.com/open-telemetry/opentelemetry-proto/blob/c20698d5bb483cf05de1a7c0e134b7c57e359674/opentelemetry/proto/trace/v1/trace.proto#L46) | ||
and exports them to OpenTelemetry Collector. | ||
|
||
|
||
## Installation | ||
|
||
```bash | ||
$ go get -u go.opentelemetry.io/otel/exporters/otlp | ||
``` | ||
|
||
[godoc-url]: https://godoc.org/go.opentelemetry.io/otel/exporters/otlp | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// Copyright 2020, 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 otlp | ||
|
||
import ( | ||
"os" | ||
"testing" | ||
"unsafe" | ||
|
||
ottest "go.opentelemetry.io/otel/internal/testing" | ||
) | ||
|
||
// Ensure struct alignment prior to running tests. | ||
func TestMain(m *testing.M) { | ||
fields := []ottest.FieldOffset{ | ||
{ | ||
Name: "Exporter.lastConnectErrPtr", | ||
Offset: unsafe.Offsetof(Exporter{}.lastConnectErrPtr), | ||
}, | ||
} | ||
if !ottest.Aligned8Byte(fields, os.Stderr) { | ||
os.Exit(1) | ||
} | ||
|
||
os.Exit(m.Run()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
// Copyright 2020, 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 otlp | ||
|
||
import ( | ||
"math/rand" | ||
"sync/atomic" | ||
"time" | ||
"unsafe" | ||
) | ||
|
||
func (e *Exporter) lastConnectError() error { | ||
errPtr := (*error)(atomic.LoadPointer(&e.lastConnectErrPtr)) | ||
if errPtr == nil { | ||
return nil | ||
} | ||
return *errPtr | ||
} | ||
|
||
func (e *Exporter) saveLastConnectError(err error) { | ||
var errPtr *error | ||
if err != nil { | ||
errPtr = &err | ||
} | ||
atomic.StorePointer(&e.lastConnectErrPtr, unsafe.Pointer(errPtr)) | ||
} | ||
|
||
func (e *Exporter) setStateDisconnected(err error) { | ||
e.saveLastConnectError(err) | ||
select { | ||
case e.disconnectedCh <- true: | ||
default: | ||
} | ||
} | ||
|
||
func (e *Exporter) setStateConnected() { | ||
e.saveLastConnectError(nil) | ||
} | ||
|
||
func (e *Exporter) connected() bool { | ||
return e.lastConnectError() == nil | ||
} | ||
|
||
const defaultConnReattemptPeriod = 10 * time.Second | ||
|
||
func (e *Exporter) indefiniteBackgroundConnection() { | ||
defer func() { | ||
e.backgroundConnectionDoneCh <- true | ||
}() | ||
|
||
connReattemptPeriod := e.c.reconnectionPeriod | ||
if connReattemptPeriod <= 0 { | ||
connReattemptPeriod = defaultConnReattemptPeriod | ||
} | ||
|
||
// No strong seeding required, nano time can | ||
// already help with pseudo uniqueness. | ||
rng := rand.New(rand.NewSource(time.Now().UnixNano() + rand.Int63n(1024))) | ||
|
||
// maxJitterNanos: 70% of the connectionReattemptPeriod | ||
maxJitterNanos := int64(0.7 * float64(connReattemptPeriod)) | ||
|
||
for { | ||
// Otherwise these will be the normal scenarios to enable | ||
// reconnection if we trip out. | ||
// 1. If we've stopped, return entirely | ||
// 2. Otherwise block until we are disconnected, and | ||
// then retry connecting | ||
select { | ||
case <-e.stopCh: | ||
return | ||
|
||
case <-e.disconnectedCh: | ||
// Normal scenario that we'll wait for | ||
} | ||
|
||
if err := e.connect(); err == nil { | ||
e.setStateConnected() | ||
} else { | ||
e.setStateDisconnected(err) | ||
} | ||
|
||
// Apply some jitter to avoid lockstep retrials of other | ||
// collector-exporters. Lockstep retrials could result in an | ||
// innocent DDOS, by clogging the machine's resources and network. | ||
jitter := time.Duration(rng.Int63n(maxJitterNanos)) | ||
select { | ||
case <-e.stopCh: | ||
return | ||
case <-time.After(connReattemptPeriod + jitter): | ||
} | ||
} | ||
} | ||
|
||
func (e *Exporter) connect() error { | ||
cc, err := e.dialToCollector() | ||
if err != nil { | ||
return err | ||
} | ||
return e.enableConnections(cc) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// Copyright 2020, 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 otlp contains an OpenTelemetry tracing exporter for OpenTelemetry Collector. | ||
package otlp // import "go.opentelemetry.io/otel/exporters/otlp" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
// Copyright 2020, 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 otlp_test | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"log" | ||
"time" | ||
|
||
"google.golang.org/grpc/credentials" | ||
|
||
"go.opentelemetry.io/otel/api/global" | ||
"go.opentelemetry.io/otel/exporters/otlp" | ||
sdktrace "go.opentelemetry.io/otel/sdk/trace" | ||
) | ||
|
||
func Example_insecure() { | ||
exp, err := otlp.NewExporter(otlp.WithInsecure()) | ||
if err != nil { | ||
log.Fatalf("Failed to create the collector exporter: %v", err) | ||
} | ||
defer func() { | ||
_ = exp.Stop() | ||
}() | ||
|
||
tp, _ := sdktrace.NewProvider( | ||
sdktrace.WithConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}), | ||
sdktrace.WithBatcher(exp, // add following two options to ensure flush | ||
sdktrace.WithScheduleDelayMillis(5), | ||
sdktrace.WithMaxExportBatchSize(10), | ||
)) | ||
if err != nil { | ||
log.Fatalf("error creating trace provider: %v\n", err) | ||
} | ||
|
||
global.SetTraceProvider(tp) | ||
|
||
tracer := global.TraceProvider().Tracer("test-tracer") | ||
|
||
// Then use the OpenTelemetry tracing library, like we normally would. | ||
ctx, span := tracer.Start(context.Background(), "CollectorExporter-Example") | ||
defer span.End() | ||
|
||
for i := 0; i < 10; i++ { | ||
_, iSpan := tracer.Start(ctx, fmt.Sprintf("Sample-%d", i)) | ||
<-time.After(6 * time.Millisecond) | ||
iSpan.End() | ||
} | ||
} | ||
|
||
func Example_withTLS() { | ||
// Please take at look at https://godoc.org/google.golang.org/grpc/credentials#TransportCredentials | ||
// for ways on how to initialize gRPC TransportCredentials. | ||
creds, err := credentials.NewClientTLSFromFile("my-cert.pem", "") | ||
if err != nil { | ||
log.Fatalf("failed to create gRPC client TLS credentials: %v", err) | ||
} | ||
|
||
exp, err := otlp.NewExporter(otlp.WithTLSCredentials(creds)) | ||
if err != nil { | ||
log.Fatalf("failed to create the collector exporter: %v", err) | ||
} | ||
defer func() { | ||
_ = exp.Stop() | ||
}() | ||
|
||
tp, err := sdktrace.NewProvider( | ||
sdktrace.WithConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}), | ||
sdktrace.WithBatcher(exp, // add following two options to ensure flush | ||
sdktrace.WithScheduleDelayMillis(5), | ||
sdktrace.WithMaxExportBatchSize(10), | ||
)) | ||
if err != nil { | ||
log.Fatalf("error creating trace provider: %v\n", err) | ||
} | ||
|
||
global.SetTraceProvider(tp) | ||
|
||
tracer := global.TraceProvider().Tracer("test-tracer") | ||
|
||
// Then use the OpenTelemetry tracing library, like we normally would. | ||
ctx, span := tracer.Start(context.Background(), "Securely-Talking-To-Collector-Span") | ||
defer span.End() | ||
|
||
for i := 0; i < 10; i++ { | ||
_, iSpan := tracer.Start(ctx, fmt.Sprintf("Sample-%d", i)) | ||
<-time.After(6 * time.Millisecond) | ||
iSpan.End() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
module go.opentelemetry.io/otel/exporters/otlp | ||
|
||
replace go.opentelemetry.io/otel => ../.. | ||
|
||
require ( | ||
github.com/golang/protobuf v1.3.2 | ||
github.com/google/go-cmp v0.4.0 | ||
github.com/open-telemetry/opentelemetry-proto v0.0.0-20200219184922-5e1d5bc66d5a | ||
github.com/stretchr/testify v1.4.0 | ||
go.opentelemetry.io/otel v0.2.3 | ||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7 // indirect | ||
golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7 // indirect | ||
golang.org/x/text v0.3.2 // indirect | ||
google.golang.org/grpc v1.27.1 | ||
) | ||
|
||
go 1.13 |
Oops, something went wrong.