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:
parent
0eb73325ce
commit
fa7d053793
@ -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.
|
||||
|
||||
|
||||
|
@ -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")
|
||||
}
|
||||
|
@ -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=
|
||||
|
@ -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)
|
||||
}
|
||||
|
16
exporter/trace/stdout/doc.go
Normal file
16
exporter/trace/stdout/doc.go
Normal 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"
|
61
exporter/trace/stdout/stdout.go
Normal file
61
exporter/trace/stdout/stdout.go
Normal 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')))
|
||||
}
|
101
exporter/trace/stdout/stdout_test.go
Normal file
101
exporter/trace/stdout/stdout_test.go
Normal 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)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user