-
Notifications
You must be signed in to change notification settings - Fork 0
/
5.4_propagation-solution.go
154 lines (128 loc) · 4.19 KB
/
5.4_propagation-solution.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package main
import (
"context"
"fmt"
"go.opentelemetry.io/otel/propagation"
"log"
"math/rand"
"net/http"
"os"
"time"
"github.com/gorilla/mux"
"go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
"go.opentelemetry.io/otel/sdk/resource"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.7.0"
"go.opentelemetry.io/otel/trace"
"google.golang.org/grpc/credentials"
)
var years = []int{2015, 2016, 2017, 2018, 2019, 2020}
func main() {
cleanup := initTracer()
defer cleanup()
r := mux.NewRouter()
r.Use(otelmux.Middleware("go-year"))
r.HandleFunc("/year", func(w http.ResponseWriter, r *http.Request) {
rand.Seed(time.Now().UnixNano())
time.Sleep(time.Duration(rand.Intn(250)) * time.Millisecond)
go doSomeWork(r.Context())
year := getYear(r.Context())
span := trace.SpanFromContext(r.Context())
span.SetAttributes(
attribute.String("foo", "bar"),
attribute.Int("year", year),
)
fmt.Fprintf(w, "%d", year)
})
http.Handle("/", r)
log.Println("Listening on ", ":6001")
log.Fatal(http.ListenAndServe(":6001", nil))
}
func doSomeWork(ctx context.Context) {
tracer := otel.Tracer("")
_, span := tracer.Start(ctx, "some-work")
span.SetAttributes(attribute.String("otel", "rocks"))
time.Sleep(time.Duration(rand.Intn(250)) * time.Millisecond)
span.AddEvent("my event", trace.WithAttributes(attribute.String("more", "details")))
time.Sleep(time.Duration(rand.Intn(150)+100) * time.Millisecond)
span.AddEvent("another event")
go generateLinkedTrace(ctx)
defer span.End()
}
func getYear(ctx context.Context) int {
rnd := rand.Intn(len(years))
year := years[rnd]
tracer := otel.Tracer("")
_, span := tracer.Start(ctx, "getYear")
span.SetAttributes(
attribute.Int("random-index", rnd),
attribute.Int("year", year),
)
defer span.End()
time.Sleep(time.Duration(rand.Intn(250)) * time.Millisecond)
return year
}
func generateLinkedTrace(ctx context.Context) {
tracer := otel.Tracer("")
srcSpanCtx := trace.SpanContextFromContext(ctx)
ctx, span := tracer.Start(context.Background(), "go-generated-span",
trace.WithLinks(trace.Link{SpanContext: srcSpanCtx}),
trace.WithAttributes(attribute.Int("depth", 1)),
)
defer span.End()
time.Sleep(time.Duration(rand.Intn(250)) * time.Millisecond)
addRecursiveSpan(ctx, 2, 5)
}
func addRecursiveSpan(ctx context.Context, depth int, maxDepth int) {
tracer := otel.Tracer("")
ctx, span := tracer.Start(ctx, "generated-span",
trace.WithAttributes(attribute.Int("depth", depth)),
)
defer span.End()
time.Sleep(time.Duration(rand.Intn(250)) * time.Millisecond)
if depth < maxDepth {
addRecursiveSpan(ctx, depth+1, maxDepth)
}
}
func initTracer() func() {
apikey, _ := os.LookupEnv("HONEYCOMB_API_KEY")
dataset, _ := os.LookupEnv("HONEYCOMB_DATASET")
// Initialize an OTLP exporter over gRPC and point it to Honeycomb.
ctx := context.Background()
// Set GRPC options to establish an insecure connection to an OpenTelemetry Collector
opts := []otlptracegrpc.Option{
otlptracegrpc.WithTLSCredentials(credentials.NewClientTLSFromCert(nil, "")),
otlptracegrpc.WithEndpoint("api.honeycomb.io:443"),
otlptracegrpc.WithHeaders(map[string]string{
"x-honeycomb-team": apikey,
"x-honeycomb-dataset": dataset,
}),
}
// Create the exporter
exporter, err := otlptrace.New(ctx, otlptracegrpc.NewClient(opts...))
if err != nil {
log.Fatalf("failed to create Otel exporter: %v", err)
}
provider := sdktrace.NewTracerProvider(
sdktrace.WithSampler(sdktrace.AlwaysSample()),
sdktrace.WithBatcher(exporter),
sdktrace.WithResource(resource.NewWithAttributes(
semconv.SchemaURL,
semconv.ServiceNameKey.String("go-year"),
)),
)
otel.SetTracerProvider(provider)
otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))
// This callback will ensure all spans get flushed before the program exits.
return func() {
ctx := context.Background()
err := provider.Shutdown(ctx)
if err != nil {
log.Fatal(err)
}
}
}