Skip to content

Commit 2ac229b

Browse files
committed
appsec: stop storing span tags, directly call span.SetTag
Signed-off-by: Eliott Bouhana <[email protected]>
1 parent e8b2b8c commit 2ac229b

File tree

9 files changed

+42
-43
lines changed

9 files changed

+42
-43
lines changed

contrib/99designs/gqlgen/tracer.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ func (t *gqlTracer) Validate(_ graphql.ExecutableSchema) error {
103103
func (t *gqlTracer) InterceptOperation(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler {
104104
opCtx := graphql.GetOperationContext(ctx)
105105
span, ctx := t.createRootSpan(ctx, opCtx)
106-
ctx, req := graphqlsec.StartRequestOperation(ctx, graphqlsec.RequestOperationArgs{
106+
ctx, req := graphqlsec.StartRequestOperation(ctx, span, graphqlsec.RequestOperationArgs{
107107
RawQuery: opCtx.RawQuery,
108108
OperationName: opCtx.OperationName,
109109
Variables: opCtx.Variables,
@@ -137,7 +137,7 @@ func (t *gqlTracer) InterceptOperation(ctx context.Context, next graphql.Operati
137137
}
138138

139139
query.Finish(executionOperationRes)
140-
req.Finish(span, requestOperationRes)
140+
req.Finish(requestOperationRes)
141141
return response
142142
}
143143
}

contrib/google.golang.org/grpc/appsec.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func appsecUnaryHandlerMiddleware(method string, span ddtrace.Span, handler grpc
4444
remoteAddr = p.Addr.String()
4545
}
4646

47-
ctx, op, blockAtomic := grpcsec.StartHandlerOperation(ctx, grpcsec.HandlerOperationArgs{
47+
ctx, op, blockAtomic := grpcsec.StartHandlerOperation(ctx, span, grpcsec.HandlerOperationArgs{
4848
Method: method,
4949
Metadata: md,
5050
RemoteAddr: remoteAddr,
@@ -55,7 +55,7 @@ func appsecUnaryHandlerMiddleware(method string, span ddtrace.Span, handler grpc
5555
if statusErr, ok := rpcErr.(interface{ GRPCStatus() *status.Status }); ok && !applyAction(blockAtomic, &rpcErr) {
5656
statusCode = int(statusErr.GRPCStatus().Code())
5757
}
58-
op.Finish(span, grpcsec.HandlerOperationRes{StatusCode: statusCode})
58+
op.Finish(grpcsec.HandlerOperationRes{StatusCode: statusCode})
5959
applyAction(blockAtomic, &rpcErr)
6060
}()
6161

@@ -90,7 +90,7 @@ func appsecStreamHandlerMiddleware(method string, span ddtrace.Span, handler grp
9090
}
9191

9292
// Create the handler operation and listen to blocking gRPC actions to detect a blocking condition
93-
ctx, op, blockAtomic := grpcsec.StartHandlerOperation(ctx, grpcsec.HandlerOperationArgs{
93+
ctx, op, blockAtomic := grpcsec.StartHandlerOperation(ctx, span, grpcsec.HandlerOperationArgs{
9494
Method: method,
9595
Metadata: md,
9696
RemoteAddr: remoteAddr,
@@ -104,7 +104,7 @@ func appsecStreamHandlerMiddleware(method string, span ddtrace.Span, handler grp
104104
statusCode = int(res.Status())
105105
}
106106

107-
op.Finish(span, grpcsec.HandlerOperationRes{StatusCode: statusCode})
107+
op.Finish(grpcsec.HandlerOperationRes{StatusCode: statusCode})
108108
applyAction(blockAtomic, &rpcErr)
109109
}()
110110

contrib/graph-gophers/graphql-go/graphql.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func (t *Tracer) TraceQuery(ctx context.Context, queryString, operationName stri
7070
}
7171
span, ctx := ddtracer.StartSpanFromContext(ctx, t.cfg.querySpanName, opts...)
7272

73-
ctx, request := graphqlsec.StartRequestOperation(ctx, graphqlsec.RequestOperationArgs{
73+
ctx, request := graphqlsec.StartRequestOperation(ctx, span, graphqlsec.RequestOperationArgs{
7474
RawQuery: queryString,
7575
OperationName: operationName,
7676
Variables: variables,
@@ -92,7 +92,7 @@ func (t *Tracer) TraceQuery(ctx context.Context, queryString, operationName stri
9292
err = fmt.Errorf("%s (and %d more errors)", errs[0], n-1)
9393
}
9494
defer span.Finish(ddtracer.WithError(err))
95-
defer request.Finish(span, graphqlsec.RequestOperationRes{Error: err})
95+
defer request.Finish(graphqlsec.RequestOperationRes{Error: err})
9696
query.Finish(graphqlsec.ExecutionOperationRes{Error: err})
9797
}
9898
}

contrib/graphql-go/graphql/graphql.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ type contextData struct {
7272
// finish closes the top-level request operation, as well as the server span.
7373
func (c *contextData) finish(data any, err error) {
7474
defer c.serverSpan.Finish(tracer.WithError(err))
75-
c.requestOp.Finish(c.serverSpan, graphqlsec.RequestOperationRes{Data: data, Error: err})
75+
c.requestOp.Finish(graphqlsec.RequestOperationRes{Data: data, Error: err})
7676
}
7777

7878
var extensionName = reflect.TypeOf((*datadogExtension)(nil)).Elem().Name()
@@ -97,7 +97,7 @@ func (i datadogExtension) Init(ctx context.Context, params *graphql.Params) cont
9797
tracer.Tag(ext.Component, componentName),
9898
tracer.Measured(),
9999
)
100-
ctx, request := graphqlsec.StartRequestOperation(ctx, graphqlsec.RequestOperationArgs{
100+
ctx, request := graphqlsec.StartRequestOperation(ctx, span, graphqlsec.RequestOperationArgs{
101101
RawQuery: params.RequestString,
102102
Variables: params.VariableValues,
103103
OperationName: params.OperationName,

internal/appsec/emitter/graphqlsec/request.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ type (
4444

4545
// Finish the GraphQL query operation, along with the given results, and emit a finish event up in
4646
// the operation stack.
47-
func (op *RequestOperation) Finish(span trace.TagSetter, res RequestOperationRes) {
47+
func (op *RequestOperation) Finish(res RequestOperationRes) {
4848
dyngo.FinishOperation(op, res)
4949
if op.wafContextOwner {
50-
op.ContextOperation.Finish(span)
50+
op.ContextOperation.Finish()
5151
}
5252
}
5353

@@ -58,10 +58,10 @@ func (RequestOperationRes) IsResultOf(*RequestOperation) {}
5858
// emits a start event up in the operation stack. The operation is usually linked to tge global root
5959
// operation. The operation is tracked on the returned context, and can be extracted later on using
6060
// FromContext.
61-
func StartRequestOperation(ctx context.Context, args RequestOperationArgs) (context.Context, *RequestOperation) {
61+
func StartRequestOperation(ctx context.Context, span trace.TagSetter, args RequestOperationArgs) (context.Context, *RequestOperation) {
6262
wafOp, found := dyngo.FindOperation[waf.ContextOperation](ctx)
6363
if !found { // Usually we can find the HTTP Handler Operation as the parent, but it's technically optional
64-
wafOp, ctx = waf.StartContextOperation(ctx)
64+
wafOp, ctx = waf.StartContextOperation(ctx, span)
6565
}
6666

6767
op := &RequestOperation{

internal/appsec/emitter/grpcsec/grpc.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,10 @@ func (HandlerOperationRes) IsResultOf(*HandlerOperation) {}
7777
// given arguments and parent operation, and emits a start event up in the
7878
// operation stack. When parent is nil, the operation is linked to the global
7979
// root operation.
80-
func StartHandlerOperation(ctx context.Context, args HandlerOperationArgs) (context.Context, *HandlerOperation, *atomic.Pointer[actions.BlockGRPC]) {
80+
func StartHandlerOperation(ctx context.Context, span trace.TagSetter, args HandlerOperationArgs) (context.Context, *HandlerOperation, *atomic.Pointer[actions.BlockGRPC]) {
8181
wafOp, found := dyngo.FindOperation[waf.ContextOperation](ctx)
8282
if !found {
83-
wafOp, ctx = waf.StartContextOperation(ctx)
83+
wafOp, ctx = waf.StartContextOperation(ctx, span)
8484
}
8585
op := &HandlerOperation{
8686
Operation: dyngo.NewOperation(wafOp),
@@ -117,9 +117,9 @@ func MonitorResponseMessage(ctx context.Context, msg any) error {
117117

118118
// Finish the gRPC handler operation, along with the given results, and emit a
119119
// finish event up in the operation stack.
120-
func (op *HandlerOperation) Finish(span trace.TagSetter, res HandlerOperationRes) {
120+
func (op *HandlerOperation) Finish(res HandlerOperationRes) {
121121
dyngo.FinishOperation(op, res)
122122
if op.wafContextOwner {
123-
op.ContextOperation.Finish(span)
123+
op.ContextOperation.Finish()
124124
}
125125
}

internal/appsec/emitter/httpsec/http.go

+7-6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919

2020
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace"
2121
"gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/dyngo"
22+
"gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/trace"
2223
"gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/waf"
2324
"gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/waf/actions"
2425
"gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/waf/addresses"
@@ -57,10 +58,10 @@ type (
5758
func (HandlerOperationArgs) IsArgOf(*HandlerOperation) {}
5859
func (HandlerOperationRes) IsResultOf(*HandlerOperation) {}
5960

60-
func StartOperation(ctx context.Context, args HandlerOperationArgs) (*HandlerOperation, *atomic.Pointer[actions.BlockHTTP], context.Context) {
61+
func StartOperation(ctx context.Context, args HandlerOperationArgs, span trace.TagSetter) (*HandlerOperation, *atomic.Pointer[actions.BlockHTTP], context.Context) {
6162
wafOp, found := dyngo.FindOperation[waf.ContextOperation](ctx)
6263
if !found {
63-
wafOp, ctx = waf.StartContextOperation(ctx)
64+
wafOp, ctx = waf.StartContextOperation(ctx, span)
6465
}
6566

6667
op := &HandlerOperation{
@@ -79,10 +80,10 @@ func StartOperation(ctx context.Context, args HandlerOperationArgs) (*HandlerOpe
7980
}
8081

8182
// Finish the HTTP handler operation and its children operations and write everything to the service entry span.
82-
func (op *HandlerOperation) Finish(res HandlerOperationRes, span ddtrace.Span) {
83+
func (op *HandlerOperation) Finish(res HandlerOperationRes) {
8384
dyngo.FinishOperation(op, res)
8485
if op.wafContextOwner {
85-
op.ContextOperation.Finish(span)
86+
op.ContextOperation.Finish()
8687
}
8788
}
8889

@@ -142,7 +143,7 @@ func BeforeHandle(
142143
Cookies: makeCookies(r.Cookies()),
143144
QueryParams: r.URL.Query(),
144145
PathParams: pathParams,
145-
})
146+
}, span)
146147
tr := r.WithContext(ctx)
147148
var blocked atomic.Bool
148149

@@ -154,7 +155,7 @@ func BeforeHandle(
154155
op.Finish(HandlerOperationRes{
155156
Headers: opts.ResponseHeaderCopier(w),
156157
StatusCode: statusCode,
157-
}, span)
158+
})
158159

159160
if blockPtr := blockAtomic.Swap(nil); blockPtr != nil {
160161
blockPtr.Handler.ServeHTTP(w, tr)

internal/appsec/emitter/trace/service_entry_span.go

+13-15
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ type (
1818
// ServiceEntrySpanOperation is a dyngo.Operation that holds a the first span of a service. Usually a http or grpc span.
1919
ServiceEntrySpanOperation struct {
2020
dyngo.Operation
21-
tags map[string]any
22-
jsonTags map[string]any
23-
mu sync.Mutex
21+
jsonTags map[string]any
22+
tagSetter TagSetter
23+
mu sync.Mutex
2424
}
2525

2626
// ServiceEntrySpanArgs is the arguments for a ServiceEntrySpanOperation
@@ -52,7 +52,7 @@ func (ServiceEntrySpanArgs) IsArgOf(*ServiceEntrySpanOperation) {}
5252
func (op *ServiceEntrySpanOperation) SetTag(key string, value any) {
5353
op.mu.Lock()
5454
defer op.mu.Unlock()
55-
op.tags[key] = value
55+
op.tagSetter.SetTag(key, value)
5656
}
5757

5858
// SetSerializableTag adds the key/value pair to the tags to add to the service entry span.
@@ -76,7 +76,7 @@ func (op *ServiceEntrySpanOperation) SetSerializableTags(tags map[string]any) {
7676
func (op *ServiceEntrySpanOperation) setSerializableTag(key string, value any) {
7777
switch value.(type) {
7878
case string, int8, int16, int32, int64, uint8, uint16, uint32, uint64, float32, float64, bool:
79-
op.tags[key] = value
79+
op.tagSetter.SetTag(key, value)
8080
default:
8181
op.jsonTags[key] = value
8282
}
@@ -87,7 +87,7 @@ func (op *ServiceEntrySpanOperation) SetTags(tags map[string]any) {
8787
op.mu.Lock()
8888
defer op.mu.Unlock()
8989
for k, v := range tags {
90-
op.tags[k] = v
90+
op.tagSetter.SetTag(k, v)
9191
}
9292
}
9393

@@ -96,7 +96,7 @@ func (op *ServiceEntrySpanOperation) SetStringTags(tags map[string]string) {
9696
op.mu.Lock()
9797
defer op.mu.Unlock()
9898
for k, v := range tags {
99-
op.tags[k] = v
99+
op.tagSetter.SetTag(k, v)
100100
}
101101
}
102102

@@ -126,32 +126,30 @@ func (op *ServiceEntrySpanOperation) OnSpanTagEvent(tag SpanTag) {
126126
op.SetTag(tag.Key, tag.Value)
127127
}
128128

129-
func StartServiceEntrySpanOperation(ctx context.Context) (*ServiceEntrySpanOperation, context.Context) {
129+
func StartServiceEntrySpanOperation(ctx context.Context, span TagSetter) (*ServiceEntrySpanOperation, context.Context) {
130130
parent, _ := dyngo.FromContext(ctx)
131131
op := &ServiceEntrySpanOperation{
132132
Operation: dyngo.NewOperation(parent),
133-
tags: make(map[string]any),
134-
jsonTags: make(map[string]any),
133+
jsonTags: make(map[string]any, 2),
134+
tagSetter: span,
135135
}
136136
return op, dyngo.StartAndRegisterOperation(ctx, op, ServiceEntrySpanArgs{})
137137
}
138138

139-
func (op *ServiceEntrySpanOperation) Finish(span TagSetter) {
139+
func (op *ServiceEntrySpanOperation) Finish() {
140+
span := op.tagSetter
140141
if _, ok := span.(*NoopTagSetter); ok { // If the span is a NoopTagSetter or is nil, we don't need to set any tags
141142
return
142143
}
143144

144145
op.mu.Lock()
145146
defer op.mu.Unlock()
146147

147-
for k, v := range op.tags {
148-
span.SetTag(k, v)
149-
}
150-
151148
for k, v := range op.jsonTags {
152149
strValue, err := json.Marshal(v)
153150
if err != nil {
154151
log.Debug("appsec: failed to marshal tag %s: %v", k, err)
152+
continue
155153
}
156154
span.SetTag(k, string(strValue))
157155
}

internal/appsec/emitter/waf/context.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -61,18 +61,18 @@ type (
6161
func (ContextArgs) IsArgOf(*ContextOperation) {}
6262
func (ContextRes) IsResultOf(*ContextOperation) {}
6363

64-
func StartContextOperation(ctx context.Context) (*ContextOperation, context.Context) {
65-
entrySpanOp, ctx := trace.StartServiceEntrySpanOperation(ctx)
64+
func StartContextOperation(ctx context.Context, span trace.TagSetter) (*ContextOperation, context.Context) {
65+
entrySpanOp, ctx := trace.StartServiceEntrySpanOperation(ctx, span)
6666
op := &ContextOperation{
6767
Operation: dyngo.NewOperation(entrySpanOp),
6868
ServiceEntrySpanOperation: entrySpanOp,
6969
}
7070
return op, dyngo.StartAndRegisterOperation(ctx, op, ContextArgs{})
7171
}
7272

73-
func (op *ContextOperation) Finish(span trace.TagSetter) {
73+
func (op *ContextOperation) Finish() {
7474
dyngo.FinishOperation(op, ContextRes{})
75-
op.ServiceEntrySpanOperation.Finish(span)
75+
op.ServiceEntrySpanOperation.Finish()
7676
}
7777

7878
func (op *ContextOperation) SwapContext(ctx *waf.Context) *waf.Context {

0 commit comments

Comments
 (0)