package service import ( "context" "fmt" "git.hlsq.asia/mmorpg/service-common/log" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" otelcodes "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/trace" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" "time" ) func (s *Base) RecoveryInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) { defer func() { if r := recover(); r != nil { log.Errorf("service Panic: %v", r) err = status.Error(codes.Internal, fmt.Sprintf("Internal server error: %v", r)) } }() return handler(ctx, req) } func (s *Base) LoggingInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) { usn := "" if md, ok := metadata.FromIncomingContext(ctx); ok { usnArr := md.Get("X-Usn") if len(usnArr) > 0 { usn = usnArr[0] } } tracer := otel.Tracer(s.ServiceName) _, span := tracer.Start(ctx, info.FullMethod) defer span.End() reqString := fmt.Sprintf("[usn:%v] method: %s, Request: %v", usn, info.FullMethod, req) span.SetAttributes(attribute.String("rpc.req", reqString)) log.Infof(reqString) start := time.Now() resp, err = handler(ctx, req) respString := fmt.Sprintf("[usn:%v] method: %s, Duration: %v, Response: %v, Error: %v", usn, info.FullMethod, time.Since(start), resp, err) span.SetAttributes(attribute.String("rpc.resp", respString)) log.Infof(respString) if err != nil { if stack, ok := err.(interface{ StackTrace() string }); ok { span.AddEvent("Stack Trace", trace.WithAttributes( attribute.String("stack.trace", fmt.Sprintf("%v", stack.StackTrace())), )) } span.SetStatus(otelcodes.Error, err.Error()) } return }