| 
									
										
										
										
											2022-10-04 18:27:14 +08:00
										 |  |  | package interceptors | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"context" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-10 01:25:19 +08:00
										 |  |  | 	"go.opentelemetry.io/otel" | 
					
						
							|  |  |  | 	"go.opentelemetry.io/otel/propagation" | 
					
						
							| 
									
										
										
										
											2022-10-04 18:27:14 +08:00
										 |  |  | 	"google.golang.org/grpc" | 
					
						
							| 
									
										
										
										
											2023-11-10 01:25:19 +08:00
										 |  |  | 	"google.golang.org/grpc/metadata" | 
					
						
							| 
									
										
										
										
											2023-01-30 16:21:27 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/infra/tracing" | 
					
						
							| 
									
										
										
										
											2022-10-04 18:27:14 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const tracingPrefix = "gRPC Server " | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TracingUnaryInterceptor(tracer tracing.Tracer) grpc.UnaryServerInterceptor { | 
					
						
							|  |  |  | 	return func( | 
					
						
							|  |  |  | 		ctx context.Context, | 
					
						
							| 
									
										
										
										
											2023-08-30 23:46:47 +08:00
										 |  |  | 		req any, | 
					
						
							| 
									
										
										
										
											2022-10-04 18:27:14 +08:00
										 |  |  | 		info *grpc.UnaryServerInfo, | 
					
						
							|  |  |  | 		handler grpc.UnaryHandler, | 
					
						
							| 
									
										
										
										
											2023-08-30 23:46:47 +08:00
										 |  |  | 	) (resp any, err error) { | 
					
						
							| 
									
										
										
										
											2023-11-10 01:25:19 +08:00
										 |  |  | 		if md, ok := metadata.FromIncomingContext(ctx); ok { | 
					
						
							|  |  |  | 			ctx = otel.GetTextMapPropagator().Extract(ctx, propagation.HeaderCarrier(md)) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-04 18:27:14 +08:00
										 |  |  | 		ctx, span := tracer.Start(ctx, tracingPrefix+info.FullMethod) | 
					
						
							|  |  |  | 		defer span.End() | 
					
						
							|  |  |  | 		resp, err = handler(ctx, req) | 
					
						
							|  |  |  | 		return resp, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TracingStreamInterceptor(tracer tracing.Tracer) grpc.StreamServerInterceptor { | 
					
						
							| 
									
										
										
										
											2023-08-30 23:46:47 +08:00
										 |  |  | 	return func(srv any, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { | 
					
						
							| 
									
										
										
										
											2023-11-10 01:25:19 +08:00
										 |  |  | 		ctx := stream.Context() | 
					
						
							|  |  |  | 		if md, ok := metadata.FromIncomingContext(ctx); ok { | 
					
						
							|  |  |  | 			ctx = otel.GetTextMapPropagator().Extract(ctx, propagation.HeaderCarrier(md)) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		ctx, span := tracer.Start(ctx, tracingPrefix+info.FullMethod) | 
					
						
							| 
									
										
										
										
											2022-10-04 18:27:14 +08:00
										 |  |  | 		defer span.End() | 
					
						
							|  |  |  | 		tracingStream := &tracingServerStream{ | 
					
						
							|  |  |  | 			ServerStream: stream, | 
					
						
							|  |  |  | 			ctx:          ctx, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return handler(srv, tracingStream) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type tracingServerStream struct { | 
					
						
							|  |  |  | 	grpc.ServerStream | 
					
						
							|  |  |  | 	ctx context.Context | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (s *tracingServerStream) Context() context.Context { | 
					
						
							|  |  |  | 	return s.ctx | 
					
						
							|  |  |  | } |