Skip to content

Commit 776d8fc

Browse files
committed
rename to tracing for real
1 parent 1974a1e commit 776d8fc

File tree

2 files changed

+110
-0
lines changed

2 files changed

+110
-0
lines changed

tracing/exporter.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package tracing
2+
3+
import (
4+
"context"
5+
6+
"go.opentelemetry.io/otel/exporters/otlp/otlptrace"
7+
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
8+
"go.opentelemetry.io/otel/sdk/resource"
9+
sdktrace "go.opentelemetry.io/otel/sdk/trace"
10+
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
11+
"golang.org/x/xerrors"
12+
)
13+
14+
// TracerProvider creates a grpc otlp exporter and configures a trace provider.
15+
// Caller is responsible for calling TracerProvider.Shutdown to ensure all data is flushed.
16+
func TracerProvider(ctx context.Context, service string) (*sdktrace.TracerProvider, error) {
17+
res, err := resource.New(ctx,
18+
resource.WithAttributes(
19+
// the service name used to display traces in backends
20+
semconv.ServiceNameKey.String(service),
21+
),
22+
)
23+
if err != nil {
24+
return nil, xerrors.Errorf("creating otlp resource: %w", err)
25+
}
26+
27+
// By default we send span data to a local otel collector.
28+
// The endpoint we push to can be configured with env vars.
29+
// See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md
30+
exporter, err := otlptrace.New(ctx, otlptracegrpc.NewClient(otlptracegrpc.WithInsecure()))
31+
if err != nil {
32+
return nil, xerrors.Errorf("creating otlp exporter: %w", err)
33+
}
34+
35+
tracerProvider := sdktrace.NewTracerProvider(
36+
sdktrace.WithBatcher(exporter),
37+
sdktrace.WithResource(res),
38+
)
39+
40+
return tracerProvider, nil
41+
}

tracing/httpmw.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package tracing
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
7+
"github.com/go-chi/chi/middleware"
8+
"github.com/go-chi/chi/v5"
9+
"go.opentelemetry.io/otel/attribute"
10+
"go.opentelemetry.io/otel/codes"
11+
sdktrace "go.opentelemetry.io/otel/sdk/trace"
12+
)
13+
14+
// HTTPMW adds tracing to http routes.
15+
func HTTPMW(tracerProvider *sdktrace.TracerProvider, name string) func(http.Handler) http.Handler {
16+
return func(next http.Handler) http.Handler {
17+
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
18+
// // do not trace if exporter has not be initialized
19+
if tracerProvider == nil {
20+
next.ServeHTTP(rw, r)
21+
return
22+
}
23+
24+
// start span with default span name. Span name will be updated once request finishes
25+
_, span := tracerProvider.Tracer(name).Start(r.Context(), "http.request")
26+
defer span.End()
27+
28+
wrw := middleware.NewWrapResponseWriter(rw, r.ProtoMajor)
29+
30+
// pass the span through the request context and serve the request to the next middleware
31+
next.ServeHTTP(rw, r)
32+
33+
// set the resource name as we get it only once the handler is executed
34+
route := chi.RouteContext(r.Context()).RoutePattern()
35+
if route == "" {
36+
route = "unknown"
37+
}
38+
span.SetName(fmt.Sprintf("%s %s", r.Method, route))
39+
span.SetAttributes(attribute.KeyValue{
40+
Key: "http.method",
41+
Value: attribute.StringValue(r.Method),
42+
})
43+
span.SetAttributes(attribute.KeyValue{
44+
Key: "http.route",
45+
Value: attribute.StringValue(route),
46+
})
47+
span.SetAttributes(attribute.KeyValue{
48+
Key: "http.path",
49+
Value: attribute.StringValue(r.URL.EscapedPath()),
50+
})
51+
52+
// set the status code
53+
status := wrw.Status()
54+
// 0 status means one has not yet been sent in which case net/http library will write StatusOK
55+
if status == 0 {
56+
status = http.StatusOK
57+
}
58+
span.SetAttributes(attribute.KeyValue{
59+
Key: "http.status_code",
60+
Value: attribute.IntValue(status),
61+
})
62+
63+
// if 5XX we set the span to "error" status
64+
if status >= 500 {
65+
span.SetStatus(codes.Error, fmt.Sprintf("%d: %s", status, http.StatusText(status)))
66+
}
67+
})
68+
}
69+
}

0 commit comments

Comments
 (0)