diff --git a/examples/hotrod/cmd/frontend.go b/examples/hotrod/cmd/frontend.go index e1eedc65c14..39a2b9f69c0 100644 --- a/examples/hotrod/cmd/frontend.go +++ b/examples/hotrod/cmd/frontend.go @@ -45,7 +45,7 @@ var frontendCmd = &cobra.Command{ logger := log.NewFactory(zapLogger) server := frontend.NewServer( options, - tracing.Init("frontend", otelExporter, metricsFactory, logger), + tracing.InitOTEL("frontend", otelExporter, metricsFactory, logger), logger, ) return logError(zapLogger, server.Run()) diff --git a/examples/hotrod/cmd/route.go b/examples/hotrod/cmd/route.go index 191bd96c556..04cf3687076 100644 --- a/examples/hotrod/cmd/route.go +++ b/examples/hotrod/cmd/route.go @@ -37,7 +37,7 @@ var routeCmd = &cobra.Command{ logger := log.NewFactory(zapLogger) server := route.NewServer( net.JoinHostPort("0.0.0.0", strconv.Itoa(routePort)), - tracing.Init("route", otelExporter, metricsFactory, logger), + tracing.InitOTEL("route", otelExporter, metricsFactory, logger), logger, ) return logError(zapLogger, server.Run()) diff --git a/examples/hotrod/pkg/tracing/http.go b/examples/hotrod/pkg/tracing/http.go index 96794abb6f1..dbea5c95ec8 100644 --- a/examples/hotrod/pkg/tracing/http.go +++ b/examples/hotrod/pkg/tracing/http.go @@ -22,26 +22,35 @@ import ( "io" "net/http" - "github.com/opentracing-contrib/go-stdlib/nethttp" - "github.com/opentracing/opentracing-go" + "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" + "go.opentelemetry.io/otel/trace" ) // HTTPClient wraps an http.Client with tracing instrumentation. type HTTPClient struct { - Tracer opentracing.Tracer - Client *http.Client + TracerProvider trace.TracerProvider + Client *http.Client +} + +func NewHTTPClient(tp trace.TracerProvider) *HTTPClient { + return &HTTPClient{ + TracerProvider: tp, + Client: &http.Client{ + Transport: otelhttp.NewTransport( + http.DefaultTransport, + otelhttp.WithTracerProvider(tp), + ), + }, + } } // GetJSON executes HTTP GET against specified url and tried to parse // the response into out object. func (c *HTTPClient) GetJSON(ctx context.Context, endpoint string, url string, out interface{}) error { - req, err := http.NewRequest(http.MethodGet, url, nil) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) if err != nil { return err } - req = req.WithContext(ctx) - req, ht := nethttp.TraceRequest(c.Tracer, req, nethttp.OperationName("HTTP GET: "+endpoint)) - defer ht.Finish() res, err := c.Client.Do(req) if err != nil { @@ -57,6 +66,7 @@ func (c *HTTPClient) GetJSON(ctx context.Context, endpoint string, url string, o } return errors.New(string(body)) } + decoder := json.NewDecoder(res.Body) return decoder.Decode(out) } diff --git a/examples/hotrod/pkg/tracing/mux.go b/examples/hotrod/pkg/tracing/mux.go index a9102f2ccb4..fe8d197a8d9 100644 --- a/examples/hotrod/pkg/tracing/mux.go +++ b/examples/hotrod/pkg/tracing/mux.go @@ -18,17 +18,15 @@ package tracing import ( "net/http" - "github.com/opentracing-contrib/go-stdlib/nethttp" - "github.com/opentracing/opentracing-go" - "go.opentelemetry.io/otel/baggage" - "go.opentelemetry.io/otel/propagation" + "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" + "go.opentelemetry.io/otel/trace" "go.uber.org/zap" "github.com/jaegertracing/jaeger/examples/hotrod/pkg/log" ) // NewServeMux creates a new TracedServeMux. -func NewServeMux(copyBaggage bool, tracer opentracing.Tracer, logger log.Factory) *TracedServeMux { +func NewServeMux(copyBaggage bool, tracer trace.TracerProvider, logger log.Factory) *TracedServeMux { return &TracedServeMux{ mux: http.NewServeMux(), copyBaggage: copyBaggage, @@ -41,7 +39,7 @@ func NewServeMux(copyBaggage bool, tracer opentracing.Tracer, logger log.Factory type TracedServeMux struct { mux *http.ServeMux copyBaggage bool - tracer opentracing.Tracer + tracer trace.TracerProvider logger log.Factory } @@ -49,43 +47,15 @@ type TracedServeMux struct { func (tm *TracedServeMux) Handle(pattern string, handler http.Handler) { tm.logger.Bg().Debug("registering traced handler", zap.String("endpoint", pattern)) - middleware := nethttp.Middleware( - tm.tracer, - handler, - nethttp.OperationNameFunc(func(r *http.Request) string { - return "HTTP " + r.Method + " " + pattern - }), - // Jaeger SDK was able to accept `jaeger-baggage` header even for requests without am active trace. - // OTEL Bridge does not support that, so we use Baggage propagator to manually extract the baggage - // into Context (in otelBaggageExtractor handler below), and once the Bridge creates a Span, - // we use this SpanObserver to copy OTEL baggage from Context into the Span. - nethttp.MWSpanObserver(func(span opentracing.Span, r *http.Request) { - if !tm.copyBaggage { - return - } - bag := baggage.FromContext(r.Context()) - for _, m := range bag.Members() { - if b := span.BaggageItem(m.Key()); b == "" { - span.SetBaggageItem(m.Key(), m.Value()) - } - } - }), - ) - tm.mux.Handle(pattern, otelBaggageExtractor(middleware)) + middleware := otelhttp.NewHandler( + otelhttp.WithRouteTag(pattern, handler), + pattern, + otelhttp.WithTracerProvider(tm.tracer)) + + tm.mux.Handle(pattern, middleware) } // ServeHTTP implements http.ServeMux#ServeHTTP. func (tm *TracedServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { tm.mux.ServeHTTP(w, r) } - -// Used with nethttp.MWSpanObserver above. -func otelBaggageExtractor(next http.Handler) http.Handler { - propagator := propagation.Baggage{} - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - carrier := propagation.HeaderCarrier(r.Header) - ctx := propagator.Extract(r.Context(), carrier) - r = r.WithContext(ctx) - next.ServeHTTP(w, r) - }) -} diff --git a/examples/hotrod/services/customer/client.go b/examples/hotrod/services/customer/client.go index f9595289c44..59787771519 100644 --- a/examples/hotrod/services/customer/client.go +++ b/examples/hotrod/services/customer/client.go @@ -18,10 +18,8 @@ package customer import ( "context" "fmt" - "net/http" - "github.com/opentracing-contrib/go-stdlib/nethttp" - "github.com/opentracing/opentracing-go" + "go.opentelemetry.io/otel/trace" "go.uber.org/zap" "github.com/jaegertracing/jaeger/examples/hotrod/pkg/log" @@ -30,21 +28,16 @@ import ( // Client is a remote client that implements customer.Interface type Client struct { - tracer opentracing.Tracer logger log.Factory client *tracing.HTTPClient hostPort string } // NewClient creates a new customer.Client -func NewClient(tracer opentracing.Tracer, logger log.Factory, hostPort string) *Client { +func NewClient(tracer trace.TracerProvider, logger log.Factory, hostPort string) *Client { return &Client{ - tracer: tracer, - logger: logger, - client: &tracing.HTTPClient{ - Client: &http.Client{Transport: &nethttp.Transport{}}, - Tracer: tracer, - }, + logger: logger, + client: tracing.NewHTTPClient(tracer), hostPort: hostPort, } } diff --git a/examples/hotrod/services/customer/database.go b/examples/hotrod/services/customer/database.go index 20512a20a59..57cc09f4c57 100644 --- a/examples/hotrod/services/customer/database.go +++ b/examples/hotrod/services/customer/database.go @@ -49,22 +49,22 @@ func newDatabase(tracer trace.Tracer, logger log.Factory) *database { customers: map[string]*Customer{ "123": { ID: "123", - Name: "Rachel's Floral Designs", + Name: "Rachel's_Floral_Designs", Location: "115,277", }, "567": { ID: "567", - Name: "Amazing Coffee Roasters", + Name: "Amazing_Coffee_Roasters", Location: "211,653", }, "392": { ID: "392", - Name: "Trom Chocolatier", + Name: "Trom_Chocolatier", Location: "577,322", }, "731": { ID: "731", - Name: "Japanese Desserts", + Name: "Japanese_Desserts", Location: "728,326", }, }, diff --git a/examples/hotrod/services/customer/server.go b/examples/hotrod/services/customer/server.go index 5a4336960e6..0b6acf2815a 100644 --- a/examples/hotrod/services/customer/server.go +++ b/examples/hotrod/services/customer/server.go @@ -19,7 +19,7 @@ import ( "encoding/json" "net/http" - "github.com/opentracing/opentracing-go" + "go.opentelemetry.io/otel/trace" "go.uber.org/zap" "github.com/jaegertracing/jaeger/examples/hotrod/pkg/httperr" @@ -31,7 +31,7 @@ import ( // Server implements Customer service type Server struct { hostPort string - tracer opentracing.Tracer + tracer trace.TracerProvider logger log.Factory database *database } @@ -40,7 +40,7 @@ type Server struct { func NewServer(hostPort string, otelExporter string, metricsFactory metrics.Factory, logger log.Factory) *Server { return &Server{ hostPort: hostPort, - tracer: tracing.Init("customer", otelExporter, metricsFactory, logger), + tracer: tracing.InitOTEL("customer", otelExporter, metricsFactory, logger), logger: logger, database: newDatabase( tracing.InitOTEL("mysql", otelExporter, metricsFactory, logger).Tracer("mysql"), diff --git a/examples/hotrod/services/driver/client.go b/examples/hotrod/services/driver/client.go index d25dfac4065..20b1e566e6c 100644 --- a/examples/hotrod/services/driver/client.go +++ b/examples/hotrod/services/driver/client.go @@ -19,8 +19,8 @@ import ( "context" "time" - otgrpc "github.com/opentracing-contrib/go-grpc" - "github.com/opentracing/opentracing-go" + "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" + "go.opentelemetry.io/otel/trace" "go.uber.org/zap" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" @@ -30,25 +30,23 @@ import ( // Client is a remote client that implements driver.Interface type Client struct { - tracer opentracing.Tracer logger log.Factory client DriverServiceClient } // NewClient creates a new driver.Client -func NewClient(tracer opentracing.Tracer, logger log.Factory, hostPort string) *Client { +func NewClient(tracerProvider trace.TracerProvider, logger log.Factory, hostPort string) *Client { conn, err := grpc.Dial(hostPort, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithUnaryInterceptor( - otgrpc.OpenTracingClientInterceptor(tracer)), + otelgrpc.UnaryClientInterceptor(otelgrpc.WithTracerProvider(tracerProvider))), grpc.WithStreamInterceptor( - otgrpc.OpenTracingStreamClientInterceptor(tracer))) + otelgrpc.StreamClientInterceptor(otelgrpc.WithTracerProvider(tracerProvider)))) if err != nil { logger.Bg().Fatal("Cannot create gRPC connection", zap.Error(err)) } client := NewDriverServiceClient(conn) return &Client{ - tracer: tracer, logger: logger, client: client, } diff --git a/examples/hotrod/services/frontend/best_eta.go b/examples/hotrod/services/frontend/best_eta.go index 5e33da7d571..3a1765a8e47 100644 --- a/examples/hotrod/services/frontend/best_eta.go +++ b/examples/hotrod/services/frontend/best_eta.go @@ -22,7 +22,8 @@ import ( "sync" "time" - "github.com/opentracing/opentracing-go" + "go.opentelemetry.io/otel/baggage" + "go.opentelemetry.io/otel/trace" "go.uber.org/zap" "github.com/jaegertracing/jaeger/examples/hotrod/pkg/log" @@ -47,7 +48,7 @@ type Response struct { ETA time.Duration } -func newBestETA(tracer opentracing.Tracer, logger log.Factory, options ConfigOptions) *bestETA { +func newBestETA(tracer trace.TracerProvider, logger log.Factory, options ConfigOptions) *bestETA { return &bestETA{ customer: customer.NewClient( tracer, @@ -76,9 +77,16 @@ func (eta *bestETA) Get(ctx context.Context, customerID string) (*Response, erro } eta.logger.For(ctx).Info("Found customer", zap.Any("customer", customer)) - if span := opentracing.SpanFromContext(ctx); span != nil { - span.SetBaggageItem("customer", customer.Name) + m, err := baggage.NewMember("customer", customer.Name) + if err != nil { + eta.logger.For(ctx).Error("cannot create baggage member", zap.Error(err)) + } + bag := baggage.FromContext(ctx) + bag, err = bag.SetMember(m) + if err != nil { + eta.logger.For(ctx).Error("cannot set baggage member", zap.Error(err)) } + ctx = baggage.ContextWithBaggage(ctx, bag) drivers, err := eta.driver.FindNearest(ctx, customer.Location) if err != nil { diff --git a/examples/hotrod/services/frontend/server.go b/examples/hotrod/services/frontend/server.go index d4d028f1fc4..45527569f85 100644 --- a/examples/hotrod/services/frontend/server.go +++ b/examples/hotrod/services/frontend/server.go @@ -21,7 +21,7 @@ import ( "net/http" "path" - "github.com/opentracing/opentracing-go" + "go.opentelemetry.io/otel/trace" "go.uber.org/zap" "github.com/jaegertracing/jaeger/examples/hotrod/pkg/httperr" @@ -36,7 +36,7 @@ var assetFS embed.FS // Server implements jaeger-demo-frontend service type Server struct { hostPort string - tracer opentracing.Tracer + tracer trace.TracerProvider logger log.Factory bestETA *bestETA assetFS http.FileSystem @@ -56,7 +56,7 @@ type ConfigOptions struct { } // NewServer creates a new frontend.Server -func NewServer(options ConfigOptions, tracer opentracing.Tracer, logger log.Factory) *Server { +func NewServer(options ConfigOptions, tracer trace.TracerProvider, logger log.Factory) *Server { return &Server{ hostPort: options.FrontendHostPort, tracer: tracer, diff --git a/examples/hotrod/services/route/client.go b/examples/hotrod/services/route/client.go index 2908956a3da..7c58f76e1dc 100644 --- a/examples/hotrod/services/route/client.go +++ b/examples/hotrod/services/route/client.go @@ -17,11 +17,9 @@ package route import ( "context" - "net/http" "net/url" - "github.com/opentracing-contrib/go-stdlib/nethttp" - "github.com/opentracing/opentracing-go" + "go.opentelemetry.io/otel/trace" "go.uber.org/zap" "github.com/jaegertracing/jaeger/examples/hotrod/pkg/log" @@ -30,21 +28,16 @@ import ( // Client is a remote client that implements route.Interface type Client struct { - tracer opentracing.Tracer logger log.Factory client *tracing.HTTPClient hostPort string } // NewClient creates a new route.Client -func NewClient(tracer opentracing.Tracer, logger log.Factory, hostPort string) *Client { +func NewClient(tracer trace.TracerProvider, logger log.Factory, hostPort string) *Client { return &Client{ - tracer: tracer, - logger: logger, - client: &tracing.HTTPClient{ - Client: &http.Client{Transport: &nethttp.Transport{}}, - Tracer: tracer, - }, + logger: logger, + client: tracing.NewHTTPClient(tracer), hostPort: hostPort, } } diff --git a/examples/hotrod/services/route/server.go b/examples/hotrod/services/route/server.go index b93662b84f0..9d2643f9301 100644 --- a/examples/hotrod/services/route/server.go +++ b/examples/hotrod/services/route/server.go @@ -24,8 +24,8 @@ import ( "net/http" "time" - "github.com/opentracing/opentracing-go" "github.com/prometheus/client_golang/prometheus/promhttp" + "go.opentelemetry.io/otel/trace" "go.uber.org/zap" "github.com/jaegertracing/jaeger/examples/hotrod/pkg/delay" @@ -38,12 +38,12 @@ import ( // Server implements Route service type Server struct { hostPort string - tracer opentracing.Tracer + tracer trace.TracerProvider logger log.Factory } // NewServer creates a new route.Server -func NewServer(hostPort string, tracer opentracing.Tracer, logger log.Factory) *Server { +func NewServer(hostPort string, tracer trace.TracerProvider, logger log.Factory) *Server { return &Server{ hostPort: hostPort, tracer: tracer,