in xray/grpc.go [68:133]
func UnaryServerInterceptor(serverInterceptorOptions ...GrpcOption) grpc.UnaryServerInterceptor {
var option grpcOption
for _, options := range serverInterceptorOptions {
options.apply(&option)
}
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
md, ok := metadata.FromIncomingContext(ctx)
var traceID string
if ok && len(md.Get(TraceIDHeaderKey)) == 1 {
traceID = md.Get(TraceIDHeaderKey)[0]
}
traceHeader := header.FromString(traceID)
var host string
if len(md.Get(":authority")) == 1 {
host = md.Get(":authority")[0]
}
requestURL := url.URL{
Scheme: "grpc",
Host: host,
Path: info.FullMethod,
}
var name string
if option.segmentNamer == nil {
name = inferServiceName(info.FullMethod)
} else {
name = option.segmentNamer.Name(host)
}
if option.config != nil {
ctx = context.WithValue(ctx, RecorderContextKey{}, option.config)
}
var seg *Segment
ctx, seg = NewSegmentFromHeader(ctx, name, &http.Request{
Host: host,
URL: &requestURL,
Method: http.MethodPost,
}, traceHeader)
defer seg.Close(nil)
seg.Lock()
seg.GetHTTP().GetRequest().ClientIP, seg.GetHTTP().GetRequest().XForwardedFor = clientIPFromGrpcMetadata(md)
seg.GetHTTP().GetRequest().URL = requestURL.String()
seg.GetHTTP().GetRequest().Method = http.MethodPost
if len(md.Get("user-agent")) == 1 {
seg.GetHTTP().GetRequest().UserAgent = md.Get("user-agent")[0]
}
seg.Unlock()
resp, err = handler(ctx, req)
if err != nil {
classifyErrorStatus(seg, err)
}
recordContentLength(seg, resp)
if headerErr := addResponseTraceHeader(ctx, seg, traceHeader); headerErr != nil {
logger.Debug("fail to set the grpc trace header")
}
return resp, err
}
}