github.com/cs3org/reva/v2@v2.27.7/internal/grpc/interceptors/appctx/appctx.go (about) 1 // Copyright 2018-2021 CERN 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // In applying this license, CERN does not waive the privileges and immunities 16 // granted to it by virtue of its status as an Intergovernmental Organization 17 // or submit itself to any jurisdiction. 18 19 package appctx 20 21 import ( 22 "context" 23 "runtime" 24 25 "github.com/cs3org/reva/v2/pkg/appctx" 26 "github.com/rs/zerolog" 27 semconv "go.opentelemetry.io/otel/semconv/v1.20.0" 28 "go.opentelemetry.io/otel/trace" 29 "google.golang.org/grpc" 30 ) 31 32 // name is the Tracer name used to identify this instrumentation library. 33 const tracerName = "appctx" 34 35 // NewUnary returns a new unary interceptor that creates the application context. 36 func NewUnary(log zerolog.Logger, tp trace.TracerProvider) grpc.UnaryServerInterceptor { 37 interceptor := func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { 38 span := trace.SpanFromContext(ctx) 39 defer span.End() 40 if !span.SpanContext().HasTraceID() { 41 ctx, span = tp.Tracer(tracerName).Start(ctx, "grpc unary") 42 } 43 _, file, _, ok := runtime.Caller(1) 44 if ok { 45 span.SetAttributes(semconv.CodeFilepathKey.String(file)) 46 } 47 48 sub := log.With().Str("traceid", span.SpanContext().TraceID().String()).Logger() 49 ctx = appctx.WithLogger(ctx, &sub) 50 ctx = appctx.WithTracerProvider(ctx, tp) 51 res, err := handler(ctx, req) 52 return res, err 53 } 54 return interceptor 55 } 56 57 // NewStream returns a new server stream interceptor 58 // that creates the application context. 59 func NewStream(log zerolog.Logger, tp trace.TracerProvider) grpc.StreamServerInterceptor { 60 interceptor := func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { 61 ctx := ss.Context() 62 span := trace.SpanFromContext(ctx) 63 defer span.End() 64 65 if !span.SpanContext().HasTraceID() { 66 ctx, span = tp.Tracer(tracerName).Start(ctx, "grpc stream") 67 } 68 _, file, _, ok := runtime.Caller(1) 69 if ok { 70 span.SetAttributes(semconv.CodeFilepathKey.String(file)) 71 } 72 73 sub := log.With().Str("traceid", span.SpanContext().TraceID().String()).Logger() 74 ctx = appctx.WithLogger(ctx, &sub) 75 76 wrapped := newWrappedServerStream(ctx, ss) 77 err := handler(srv, wrapped) 78 return err 79 } 80 return interceptor 81 } 82 83 func newWrappedServerStream(ctx context.Context, ss grpc.ServerStream) *wrappedServerStream { 84 return &wrappedServerStream{ServerStream: ss, newCtx: ctx} 85 } 86 87 type wrappedServerStream struct { 88 grpc.ServerStream 89 newCtx context.Context 90 } 91 92 func (ss *wrappedServerStream) Context() context.Context { 93 return ss.newCtx 94 }