@@ -3,18 +3,78 @@ package middleware
33import (
44 "net/http"
55
6+ "github.com/owncloud/ocis/v2/ocis-pkg/tracing"
7+ "go-micro.dev/v4/metadata"
8+ "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
69 "go.opentelemetry.io/otel/propagation"
10+ "go.opentelemetry.io/otel/trace"
711)
812
9- var propagator = propagation .NewCompositeTextMapPropagator (
10- propagation.Baggage {},
11- propagation.TraceContext {},
12- )
13+ // GetOtelhttpMiddleware gets a new tracing middleware based on otelhttp
14+ // to trace the requests.
15+ // This middleware will use the otelhttp middleware and then store the
16+ // incoming data into the go-micro's metadata so it can be propagated through
17+ // go-micro.
18+ func GetOtelhttpMiddleware (service string , tp trace.TracerProvider ) func (http.Handler ) http.Handler {
19+ otelMid := otelhttp .NewMiddleware (
20+ service ,
21+ otelhttp .WithTracerProvider (tp ),
22+ otelhttp .WithPropagators (tracing .GetPropagator ()),
23+ otelhttp .WithSpanOptions (trace .WithSpanKind (trace .SpanKindServer )),
24+ otelhttp .WithSpanNameFormatter (func (name string , r * http.Request ) string {
25+ return r .Method + " " + r .URL .Path
26+ }),
27+ )
28+
29+ httpToMicroMid := otelhttpToGoMicroGrpc ()
30+
31+ return func (next http.Handler ) http.Handler {
32+ return otelMid (httpToMicroMid (next ))
33+ }
34+ }
35+
36+ func otelhttpToGoMicroGrpc () func (http.Handler ) http.Handler {
37+ return func (next http.Handler ) http.Handler {
38+ return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
39+ ctx := r .Context ()
40+ propagator := tracing .GetPropagator ()
41+
42+ // based on go-micro plugin for opentelemetry
43+ // inject telemetry data into go-micro's metadata
44+ // in order to propagate the info to go-micro's calls
45+ md := make (metadata.Metadata )
46+ carrier := make (propagation.MapCarrier )
47+ propagator .Inject (ctx , carrier )
48+ for k , v := range carrier {
49+ md .Set (k , v )
50+ }
51+ mdCtx := metadata .NewContext (ctx , md )
52+ r = r .WithContext (mdCtx )
53+
54+ next .ServeHTTP (w , r )
55+ })
56+ }
57+ }
58+
59+ // GetOtelhttpClient will get a new HTTP client that will use telemetry and
60+ // automatically set the telemetry headers. It will wrap the default transport
61+ // in order to use telemetry.
62+ func GetOtelhttpClient (tp trace.TracerProvider ) * http.Client {
63+ return & http.Client {
64+ Transport : GetOtelhttpClientTransport (http .DefaultTransport , tp ),
65+ }
66+ }
1367
14- // TraceContext unpacks the request context looking for an existing trace id.
15- func TraceContext (next http.Handler ) http.Handler {
16- return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
17- ctx := propagator .Extract (r .Context (), propagation .HeaderCarrier (r .Header ))
18- next .ServeHTTP (w , r .WithContext (ctx ))
19- })
68+ // GetOtelhttpClientTransport will get a new wrapped transport that will
69+ // include telemetry automatically. You can use the http.DefaultTransport
70+ // as base transport
71+ func GetOtelhttpClientTransport (baseTransport http.RoundTripper , tp trace.TracerProvider ) http.RoundTripper {
72+ return otelhttp .NewTransport (
73+ baseTransport ,
74+ otelhttp .WithTracerProvider (tp ),
75+ otelhttp .WithPropagators (tracing .GetPropagator ()),
76+ otelhttp .WithSpanNameFormatter (func (name string , r * http.Request ) string {
77+ return r .Method + " " + r .URL .Path
78+ }),
79+ )
2080}
0 commit comments