From 5dfc77a2d68517884c2a1454be13736b0fcb5e4a Mon Sep 17 00:00:00 2001 From: Nikita Volodin Date: Mon, 29 Apr 2024 01:54:28 -0400 Subject: [PATCH] feat(prose/filter): inject span context in w3c format for presidio --- .../internal/common/otel_propagator.go | 56 +++++++++++++++++++ .../internal/common/pii_analysis.go | 20 ++++++- 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 privacy-profile-composer/pkg/envoyfilter/internal/common/otel_propagator.go diff --git a/privacy-profile-composer/pkg/envoyfilter/internal/common/otel_propagator.go b/privacy-profile-composer/pkg/envoyfilter/internal/common/otel_propagator.go new file mode 100644 index 00000000..d1a653ad --- /dev/null +++ b/privacy-profile-composer/pkg/envoyfilter/internal/common/otel_propagator.go @@ -0,0 +1,56 @@ +package common + +import ( + "fmt" + + "github.com/openzipkin/zipkin-go/model" + "go.opentelemetry.io/otel/propagation" + "go.opentelemetry.io/otel/trace" +) + +var GlobalOtelPropagator = propagation.NewCompositeTextMapPropagator( + propagation.TraceContext{}, + propagation.Baggage{}, +) + +func otelSpanContextFromZipkin(span model.SpanContext) (trace.SpanContext, error) { + traceFlags := trace.TraceFlags(0) + if span.Sampled == nil { + traceFlags = traceFlags.WithSampled(false) + } else { + traceFlags = traceFlags.WithSampled(*span.Sampled) + } + + traceID, err := trace.TraceIDFromHex(fmt.Sprintf("%032s", span.TraceID.String())) + if err != nil { + return trace.NewSpanContext( + trace.SpanContextConfig{ + TraceFlags: traceFlags, + TraceState: trace.TraceState{}, + Remote: false, + }, + ), fmt.Errorf("invalid trace ID: %w", err) + } + + spanID, err := trace.SpanIDFromHex(span.ID.String()) + if err != nil { + return trace.NewSpanContext( + trace.SpanContextConfig{ + TraceID: traceID, + TraceFlags: traceFlags, + TraceState: trace.TraceState{}, + Remote: false, + }, + ), fmt.Errorf("invalid span ID: %w", err) + } + + return trace.NewSpanContext( + trace.SpanContextConfig{ + TraceID: traceID, + SpanID: spanID, + TraceFlags: traceFlags, + TraceState: trace.TraceState{}, + Remote: false, + }, + ), nil +} diff --git a/privacy-profile-composer/pkg/envoyfilter/internal/common/pii_analysis.go b/privacy-profile-composer/pkg/envoyfilter/internal/common/pii_analysis.go index 8a01c073..db0d3623 100644 --- a/privacy-profile-composer/pkg/envoyfilter/internal/common/pii_analysis.go +++ b/privacy-profile-composer/pkg/envoyfilter/internal/common/pii_analysis.go @@ -7,6 +7,9 @@ import ( "fmt" "io" "net/http" + + "go.opentelemetry.io/otel/propagation" + "go.opentelemetry.io/otel/trace" ) type PresidioDataFormat struct { @@ -18,6 +21,13 @@ func PiiAnalysis(ctx context.Context, presidioSvcURL string, svcName string, buf span, ctx := GlobalTracer.StartSpanFromContext(ctx, "PiiAnalysis") defer span.Finish() + otelSpanCtx, err := otelSpanContextFromZipkin(span.Context()) + if err != nil { + fmt.Printf("Error converting span context: %v\n", err) + } + + ctx = trace.ContextWithSpanContext(ctx, otelSpanCtx) + empty := []string{} msgString, err := json.Marshal( @@ -30,7 +40,15 @@ func PiiAnalysis(ctx context.Context, presidioSvcURL string, svcName string, buf return empty, fmt.Errorf("could not convert data for presidio into json: %w", err) } - resp, err := http.Post(presidioSvcURL, "application/json", bytes.NewBuffer(msgString)) + req, err := http.NewRequest("POST", presidioSvcURL, bytes.NewBuffer(msgString)) + if err != nil { + return empty, fmt.Errorf("could not create new request object: %w", err) + } + + req.Header.Set("Content-Type", "application/json") + GlobalOtelPropagator.Inject(ctx, propagation.HeaderCarrier(req.Header)) + + resp, err := http.DefaultClient.Do(req) if err != nil { return empty, fmt.Errorf("presidio post error: %w", err) }