53 lines
1.7 KiB
Go
53 lines
1.7 KiB
Go
package sentry
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/getsentry/sentry-go/internal/debuglog"
|
|
"github.com/getsentry/sentry-go/internal/otel/baggage"
|
|
)
|
|
|
|
// MergeBaggage merges an existing baggage header with a Sentry-generated one.
|
|
//
|
|
// Existing third-party members are preserved. If both baggage strings contain
|
|
// the same member key, the Sentry-generated member wins. The helper is best-effort
|
|
// and only keeps the sentry baggage in case the existing one is malformed.
|
|
func MergeBaggage(existingHeader, sentryHeader string) (string, error) {
|
|
// TODO: we are reparsing the headers here, because we currently don't
|
|
// expose a method to get only DSC or its baggage members.
|
|
sentryBaggage, err := baggage.Parse(sentryHeader)
|
|
if err != nil {
|
|
return "", fmt.Errorf("cannot parse sentryHeader: %w", err)
|
|
}
|
|
|
|
existingBaggage, err := baggage.Parse(existingHeader)
|
|
if err != nil {
|
|
if sentryBaggage.Len() == 0 {
|
|
return "", fmt.Errorf("cannot parse existingHeader: %w", err)
|
|
}
|
|
// in case that the incoming header is malformed we should only
|
|
// care about merging sentry related baggage information for distributed tracing.
|
|
debuglog.Printf("malformed incoming header: %v", err)
|
|
return sentryBaggage.String(), nil
|
|
}
|
|
|
|
sentryKeys := make(map[string]struct{}, sentryBaggage.Len())
|
|
for _, member := range sentryBaggage.Members() {
|
|
sentryKeys[member.Key()] = struct{}{}
|
|
}
|
|
|
|
parts := make([]string, 0, sentryBaggage.Len()+existingBaggage.Len())
|
|
if s := sentryBaggage.String(); s != "" {
|
|
parts = append(parts, s)
|
|
}
|
|
for _, member := range existingBaggage.Members() {
|
|
if _, collides := sentryKeys[member.Key()]; collides {
|
|
continue
|
|
}
|
|
parts = append(parts, member.String())
|
|
}
|
|
|
|
return strings.Join(parts, ","), nil
|
|
}
|