1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2025-01-03 22:52:30 +02:00

Add stdout trace exporter (#153)

* Add stdout trace exporter (#134)

* Update go.mod and go.sum

* Do not use assert in tests
This commit is contained in:
Steven Karis 2019-09-28 11:27:02 -07:00 committed by rghetia
parent 0eb73325ce
commit fa7d053793
7 changed files with 189 additions and 32 deletions

View File

@ -28,32 +28,20 @@ Example uses
GO111MODULE="" go get -d go.opentelemetry.io
```
#### 2 Start All-in-one Jaeger
```
docker run -d --name jaeger \
-p 16686:16686 \
-p 14268:14268 \
jaegertracing/all-in-one:1.8
```
#### 3 Start Server
#### 2 Start Server
```
cd $GOPATH/src/go.opentelemetry.io/example/http/
go run ./server/server.go
```
#### 4 Start Client
#### 3 Start Client
```
cd $GOPATH/src/go.opentelemetry.io/example/http/
go run ./client/client.go
```
#### 5 Check traces on Jaeger UI
#### 4 Check traces in stdout
Visit http://localhost:16686 with a web browser
Click on 'Find' to see traces.
[Sample Snapshot](http/images/JaegarTraceExample.png)
The spans should be visible in stdout in the order that they were exported.

View File

@ -28,7 +28,7 @@ import (
"go.opentelemetry.io/api/key"
"go.opentelemetry.io/api/tag"
"go.opentelemetry.io/api/trace"
"go.opentelemetry.io/exporter/trace/jaeger"
"go.opentelemetry.io/exporter/trace/stdout"
"go.opentelemetry.io/plugin/httptrace"
sdktrace "go.opentelemetry.io/sdk/trace"
)
@ -37,14 +37,9 @@ func initTracer() {
// Register SDK as trace provider.
sdktrace.Register()
// Create Jaeger exporter to be able to retrieve
// Create stdout exporter to be able to retrieve
// the collected spans.
exporter, err := jaeger.NewExporter(jaeger.Options{
CollectorEndpoint: "http://localhost:14268/api/traces",
Process: jaeger.Process{
ServiceName: "trace-demo",
},
})
exporter, err := stdout.NewExporter(stdout.Options{PrettyPrint: true})
if err != nil {
log.Fatal(err)
}
@ -94,5 +89,5 @@ func main() {
fmt.Printf("Response Received: %s\n\n\n", body)
fmt.Printf("Waiting for few seconds to export spans ...\n\n")
time.Sleep(10 * time.Second)
fmt.Printf("Check traces on http://localhost:16686\n")
fmt.Printf("Inspect traces on stdout")
}

View File

@ -84,6 +84,7 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/magiconair/properties v1.7.6 h1:U+1DqNen04MdEPgFiIwdOUiqZ8qPa37xgogX/sd3+54=
github.com/magiconair/properties v1.7.6/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=

View File

@ -21,7 +21,7 @@ import (
"go.opentelemetry.io/api/tag"
"go.opentelemetry.io/api/trace"
"go.opentelemetry.io/exporter/trace/jaeger"
"go.opentelemetry.io/exporter/trace/stdout"
"go.opentelemetry.io/plugin/httptrace"
sdktrace "go.opentelemetry.io/sdk/trace"
)
@ -31,12 +31,7 @@ func initTracer() {
// Create Jaeger exporter to be able to retrieve
// the collected spans.
exporter, err := jaeger.NewExporter(jaeger.Options{
CollectorEndpoint: "http://localhost:14268/api/traces",
Process: jaeger.Process{
ServiceName: "trace-demo",
},
})
exporter, err := stdout.NewExporter(stdout.Options{PrettyPrint: true})
if err != nil {
log.Fatal(err)
}

View File

@ -0,0 +1,16 @@
// 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 stdout contains an OpenTelemetry tracing exporter for writing to stdout.
package stdout // import "go.opentelemetry.io/exporter/trace/stdout"

View File

@ -0,0 +1,61 @@
// 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 stdout
import (
"encoding/json"
"io"
"os"
"go.opentelemetry.io/sdk/trace"
)
// Options are the options to be used when initializing a stdout exporter.
type Options struct {
// PrettyPrint will pretty the json representation of the span,
// making it print "pretty". Default is false.
PrettyPrint bool
}
// Exporter is an implementation of trace.Exporter that writes spans to stdout.
type Exporter struct {
pretty bool
outputWriter io.Writer
}
func NewExporter(o Options) (*Exporter, error) {
return &Exporter{
pretty: o.PrettyPrint,
outputWriter: os.Stdout,
}, nil
}
// ExportSpan writes a SpanData in json format to stdout.
func (e *Exporter) ExportSpan(data *trace.SpanData) {
var jsonSpan []byte
var err error
if e.pretty {
jsonSpan, err = json.MarshalIndent(data, "", "\t")
} else {
jsonSpan, err = json.Marshal(data)
}
if err != nil {
// ignore writer failures for now
_, _ = e.outputWriter.Write([]byte("Error converting spanData to json: " + err.Error()))
return
}
// ignore writer failures for now
_, _ = e.outputWriter.Write(append(jsonSpan, byte('\n')))
}

View File

@ -0,0 +1,101 @@
// 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 stdout
import (
"bytes"
"encoding/json"
"testing"
"time"
"google.golang.org/grpc/codes"
"go.opentelemetry.io/api/core"
"go.opentelemetry.io/sdk/trace"
)
func TestExporter_ExportSpan(t *testing.T) {
exporter, err := NewExporter(Options{})
if err != nil {
t.Errorf("Error constructing stdout exporter %s", err)
}
// override output writer for testing
var b bytes.Buffer
exporter.outputWriter = &b
// setup test span
now := time.Now()
traceID := core.TraceID{High: 0x0102030405060708, Low: 0x090a0b0c0d0e0f10}
spanID := uint64(0x0102030405060708)
keyValue := "value"
doubleValue := float64(123.456)
testSpan := &trace.SpanData{
SpanContext: core.SpanContext{
TraceID: traceID,
SpanID: spanID,
},
Name: "/foo",
StartTime: now,
EndTime: now,
Attributes: []core.KeyValue{
{
Key: core.Key{Name: "key"},
Value: core.Value{Type: core.STRING, String: keyValue},
},
{
Key: core.Key{Name: "double"},
Value: core.Value{Type: core.FLOAT64, Float64: doubleValue},
},
},
Status: codes.Unknown,
}
exporter.ExportSpan(testSpan)
expectedSerializedNow, _ := json.Marshal(now)
got := b.String()
expectedOutput := `{"SpanContext":{` +
`"TraceID":{"High":72623859790382856,"Low":651345242494996240},` +
`"SpanID":72623859790382856,"TraceFlags":0},` +
`"ParentSpanID":0,` +
`"SpanKind":0,` +
`"Name":"/foo",` +
`"StartTime":` + string(expectedSerializedNow) + "," +
`"EndTime":` + string(expectedSerializedNow) + "," +
`"Attributes":[` +
`{` +
`"Key":{"Name":"key"},` +
`"Value":{"Type":8,"Bool":false,"Int64":0,"Uint64":0,"Float64":0,"String":"value","Bytes":null}` +
`},` +
`{` +
`"Key":{"Name":"double"},` +
`"Value":{"Type":7,"Bool":false,"Int64":0,"Uint64":0,"Float64":123.456,"String":"","Bytes":null}` +
`}` +
`],` +
`"MessageEvents":null,` +
`"Links":null,` +
`"Status":2,` +
`"HasRemoteParent":false,` +
`"DroppedAttributeCount":0,` +
`"DroppedMessageEventCount":0,` +
`"DroppedLinkCount":0,` +
`"ChildSpanCount":0}` + "\n"
if got != expectedOutput {
t.Errorf("Want: %v but got: %v", expectedOutput, got)
}
}