From b2f214b1f2c191135cb755f8f16a105a43b53d74 Mon Sep 17 00:00:00 2001 From: kenriortega Date: Sun, 14 Nov 2021 14:36:51 -0500 Subject: [PATCH] ref: instrumented grpc proxy with otel --- cmd/cli/grpcxy.go | 58 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/cmd/cli/grpcxy.go b/cmd/cli/grpcxy.go index 0653af6..d533745 100644 --- a/cmd/cli/grpcxy.go +++ b/cmd/cli/grpcxy.go @@ -11,8 +11,11 @@ import ( "github.com/kenriortega/ngonx/pkg/errors" "github.com/kenriortega/ngonx/pkg/logger" + "github.com/kenriortega/ngonx/pkg/otelify" "github.com/spf13/cobra" "github.com/talos-systems/grpc-proxy/proxy" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/trace" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" @@ -25,6 +28,25 @@ var grpcCmd = &cobra.Command{ Use: "grpc", Short: "Run ngonx as a grpc proxy", Run: func(cmd *cobra.Command, args []string) { + + enableMetric, err := cmd.Flags().GetBool(flagMetric) + if err != nil { + logger.LogError(errors.Errorf("proxy: %v", err).Error()) + } + if enableMetric { + // TODO: pass from compile vars + flush := otelify.InitProvider( + "ngonx", + "v0.4.5", + "dev", + // TODO: pass from yml file object + "0.0.0.0:55680", + ) + defer flush() + // Exporter Metrics + go otelify.ExposeMetricServer(configFromYaml.ProxyGateway.PortExporterProxy) + } + var opts []grpc.ServerOption lis, err := net.Listen("tcp", configFromYaml.GrpcProxy.Listener) @@ -34,6 +56,9 @@ var grpcCmd = &cobra.Command{ logger.LogInfo(fmt.Sprintf("Proxy running at %q\n", configFromYaml.GrpcProxy.Listener)) simpleBackendGen := func(hostname string) proxy.Backend { + ctx, span := otel.Tracer("grpcxy.simpleBackendGen").Start(context.Background(), "simpleBackendGen") + defer span.End() + traceID := trace.SpanContextFromContext(ctx).TraceID().String() return &proxy.SingleBackend{ GetConn: func(ctx context.Context) (context.Context, *grpc.ClientConn, error) { md, _ := metadata.FromIncomingContext(ctx) @@ -41,7 +66,9 @@ var grpcCmd = &cobra.Command{ outCtx := metadata.NewOutgoingContext(ctx, md.Copy()) if configFromYaml.GrpcSSL.Enable { creds, sslErr := credentials.NewClientTLSFromFile( - configFromYaml.GrpcClientCert, "") + configFromYaml.GrpcClientCert, + "", + ) if sslErr != nil { logger.LogError(errors.Errorf("grpc: failed to parse credentials: %v", sslErr).Error()) } @@ -51,6 +78,10 @@ var grpcCmd = &cobra.Command{ grpc.WithTransportCredentials(creds), grpc.WithCodec(proxy.Codec()), ) //nolint: staticcheck + if err != nil { + otelify.InstrumentedError(span, "grpcxy.grpc.DialContext", traceID, err) + } + otelify.InstrumentedInfo(span, "grpcxy.grpc.DialContext", traceID) return outCtx, conn, err } conn, err := grpc.DialContext( @@ -59,27 +90,48 @@ var grpcCmd = &cobra.Command{ grpc.WithInsecure(), grpc.WithCodec(proxy.Codec()), ) //nolint: staticcheck - + if err != nil { + otelify.InstrumentedError(span, "grpcxy.grpc.DialContext", traceID, err) + } + otelify.InstrumentedInfo(span, "grpcxy.grpc.DialContext", traceID) return outCtx, conn, err }, } } director = func(ctx context.Context, fullMethodName string) (proxy.Mode, []proxy.Backend, error) { + ctx, span := otel.Tracer("grpcxy.director").Start(context.Background(), "director") + defer span.End() + traceID := trace.SpanContextFromContext(ctx).TraceID().String() for _, bkd := range configFromYaml.GrpcEndpoints { // Make sure we never forward internal services. if !strings.HasPrefix(fullMethodName, bkd.Name) { + otelify.InstrumentedError( + span, + "grpcxy.not.strings.HasPrefix", + traceID, + errors.NewError("Unknown method"), + ) + return proxy.One2One, nil, status.Errorf(codes.Unimplemented, "Unknown method") } md, ok := metadata.FromIncomingContext(ctx) if ok { if _, exists := md[":authority"]; exists { + otelify.InstrumentedInfo(span, "director.proxy.One2One", traceID) + return proxy.One2One, []proxy.Backend{ simpleBackendGen(bkd.HostURI), }, nil } } } + otelify.InstrumentedError( + span, + "grpcxy.One2One", + traceID, + errors.NewError("Unknown method"), + ) return proxy.One2One, nil, status.Errorf(codes.Unimplemented, "Unknown method") } opts = append(opts, @@ -110,7 +162,7 @@ var grpcCmd = &cobra.Command{ } func init() { - + grpcCmd.Flags().Bool(flagMetric, false, "Action for enable metrics OTEL") rootCmd.AddCommand(grpcCmd) }