diff --git a/pkg/services/authn/grpcutils/grpc_authenticator.go b/pkg/services/authn/grpcutils/grpc_authenticator.go index ff3451cdf11..dc9f3701eed 100644 --- a/pkg/services/authn/grpcutils/grpc_authenticator.go +++ b/pkg/services/authn/grpcutils/grpc_authenticator.go @@ -9,7 +9,9 @@ import ( authnlib "github.com/grafana/authlib/authn" "github.com/prometheus/client_golang/prometheus" + "go.opentelemetry.io/otel/attribute" + "github.com/grafana/grafana/pkg/infra/tracing" "github.com/grafana/grafana/pkg/services/grpcserver/interceptors" "github.com/grafana/grafana/pkg/setting" ) @@ -25,7 +27,7 @@ func NewInProcGrpcAuthenticator() *authnlib.GrpcAuthenticator { ) } -func NewGrpcAuthenticator(cfg *setting.Cfg) (*authnlib.GrpcAuthenticator, error) { +func NewGrpcAuthenticator(cfg *setting.Cfg, tracer tracing.Tracer) (*authnlib.GrpcAuthenticator, error) { authCfg, err := ReadGrpcServerConfig(cfg) if err != nil { return nil, err @@ -49,6 +51,7 @@ func NewGrpcAuthenticator(cfg *setting.Cfg) (*authnlib.GrpcAuthenticator, error) grpcOpts := []authnlib.GrpcAuthenticatorOption{ authnlib.WithIDTokenAuthOption(true), authnlib.WithKeyRetrieverOption(keyRetriever), + authnlib.WithTracerAuthOption(tracer), } if authCfg.Mode == ModeOnPrem { grpcOpts = append(grpcOpts, @@ -67,15 +70,16 @@ type AuthenticatorWithFallback struct { authenticator *authnlib.GrpcAuthenticator fallback interceptors.Authenticator metrics *metrics + tracer tracing.Tracer } -func NewGrpcAuthenticatorWithFallback(cfg *setting.Cfg, reg prometheus.Registerer, fallback interceptors.Authenticator) (interceptors.Authenticator, error) { +func NewGrpcAuthenticatorWithFallback(cfg *setting.Cfg, reg prometheus.Registerer, tracer tracing.Tracer, fallback interceptors.Authenticator) (interceptors.Authenticator, error) { authCfg, err := ReadGrpcServerConfig(cfg) if err != nil { return nil, err } - authenticator, err := NewGrpcAuthenticator(cfg) + authenticator, err := NewGrpcAuthenticator(cfg, tracer) if err != nil { return nil, err } @@ -88,16 +92,20 @@ func NewGrpcAuthenticatorWithFallback(cfg *setting.Cfg, reg prometheus.Registere authenticator: authenticator, fallback: fallback, metrics: newMetrics(reg), + tracer: tracer, }, nil } func (f *AuthenticatorWithFallback) Authenticate(ctx context.Context) (context.Context, error) { + ctx, span := f.tracer.Start(ctx, "grpcutils.AuthenticatorWithFallback.Authenticate") + span.SetAttributes(attribute.Bool("fallback_used", false)) // Try to authenticate with the new authenticator first newCtx, err := f.authenticator.Authenticate(ctx) if err != nil { // In case of error, fallback to the legacy authenticator newCtx, err = f.fallback.Authenticate(ctx) f.metrics.fallbackCounter.WithLabelValues(fmt.Sprintf("%t", err == nil)).Inc() + span.SetAttributes(attribute.Bool("fallback_used", true)) } return newCtx, err } diff --git a/pkg/storage/unified/client.go b/pkg/storage/unified/client.go index 4d1b225c038..c1cf0a2513b 100644 --- a/pkg/storage/unified/client.go +++ b/pkg/storage/unified/client.go @@ -87,7 +87,7 @@ func ProvideUnifiedStorageClient( } // Create a client instance - client, err := newResourceClient(conn, cfg, features) + client, err := newResourceClient(conn, cfg, features, tracer) if err != nil { return nil, err } @@ -116,15 +116,15 @@ func clientCfgMapping(clientCfg *grpcutils.GrpcClientConfig) authnlib.GrpcClient } } -func newResourceClient(conn *grpc.ClientConn, cfg *setting.Cfg, features featuremgmt.FeatureToggles) (resource.ResourceClient, error) { +func newResourceClient(conn *grpc.ClientConn, cfg *setting.Cfg, features featuremgmt.FeatureToggles, tracer tracing.Tracer) (resource.ResourceClient, error) { if !features.IsEnabledGlobally(featuremgmt.FlagAppPlatformGrpcClientAuth) { return resource.NewLegacyResourceClient(conn), nil } if cfg.StackID == "" { - return resource.NewGRPCResourceClient(conn) + return resource.NewGRPCResourceClient(tracer, conn) } grpcClientCfg := grpcutils.ReadGrpcClientConfig(cfg) - return resource.NewCloudResourceClient(conn, clientCfgMapping(grpcClientCfg), cfg.Env == setting.Dev) + return resource.NewCloudResourceClient(tracer, conn, clientCfgMapping(grpcClientCfg), cfg.Env == setting.Dev) } diff --git a/pkg/storage/unified/resource/client.go b/pkg/storage/unified/resource/client.go index 46c3c5c3605..c06cd065463 100644 --- a/pkg/storage/unified/resource/client.go +++ b/pkg/storage/unified/resource/client.go @@ -17,6 +17,7 @@ import ( "google.golang.org/grpc" "github.com/grafana/grafana/pkg/apimachinery/identity" + "github.com/grafana/grafana/pkg/infra/tracing" "github.com/grafana/grafana/pkg/services/auth" "github.com/grafana/grafana/pkg/services/authn/grpcutils" grpcUtils "github.com/grafana/grafana/pkg/storage/unified/resource/grpc" @@ -83,12 +84,13 @@ func NewLocalResourceClient(server ResourceServer) ResourceClient { } } -func NewGRPCResourceClient(conn *grpc.ClientConn) (ResourceClient, error) { +func NewGRPCResourceClient(tracer tracing.Tracer, conn *grpc.ClientConn) (ResourceClient, error) { // scenario: remote on-prem clientInt, err := authnlib.NewGrpcClientInterceptor( &authnlib.GrpcClientConfig{}, authnlib.WithDisableAccessTokenOption(), authnlib.WithIDTokenExtractorOption(idTokenExtractor), + authnlib.WithTracerOption(tracer), ) if err != nil { return nil, err @@ -102,10 +104,11 @@ func NewGRPCResourceClient(conn *grpc.ClientConn) (ResourceClient, error) { }, nil } -func NewCloudResourceClient(conn *grpc.ClientConn, cfg authnlib.GrpcClientConfig, allowInsecure bool) (ResourceClient, error) { +func NewCloudResourceClient(tracer tracing.Tracer, conn *grpc.ClientConn, cfg authnlib.GrpcClientConfig, allowInsecure bool) (ResourceClient, error) { // scenario: remote cloud opts := []authnlib.GrpcClientInterceptorOption{ authnlib.WithIDTokenExtractorOption(idTokenExtractor), + authnlib.WithTracerOption(tracer), } if allowInsecure { diff --git a/pkg/storage/unified/sql/service.go b/pkg/storage/unified/sql/service.go index d531a56a15a..83105efb371 100644 --- a/pkg/storage/unified/sql/service.go +++ b/pkg/storage/unified/sql/service.go @@ -70,7 +70,7 @@ func ProvideUnifiedStorageGrpcService( // FIXME: This is a temporary solution while we are migrating to the new authn interceptor // grpcutils.NewGrpcAuthenticator should be used instead. - authn, err := grpcutils.NewGrpcAuthenticatorWithFallback(cfg, prometheus.DefaultRegisterer, &grpc.Authenticator{}) + authn, err := grpcutils.NewGrpcAuthenticatorWithFallback(cfg, prometheus.DefaultRegisterer, tracing, &grpc.Authenticator{}) if err != nil { return nil, err } diff --git a/pkg/storage/unified/sql/test/integration_test.go b/pkg/storage/unified/sql/test/integration_test.go index 30414aed449..d3e10b6cb75 100644 --- a/pkg/storage/unified/sql/test/integration_test.go +++ b/pkg/storage/unified/sql/test/integration_test.go @@ -15,6 +15,7 @@ import ( "github.com/grafana/grafana/pkg/apimachinery/identity" infraDB "github.com/grafana/grafana/pkg/infra/db" + "github.com/grafana/grafana/pkg/infra/tracing" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/storage/unified/resource" @@ -375,7 +376,7 @@ func TestClientServer(t *testing.T) { t.Run("Create a client", func(t *testing.T) { conn, err := grpc.NewClient(svc.GetAddress(), grpc.WithTransportCredentials(insecure.NewCredentials())) require.NoError(t, err) - client, err = resource.NewGRPCResourceClient(conn) + client, err = resource.NewGRPCResourceClient(tracing.NewNoopTracerService(), conn) require.NoError(t, err) })