You've already forked opentelemetry-go
mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-11-27 22:49:15 +02:00
Update example to use jaeger exporter and update Readme (#143)
* update http example to use jaeger exporter and sdk. * update image location. * remove extra parameters for jaeger.
This commit is contained in:
59
example/README.md
Normal file
59
example/README.md
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# Example
|
||||||
|
|
||||||
|
## HTTP
|
||||||
|
This is a simple example that demonstrates tracing http request from client to server. The example
|
||||||
|
shows key aspects of tracing such as
|
||||||
|
- Root Span (on Client)
|
||||||
|
- Child Span (on Client)
|
||||||
|
- Child Span from a Remote Parent (on Server)
|
||||||
|
- SpanContext Propagation (from Client to Server)
|
||||||
|
- Span Events
|
||||||
|
- Span Attributes
|
||||||
|
|
||||||
|
Example uses
|
||||||
|
- open-telemetry SDK as trace instrumentation provider,
|
||||||
|
- httptrace plugin to facilitate tracing http request on client and server
|
||||||
|
- http trace_context propagation to propagate SpanContext on the wire.
|
||||||
|
- jaeger exporter to export spans to visualize and store them.
|
||||||
|
|
||||||
|
### How to run?
|
||||||
|
|
||||||
|
#### Prequisites
|
||||||
|
|
||||||
|
- go 1.12 installed
|
||||||
|
- GOPATH is configured.
|
||||||
|
|
||||||
|
#### 1 Download git repo
|
||||||
|
```
|
||||||
|
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
|
||||||
|
```
|
||||||
|
cd $GOPATH/src/go.opentelemetry.io/example/http/
|
||||||
|
go run ./server/server.go
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4 Start Client
|
||||||
|
```
|
||||||
|
cd $GOPATH/src/go.opentelemetry.io/example/http/
|
||||||
|
go run ./client/client.go
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 5 Check traces on Jaeger UI
|
||||||
|
|
||||||
|
Visit http://localhost:16686 with a web browser
|
||||||
|
Click on 'Find' to see traces.
|
||||||
|
|
||||||
|
[Sample Snapshot](http/images/JaegarTraceExample.png)
|
||||||
|
|
||||||
|
|
||||||
@@ -18,27 +18,49 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
|
|
||||||
"go.opentelemetry.io/api/key"
|
"go.opentelemetry.io/api/key"
|
||||||
"go.opentelemetry.io/api/tag"
|
"go.opentelemetry.io/api/tag"
|
||||||
"go.opentelemetry.io/api/trace"
|
"go.opentelemetry.io/api/trace"
|
||||||
|
"go.opentelemetry.io/exporter/trace/jaeger"
|
||||||
"go.opentelemetry.io/plugin/httptrace"
|
"go.opentelemetry.io/plugin/httptrace"
|
||||||
|
sdktrace "go.opentelemetry.io/sdk/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
func initTracer() {
|
||||||
tracer = trace.GlobalTracer().
|
// Register SDK as trace provider.
|
||||||
WithService("client").
|
sdktrace.Register()
|
||||||
WithComponent("main").
|
|
||||||
WithResources(
|
// Create Jaeger exporter to be able to retrieve
|
||||||
key.New("whatevs").String("yesss"),
|
// the collected spans.
|
||||||
)
|
exporter, err := jaeger.NewExporter(jaeger.Options{
|
||||||
)
|
CollectorEndpoint: "http://localhost:14268/api/traces",
|
||||||
|
Process: jaeger.Process{
|
||||||
|
ServiceName: "trace-demo",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap Jaeger exporter with SimpleSpanProcessor and register the processor.
|
||||||
|
ssp := sdktrace.NewSimpleSpanProcessor(exporter)
|
||||||
|
sdktrace.RegisterSpanProcessor(ssp)
|
||||||
|
|
||||||
|
// For the demonstration, use sdktrace.AlwaysSample sampler to sample all traces.
|
||||||
|
// In a production application, use sdktrace.ProbabilitySampler with a desired probability.
|
||||||
|
sdktrace.ApplyConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()})
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Printf("Tracer %v\n", tracer)
|
initTracer()
|
||||||
|
|
||||||
client := http.DefaultClient
|
client := http.DefaultClient
|
||||||
ctx := tag.NewContext(context.Background(),
|
ctx := tag.NewContext(context.Background(),
|
||||||
tag.Insert(key.New("username").String("donuts")),
|
tag.Insert(key.New("username").String("donuts")),
|
||||||
@@ -46,13 +68,14 @@ func main() {
|
|||||||
|
|
||||||
var body []byte
|
var body []byte
|
||||||
|
|
||||||
err := tracer.WithSpan(ctx, "say hello",
|
err := trace.GlobalTracer().WithSpan(ctx, "say hello",
|
||||||
func(ctx context.Context) error {
|
func(ctx context.Context) error {
|
||||||
req, _ := http.NewRequest("GET", "http://localhost:7777/hello", nil)
|
req, _ := http.NewRequest("GET", "http://localhost:7777/hello", nil)
|
||||||
|
|
||||||
ctx, req = httptrace.W3C(ctx, req)
|
ctx, req = httptrace.W3C(ctx, req)
|
||||||
httptrace.Inject(ctx, req)
|
httptrace.Inject(ctx, req)
|
||||||
|
|
||||||
|
fmt.Printf("Sending request...\n")
|
||||||
res, err := client.Do(req)
|
res, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@@ -68,5 +91,8 @@ func main() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("%s", body)
|
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")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSR
|
|||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/OpenPeeDeeP/depguard v1.0.0/go.mod h1:7/4sitnI9YlQgTLLk734QlzXT8DuHVnAyztLplQjk+o=
|
github.com/OpenPeeDeeP/depguard v1.0.0/go.mod h1:7/4sitnI9YlQgTLLk734QlzXT8DuHVnAyztLplQjk+o=
|
||||||
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||||
|
github.com/apache/thrift v0.12.0 h1:pODnxUFNcjP9UTLZGTdeh+j16A8lJbRvD3rOtrk/7bs=
|
||||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
@@ -64,6 +65,7 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m
|
|||||||
github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
|
github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
|
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
|
||||||
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||||
github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=
|
github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=
|
||||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||||
@@ -188,6 +190,7 @@ golang.org/x/tools v0.0.0-20190909030654-5b82db07426d/go.mod h1:b+2E5dAYhXwXZwtn
|
|||||||
golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||||
|
google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8=
|
||||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
|||||||
BIN
example/http/images/JaegarTraceExample.png
Normal file
BIN
example/http/images/JaegarTraceExample.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 184 KiB |
@@ -16,24 +16,43 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"go.opentelemetry.io/api/key"
|
|
||||||
"go.opentelemetry.io/api/tag"
|
"go.opentelemetry.io/api/tag"
|
||||||
"go.opentelemetry.io/api/trace"
|
"go.opentelemetry.io/api/trace"
|
||||||
|
"go.opentelemetry.io/exporter/trace/jaeger"
|
||||||
"go.opentelemetry.io/plugin/httptrace"
|
"go.opentelemetry.io/plugin/httptrace"
|
||||||
|
sdktrace "go.opentelemetry.io/sdk/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
func initTracer() {
|
||||||
tracer = trace.GlobalTracer().
|
sdktrace.Register()
|
||||||
WithService("server").
|
|
||||||
WithComponent("main").
|
// Create Jaeger exporter to be able to retrieve
|
||||||
WithResources(
|
// the collected spans.
|
||||||
key.New("whatevs").String("nooooo"),
|
exporter, err := jaeger.NewExporter(jaeger.Options{
|
||||||
)
|
CollectorEndpoint: "http://localhost:14268/api/traces",
|
||||||
)
|
Process: jaeger.Process{
|
||||||
|
ServiceName: "trace-demo",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap Jaeger exporter with SimpleSpanProcessor and register the processor.
|
||||||
|
ssp := sdktrace.NewSimpleSpanProcessor(exporter)
|
||||||
|
sdktrace.RegisterSpanProcessor(ssp)
|
||||||
|
|
||||||
|
// For the demonstration, use sdktrace.AlwaysSample sampler to sample all traces.
|
||||||
|
// In a production application, use sdktrace.ProbabilitySampler with a desired probability.
|
||||||
|
sdktrace.ApplyConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()})
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
initTracer()
|
||||||
|
|
||||||
helloHandler := func(w http.ResponseWriter, req *http.Request) {
|
helloHandler := func(w http.ResponseWriter, req *http.Request) {
|
||||||
attrs, tags, spanCtx := httptrace.Extract(req.Context(), req)
|
attrs, tags, spanCtx := httptrace.Extract(req.Context(), req)
|
||||||
|
|
||||||
@@ -41,7 +60,7 @@ func main() {
|
|||||||
MultiKV: tags,
|
MultiKV: tags,
|
||||||
})))
|
})))
|
||||||
|
|
||||||
ctx, span := tracer.Start(
|
ctx, span := trace.GlobalTracer().Start(
|
||||||
req.Context(),
|
req.Context(),
|
||||||
"hello",
|
"hello",
|
||||||
trace.WithAttributes(attrs...),
|
trace.WithAttributes(attrs...),
|
||||||
|
|||||||
@@ -22,13 +22,12 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
|
||||||
|
|
||||||
"google.golang.org/grpc/codes"
|
|
||||||
|
|
||||||
"github.com/apache/thrift/lib/go/thrift"
|
"github.com/apache/thrift/lib/go/thrift"
|
||||||
"google.golang.org/api/support/bundler"
|
"google.golang.org/api/support/bundler"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
|
||||||
|
"go.opentelemetry.io/api/core"
|
||||||
gen "go.opentelemetry.io/exporter/trace/jaeger/internal/gen-go/jaeger"
|
gen "go.opentelemetry.io/exporter/trace/jaeger/internal/gen-go/jaeger"
|
||||||
"go.opentelemetry.io/sdk/trace"
|
"go.opentelemetry.io/sdk/trace"
|
||||||
)
|
)
|
||||||
@@ -165,38 +164,33 @@ func (e *Exporter) ExportSpan(data *trace.SpanData) {
|
|||||||
|
|
||||||
func spanDataToThrift(data *trace.SpanData) *gen.Span {
|
func spanDataToThrift(data *trace.SpanData) *gen.Span {
|
||||||
tags := make([]*gen.Tag, 0, len(data.Attributes))
|
tags := make([]*gen.Tag, 0, len(data.Attributes))
|
||||||
for k, v := range data.Attributes {
|
for _, kv := range data.Attributes {
|
||||||
tag := attributeToTag(k, v)
|
tag := coreAttributeToTag(kv)
|
||||||
if tag != nil {
|
tags = append(tags, tag)
|
||||||
tags = append(tags, tag)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tags = append(tags,
|
tags = append(tags, getInt64Tag("status.code", int64(data.Status)),
|
||||||
attributeToTag("status.code", int32(data.Status)),
|
getStringTag("status.message", data.Status.String()),
|
||||||
attributeToTag("status.message", data.Status.String()),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ensure that if Status.Code is not OK, that we set the "error" tag on the Jaeger span.
|
// Ensure that if Status.Code is not OK, that we set the "error" tag on the Jaeger span.
|
||||||
// See Issue https://github.com/census-instrumentation/opencensus-go/issues/1041
|
// See Issue https://github.com/census-instrumentation/opencensus-go/issues/1041
|
||||||
if data.Status != codes.OK {
|
if data.Status != codes.OK {
|
||||||
tags = append(tags, attributeToTag("error", true))
|
tags = append(tags, getBoolTag("error", true))
|
||||||
}
|
}
|
||||||
|
|
||||||
var logs []*gen.Log
|
var logs []*gen.Log
|
||||||
for _, a := range data.MessageEvents {
|
for _, a := range data.MessageEvents {
|
||||||
fields := make([]*gen.Tag, 0, len(a.Attributes))
|
fields := make([]*gen.Tag, 0, len(a.Attributes))
|
||||||
for _, kv := range a.Attributes {
|
for _, kv := range a.Attributes {
|
||||||
tag := attributeToTag(kv.Key.Name, kv.Value.Emit())
|
tag := coreAttributeToTag(kv)
|
||||||
if tag != nil {
|
if tag != nil {
|
||||||
fields = append(fields, tag)
|
fields = append(fields, tag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fields = append(fields, attributeToTag("message", a.Message))
|
fields = append(fields, getStringTag("message", a.Message))
|
||||||
logs = append(logs, &gen.Log{
|
logs = append(logs, &gen.Log{
|
||||||
//Timestamp: a.Time.UnixNano() / 1000,
|
Timestamp: a.Time.UnixNano() / 1000,
|
||||||
//TODO: [rghetia] update when time is supported in the event.
|
|
||||||
Timestamp: time.Now().UnixNano() / 1000,
|
|
||||||
Fields: fields,
|
Fields: fields,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -227,6 +221,61 @@ func spanDataToThrift(data *trace.SpanData) *gen.Span {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func coreAttributeToTag(kv core.KeyValue) *gen.Tag {
|
||||||
|
var tag *gen.Tag
|
||||||
|
switch kv.Value.Type {
|
||||||
|
case core.STRING:
|
||||||
|
tag = &gen.Tag{
|
||||||
|
Key: kv.Key.Name,
|
||||||
|
VStr: &kv.Value.String,
|
||||||
|
VType: gen.TagType_STRING,
|
||||||
|
}
|
||||||
|
case core.BOOL:
|
||||||
|
tag = &gen.Tag{
|
||||||
|
Key: kv.Key.Name,
|
||||||
|
VBool: &kv.Value.Bool,
|
||||||
|
VType: gen.TagType_BOOL,
|
||||||
|
}
|
||||||
|
case core.INT32, core.INT64:
|
||||||
|
tag = &gen.Tag{
|
||||||
|
Key: kv.Key.Name,
|
||||||
|
VLong: &kv.Value.Int64,
|
||||||
|
VType: gen.TagType_LONG,
|
||||||
|
}
|
||||||
|
case core.FLOAT32, core.FLOAT64:
|
||||||
|
tag = &gen.Tag{
|
||||||
|
Key: kv.Key.Name,
|
||||||
|
VDouble: &kv.Value.Float64,
|
||||||
|
VType: gen.TagType_DOUBLE,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tag
|
||||||
|
}
|
||||||
|
|
||||||
|
func getInt64Tag(k string, i int64) *gen.Tag {
|
||||||
|
return &gen.Tag{
|
||||||
|
Key: k,
|
||||||
|
VLong: &i,
|
||||||
|
VType: gen.TagType_LONG,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getStringTag(k, s string) *gen.Tag {
|
||||||
|
return &gen.Tag{
|
||||||
|
Key: k,
|
||||||
|
VStr: &s,
|
||||||
|
VType: gen.TagType_STRING,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBoolTag(k string, b bool) *gen.Tag {
|
||||||
|
return &gen.Tag{
|
||||||
|
Key: k,
|
||||||
|
VBool: &b,
|
||||||
|
VType: gen.TagType_BOOL,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(rghetia): remove interface{}. see https://github.com/open-telemetry/opentelemetry-go/pull/112/files#r321444786
|
// TODO(rghetia): remove interface{}. see https://github.com/open-telemetry/opentelemetry-go/pull/112/files#r321444786
|
||||||
func attributeToTag(key string, a interface{}) *gen.Tag {
|
func attributeToTag(key string, a interface{}) *gen.Tag {
|
||||||
var tag *gen.Tag
|
var tag *gen.Tag
|
||||||
|
|||||||
@@ -55,9 +55,15 @@ func Test_spanDataToThrift(t *testing.T) {
|
|||||||
Name: "/foo",
|
Name: "/foo",
|
||||||
StartTime: now,
|
StartTime: now,
|
||||||
EndTime: now,
|
EndTime: now,
|
||||||
Attributes: map[string]interface{}{
|
Attributes: []core.KeyValue{
|
||||||
"double": doubleValue,
|
{
|
||||||
"key": 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},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
// TODO: [rghetia] add events test after event is concrete type.
|
// TODO: [rghetia] add events test after event is concrete type.
|
||||||
Status: codes.Unknown,
|
Status: codes.Unknown,
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ type SpanData struct {
|
|||||||
// from StartTime by the duration of the span.
|
// from StartTime by the duration of the span.
|
||||||
EndTime time.Time
|
EndTime time.Time
|
||||||
// The values of Attributes each have type string, bool, or int64.
|
// The values of Attributes each have type string, bool, or int64.
|
||||||
Attributes map[string]interface{}
|
Attributes []core.KeyValue
|
||||||
MessageEvents []Event
|
MessageEvents []Event
|
||||||
Links []apitrace.Link
|
Links []apitrace.Link
|
||||||
Status codes.Code
|
Status codes.Code
|
||||||
|
|||||||
@@ -272,13 +272,14 @@ func (s *span) interfaceArrayToMessageEventArray() []Event {
|
|||||||
return messageEventArr
|
return messageEventArr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *span) lruAttributesToAttributeMap() map[string]interface{} {
|
func (s *span) lruAttributesToAttributeMap() []core.KeyValue {
|
||||||
attributes := make(map[string]interface{})
|
attributes := make([]core.KeyValue, 0, s.lruAttributes.simpleLruMap.Len())
|
||||||
for _, key := range s.lruAttributes.simpleLruMap.Keys() {
|
for _, key := range s.lruAttributes.simpleLruMap.Keys() {
|
||||||
value, ok := s.lruAttributes.simpleLruMap.Get(key)
|
value, ok := s.lruAttributes.simpleLruMap.Get(key)
|
||||||
if ok {
|
if ok {
|
||||||
key := key.(core.Key)
|
key := key.(core.Key)
|
||||||
attributes[key.Name] = value
|
value := value.(core.Value)
|
||||||
|
attributes = append(attributes, core.KeyValue{Key: key, Value: value})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return attributes
|
return attributes
|
||||||
|
|||||||
@@ -186,9 +186,12 @@ func TestSetSpanAttributes(t *testing.T) {
|
|||||||
TraceID: tid,
|
TraceID: tid,
|
||||||
TraceOptions: 0x1,
|
TraceOptions: 0x1,
|
||||||
},
|
},
|
||||||
ParentSpanID: sid,
|
ParentSpanID: sid,
|
||||||
Name: "span0",
|
Name: "span0",
|
||||||
Attributes: map[string]interface{}{"key1": core.Value{Type: core.STRING, String: "value1"}},
|
Attributes: []core.KeyValue{{
|
||||||
|
Key: core.Key{Name: "key1"},
|
||||||
|
Value: core.Value{Type: core.STRING, String: "value1"},
|
||||||
|
}},
|
||||||
HasRemoteParent: true,
|
HasRemoteParent: true,
|
||||||
}
|
}
|
||||||
if diff := cmp.Diff(got, want); diff != "" {
|
if diff := cmp.Diff(got, want); diff != "" {
|
||||||
@@ -217,9 +220,16 @@ func TestSetSpanAttributesOverLimit(t *testing.T) {
|
|||||||
},
|
},
|
||||||
ParentSpanID: sid,
|
ParentSpanID: sid,
|
||||||
Name: "span0",
|
Name: "span0",
|
||||||
Attributes: map[string]interface{}{
|
Attributes: []core.KeyValue{
|
||||||
"key1": core.Value{Type: core.STRING, String: "value3"},
|
{
|
||||||
"key4": core.Value{Type: core.STRING, String: "value4"}},
|
Key: core.Key{Name: "key1"},
|
||||||
|
Value: core.Value{Type: core.STRING, String: "value3"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Key: core.Key{Name: "key4"},
|
||||||
|
Value: core.Value{Type: core.STRING, String: "value4"},
|
||||||
|
},
|
||||||
|
},
|
||||||
HasRemoteParent: true,
|
HasRemoteParent: true,
|
||||||
DroppedAttributeCount: 1,
|
DroppedAttributeCount: 1,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user