github.com/Jeffail/benthos/v3@v3.65.0/lib/message/tracing/package.go (about) 1 // Package tracing implements utility functions for recording opentracing events 2 // for messages. 3 // 4 // Deprecated: Use ./internal/tracing instead. 5 package tracing 6 7 import ( 8 "github.com/Jeffail/benthos/v3/lib/message" 9 "github.com/Jeffail/benthos/v3/lib/types" 10 "github.com/opentracing/opentracing-go" 11 ) 12 13 //------------------------------------------------------------------------------ 14 15 // GetSpan returns a span attached to a message part. Returns nil if the part 16 // doesn't have a span attached. 17 func GetSpan(p types.Part) opentracing.Span { 18 return opentracing.SpanFromContext(message.GetContext(p)) 19 } 20 21 // CreateChildSpan takes a message part, extracts an existing span if there is 22 // one and returns child span. 23 func CreateChildSpan(operationName string, part types.Part) opentracing.Span { 24 span := GetSpan(part) 25 if span == nil { 26 span = opentracing.StartSpan(operationName) 27 } else { 28 span = opentracing.StartSpan( 29 operationName, 30 opentracing.ChildOf(span.Context()), 31 ) 32 } 33 return span 34 } 35 36 // CreateChildSpans takes a message, extracts spans per message part and returns 37 // a slice of child spans. The length of the returned slice is guaranteed to 38 // match the message size. 39 func CreateChildSpans(operationName string, msg types.Message) []opentracing.Span { 40 spans := make([]opentracing.Span, msg.Len()) 41 msg.Iter(func(i int, part types.Part) error { 42 spans[i] = CreateChildSpan(operationName, part) 43 return nil 44 }) 45 return spans 46 } 47 48 // PartsWithChildSpans takes a slice of message parts, extracts spans per part, 49 // creates new child spans, and returns a new slice of parts with those spans 50 // embedded. The original parts are unchanged. 51 func PartsWithChildSpans(operationName string, parts []types.Part) ([]types.Part, []opentracing.Span) { 52 spans := make([]opentracing.Span, 0, len(parts)) 53 newParts := make([]types.Part, len(parts)) 54 for i, part := range parts { 55 if part == nil { 56 continue 57 } 58 ctx := message.GetContext(part) 59 span := opentracing.SpanFromContext(ctx) 60 if span == nil { 61 span = opentracing.StartSpan(operationName) 62 } else { 63 span = opentracing.StartSpan( 64 operationName, 65 opentracing.ChildOf(span.Context()), 66 ) 67 } 68 ctx = opentracing.ContextWithSpan(ctx, span) 69 newParts[i] = message.WithContext(ctx, part) 70 spans = append(spans, span) 71 } 72 return newParts, spans 73 } 74 75 // WithChildSpans takes a message, extracts spans per message part, creates new 76 // child spans, and returns a new message with those spans embedded. The 77 // original message is unchanged. 78 func WithChildSpans(operationName string, msg types.Message) (types.Message, []opentracing.Span) { 79 parts := make([]types.Part, 0, msg.Len()) 80 msg.Iter(func(i int, p types.Part) error { 81 parts = append(parts, p) 82 return nil 83 }) 84 85 newParts, spans := PartsWithChildSpans(operationName, parts) 86 newMsg := message.New(nil) 87 newMsg.SetAll(newParts) 88 89 return newMsg, spans 90 } 91 92 // WithSiblingSpans takes a message, extracts spans per message part, creates 93 // new sibling spans, and returns a new message with those spans embedded. The 94 // original message is unchanged. 95 func WithSiblingSpans(operationName string, msg types.Message) types.Message { 96 parts := make([]types.Part, msg.Len()) 97 msg.Iter(func(i int, part types.Part) error { 98 ctx := message.GetContext(part) 99 span := opentracing.SpanFromContext(ctx) 100 if span == nil { 101 span = opentracing.StartSpan(operationName) 102 } else { 103 span = opentracing.StartSpan( 104 operationName, 105 opentracing.FollowsFrom(span.Context()), 106 ) 107 } 108 ctx = opentracing.ContextWithSpan(ctx, span) 109 parts[i] = message.WithContext(ctx, part) 110 return nil 111 }) 112 113 newMsg := message.New(nil) 114 newMsg.SetAll(parts) 115 return newMsg 116 } 117 118 //------------------------------------------------------------------------------ 119 120 // IterateWithChildSpans iterates all the parts of a message and, for each part, 121 // creates a new span from an existing span attached to the part and calls a 122 // func with that span before finishing the child span. 123 func IterateWithChildSpans(operationName string, msg types.Message, iter func(int, opentracing.Span, types.Part) error) error { 124 return msg.Iter(func(i int, p types.Part) error { 125 span, _ := opentracing.StartSpanFromContext(message.GetContext(p), operationName) 126 err := iter(i, span, p) 127 span.Finish() 128 return err 129 }) 130 } 131 132 // InitSpans sets up OpenTracing spans on each message part if one does not 133 // already exist. 134 func InitSpans(operationName string, msg types.Message) { 135 tracedParts := make([]types.Part, msg.Len()) 136 msg.Iter(func(i int, p types.Part) error { 137 tracedParts[i] = InitSpan(operationName, p) 138 return nil 139 }) 140 msg.SetAll(tracedParts) 141 } 142 143 // InitSpan sets up an OpenTracing span on a message part if one does not 144 // already exist. 145 func InitSpan(operationName string, part types.Part) types.Part { 146 if GetSpan(part) != nil { 147 return part 148 } 149 span := opentracing.StartSpan(operationName) 150 ctx := opentracing.ContextWithSpan(message.GetContext(part), span) 151 return message.WithContext(ctx, part) 152 } 153 154 // InitSpansFromParent sets up OpenTracing spans as children of a parent span on 155 // each message part if one does not already exist. 156 func InitSpansFromParent(operationName string, parent opentracing.SpanContext, msg types.Message) { 157 tracedParts := make([]types.Part, msg.Len()) 158 msg.Iter(func(i int, p types.Part) error { 159 tracedParts[i] = InitSpanFromParent(operationName, parent, p) 160 return nil 161 }) 162 msg.SetAll(tracedParts) 163 } 164 165 // InitSpanFromParent sets up an OpenTracing span as children of a parent 166 // span on a message part if one does not already exist. 167 func InitSpanFromParent(operationName string, parent opentracing.SpanContext, part types.Part) types.Part { 168 if GetSpan(part) != nil { 169 return part 170 } 171 span := opentracing.StartSpan(operationName, opentracing.ChildOf(parent)) 172 ctx := opentracing.ContextWithSpan(message.GetContext(part), span) 173 return message.WithContext(ctx, part) 174 } 175 176 // FinishSpans calls Finish on all message parts containing a span. 177 func FinishSpans(msg types.Message) { 178 msg.Iter(func(i int, p types.Part) error { 179 span := GetSpan(p) 180 if span == nil { 181 return nil 182 } 183 span.Finish() 184 return nil 185 }) 186 } 187 188 //------------------------------------------------------------------------------