func UnaryClientInterceptor()

in xray/grpc.go [25:65]


func UnaryClientInterceptor(clientInterceptorOptions ...GrpcOption) grpc.UnaryClientInterceptor {
	var option grpcOption
	for _, interceptorOption := range clientInterceptorOptions {
		interceptorOption.apply(&option)
	}

	return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
		var segmentName string
		if option.segmentNamer == nil {
			segmentName = inferServiceName(method)
		} else {
			segmentName = option.segmentNamer.Name(cc.Target())
		}
		if option.config != nil {
			ctx = context.WithValue(ctx, RecorderContextKey{}, option.config)
		}
		return Capture(ctx, segmentName, func(ctx context.Context) error {
			seg := GetSegment(ctx)
			if seg == nil {
				return errors.New("failed to record gRPC transaction: segment cannot be found")
			}

			ctx = metadata.AppendToOutgoingContext(ctx, TraceIDHeaderKey, seg.DownstreamHeader().String())

			seg.Lock()
			seg.Namespace = "remote"
			seg.GetHTTP().GetRequest().URL = "grpc://" + cc.Target() + method
			seg.GetHTTP().GetRequest().Method = http.MethodPost
			seg.Unlock()

			err := invoker(ctx, method, req, reply, cc, opts...)

			recordContentLength(seg, reply)
			if err != nil {
				classifyErrorStatus(seg, err)
			}

			return err
		})
	}
}