@@ -7,13 +7,15 @@ import (
77
88 "go.opentelemetry.io/otel"
99 "go.opentelemetry.io/otel/propagation"
10+ "go.opentelemetry.io/otel/trace"
1011
1112 "github.com/warpstreamlabs/bento/internal/bundle"
1213 "github.com/warpstreamlabs/bento/public/bloblang"
1314)
1415
1516const (
16- etsField = "extract_tracing_map"
17+ etsField = "extract_tracing_map"
18+ nrswlField = "new_root_span_with_link"
1719)
1820
1921// NewExtractTracingSpanMappingField returns a config field for mapping messages
@@ -27,18 +29,33 @@ func NewExtractTracingSpanMappingField() *ConfigField {
2729 Advanced ()
2830}
2931
32+ func NewRootSpanWithLinkField () * ConfigField {
33+ return NewBoolField (nrswlField ).
34+ Description ("EXPERIMENTAL: Starts a new root span with link to parent." ).
35+ Version ("1.0.0" ).
36+ Optional ().
37+ Advanced ()
38+ }
39+
3040// WrapBatchInputExtractTracingSpanMapping wraps a BatchInput with a mechanism
3141// for extracting tracing spans using a bloblang mapping.
3242func (p * ParsedConfig ) WrapBatchInputExtractTracingSpanMapping (inputName string , i BatchInput ) (
3343 BatchInput , error ) {
3444 if str , _ := p .FieldString (etsField ); str == "" {
3545 return i , nil
3646 }
47+
3748 exe , err := p .FieldBloblang (etsField )
3849 if err != nil {
3950 return nil , err
4051 }
41- return & spanInjectBatchInput {inputName : inputName , mgr : p .mgr , mapping : exe , rdr : i }, nil
52+
53+ newSpan , err := p .FieldBool (nrswlField )
54+ if err != nil && ! strings .Contains (err .Error (), "was not found in the config" ) {
55+ return nil , err
56+ }
57+
58+ return & spanInjectBatchInput {inputName : inputName , mgr : p .mgr , mapping : exe , rdr : i , newSpan : newSpan }, nil
4259}
4360
4461// WrapInputExtractTracingSpanMapping wraps a Input with a mechanism for
@@ -51,7 +68,13 @@ func (p *ParsedConfig) WrapInputExtractTracingSpanMapping(inputName string, i In
5168 if err != nil {
5269 return nil , err
5370 }
54- return & spanInjectInput {inputName : inputName , mgr : p .mgr , mapping : exe , rdr : i }, nil
71+
72+ newSpan , err := p .FieldBool (nrswlField )
73+ if err != nil && ! strings .Contains (err .Error (), "was not found in the config" ) {
74+ return nil , err
75+ }
76+
77+ return & spanInjectInput {inputName : inputName , mgr : p .mgr , mapping : exe , rdr : i , newSpan : newSpan }, nil
5578}
5679
5780func getPropMapCarrier (spanPart * Message ) (propagation.MapCarrier , error ) {
@@ -82,6 +105,7 @@ type spanInjectBatchInput struct {
82105
83106 mapping * bloblang.Executor
84107 rdr BatchInput
108+ newSpan bool
85109}
86110
87111func (s * spanInjectBatchInput ) Connect (ctx context.Context ) error {
@@ -112,7 +136,16 @@ func (s *spanInjectBatchInput) ReadBatch(ctx context.Context) (MessageBatch, Ack
112136 textProp := otel .GetTextMapPropagator ()
113137 for i , p := range m {
114138 ctx := textProp .Extract (p .Context (), c )
115- pCtx , _ := prov .Tracer ("bento" ).Start (ctx , operationName )
139+
140+ var opts []trace.SpanStartOption
141+ if s .newSpan {
142+ opts = []trace.SpanStartOption {
143+ trace .WithNewRoot (),
144+ trace .WithLinks (trace .LinkFromContext (ctx )),
145+ }
146+ }
147+
148+ pCtx , _ := prov .Tracer ("bento" ).Start (ctx , operationName , opts ... )
116149 m [i ] = p .WithContext (pCtx )
117150 }
118151 return m , afn , nil
@@ -130,6 +163,7 @@ type spanInjectInput struct {
130163
131164 mapping * bloblang.Executor
132165 rdr Input
166+ newSpan bool
133167}
134168
135169func (s * spanInjectInput ) Connect (ctx context.Context ) error {
@@ -159,7 +193,17 @@ func (s *spanInjectInput) Read(ctx context.Context) (*Message, AckFunc, error) {
159193
160194 textProp := otel .GetTextMapPropagator ()
161195
162- pCtx , _ := prov .Tracer ("bento" ).Start (textProp .Extract (m .Context (), c ), operationName )
196+ ctx = textProp .Extract (m .Context (), c )
197+
198+ var opts []trace.SpanStartOption
199+ if s .newSpan {
200+ opts = []trace.SpanStartOption {
201+ trace .WithNewRoot (),
202+ trace .WithLinks (trace .LinkFromContext (ctx )),
203+ }
204+ }
205+
206+ pCtx , _ := prov .Tracer ("bento" ).Start (ctx , operationName , opts ... )
163207 m = m .WithContext (pCtx )
164208
165209 return m , afn , nil
0 commit comments