github.com/asynkron/protoactor-go@v0.0.0-20240308120642-ef91a6abee75/actor/middleware/opentracing/receivermiddleware.go (about) 1 package opentracing 2 3 import ( 4 "fmt" 5 "log/slog" 6 7 "github.com/asynkron/protoactor-go/actor" 8 "github.com/opentracing/opentracing-go" 9 ) 10 11 func ReceiverMiddleware() actor.ReceiverMiddleware { 12 return func(next actor.ReceiverFunc) actor.ReceiverFunc { 13 return func(c actor.ReceiverContext, envelope *actor.MessageEnvelope) { 14 spanContext, err := opentracing.GlobalTracer().Extract(opentracing.TextMap, opentracing.TextMapReader(&messageHeaderReader{ReadOnlyMessageHeader: envelope.Header})) 15 if err == opentracing.ErrSpanContextNotFound { 16 c.Logger().Debug("INBOUND No spanContext found", slog.Any("self", c.Self()), slog.Any("error", err)) 17 // next(c) 18 } else if err != nil { 19 c.Logger().Debug("INBOUND Error", slog.Any("self", c.Self()), slog.Any("error", err)) 20 next(c, envelope) 21 return 22 } 23 var span opentracing.Span 24 switch envelope.Message.(type) { 25 case *actor.Started: 26 parentSpan := getAndClearParentSpan(c.Self()) 27 if parentSpan != nil { 28 span = opentracing.StartSpan(fmt.Sprintf("%T/%T", c.Actor(), envelope.Message), opentracing.ChildOf(parentSpan.Context())) 29 c.Logger().Debug("INBOUND Found parent span", slog.Any("self", c.Self()), slog.Any("actor", c.Actor()), slog.Any("message", envelope.Message)) 30 } else { 31 c.Logger().Debug("INBOUND No parent span", slog.Any("self", c.Self()), slog.Any("actor", c.Actor()), slog.Any("message", envelope.Message)) 32 } 33 case *actor.Stopping: 34 var parentSpan opentracing.Span 35 if c.Parent() != nil { 36 parentSpan = getStoppingSpan(c.Parent()) 37 } 38 if parentSpan != nil { 39 span = opentracing.StartSpan(fmt.Sprintf("%T/stopping", c.Actor()), opentracing.ChildOf(parentSpan.Context())) 40 } else { 41 span = opentracing.StartSpan(fmt.Sprintf("%T/stopping", c.Actor())) 42 } 43 setStoppingSpan(c.Self(), span) 44 span.SetTag("ActorPID", c.Self()) 45 span.SetTag("ActorType", fmt.Sprintf("%T", c.Actor())) 46 span.SetTag("MessageType", fmt.Sprintf("%T", envelope.Message)) 47 stoppingHandlingSpan := opentracing.StartSpan("stopping-handling", opentracing.ChildOf(span.Context())) 48 next(c, envelope) 49 stoppingHandlingSpan.Finish() 50 return 51 case *actor.Stopped: 52 span = getAndClearStoppingSpan(c.Self()) 53 next(c, envelope) 54 if span != nil { 55 span.Finish() 56 } 57 return 58 } 59 if span == nil && spanContext == nil { 60 c.Logger().Debug("INBOUND No spanContext. Starting new span", slog.Any("self", c.Self()), slog.Any("actor", c.Actor()), slog.Any("message", envelope.Message)) 61 span = opentracing.StartSpan(fmt.Sprintf("%T/%T", c.Actor(), envelope.Message)) 62 } 63 if span == nil { 64 c.Logger().Debug("INBOUND Starting span from parent", slog.Any("self", c.Self()), slog.Any("actor", c.Actor()), slog.Any("message", envelope.Message)) 65 span = opentracing.StartSpan(fmt.Sprintf("%T/%T", c.Actor(), envelope.Message), opentracing.ChildOf(spanContext)) 66 } 67 68 setActiveSpan(c.Self(), span) 69 span.SetTag("ActorPID", c.Self()) 70 span.SetTag("ActorType", fmt.Sprintf("%T", c.Actor())) 71 span.SetTag("MessageType", fmt.Sprintf("%T", envelope.Message)) 72 73 defer func() { 74 c.Logger().Debug("INBOUND Finishing span", slog.Any("self", c.Self()), slog.Any("actor", c.Actor()), slog.Any("message", envelope.Message)) 75 span.Finish() 76 clearActiveSpan(c.Self()) 77 }() 78 79 next(c, envelope) 80 } 81 } 82 }