Skip to content

Commit

Permalink
Merge branch 'main' into rarguelloF/AIDM-229/gocql-observer-api
Browse files Browse the repository at this point in the history
  • Loading branch information
rarguelloF authored Aug 12, 2024
2 parents 8124bdc + 0462924 commit c6c0385
Show file tree
Hide file tree
Showing 11 changed files with 185 additions and 15 deletions.
22 changes: 22 additions & 0 deletions .github/workflows/orchestrion.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Orchestrion
on:
workflow_dispatch: # manually
pull_request:
merge_group:
push:
branches:
- release-v*

permissions: read-all

concurrency:
# Automatically cancel previous runs if a new one is triggered to conserve resources.
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }}
cancel-in-progress: true

jobs:
test:
name: 'Run Tests'
uses: DataDog/orchestrion/.github/workflows/workflow_call.yml@main # we don't want to pin our own action
with:
dd-trace-go-ref: ${{ github.sha }}
2 changes: 1 addition & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ variables:
INDEX_FILE: index.txt
KUBERNETES_SERVICE_ACCOUNT_OVERWRITE: dd-trace-go
FF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGY: "true"
BENCHMARK_TARGETS: "BenchmarkStartRequestSpan|BenchmarkHttpServeTrace|BenchmarkTracerAddSpans|BenchmarkStartSpan|BenchmarkSingleSpanRetention|BenchmarkOTelApiWithCustomTags|BenchmarkInjectW3C|BenchmarkExtractW3C|BenchmarkPartialFlushing|BenchmarkGraphQL|BenchmarkSampleWAFContext|BenchmarkCaptureStackTrace"
BENCHMARK_TARGETS: "BenchmarkStartRequestSpan|BenchmarkHttpServeTrace|BenchmarkTracerAddSpans|BenchmarkStartSpan|BenchmarkSingleSpanRetention|BenchmarkOTelApiWithCustomTags|BenchmarkInjectW3C|BenchmarkExtractW3C|BenchmarkPartialFlushing|BenchmarkGraphQL|BenchmarkSampleWAFContext|BenchmarkCaptureStackTrace|BenchmarkSetTagString|BenchmarkSetTagStringPtr|BenchmarkSetTagMetric|BenchmarkSetTagStringer"

include:
- ".gitlab/benchmarks.yml"
Expand Down
1 change: 1 addition & 0 deletions ddtrace/tracer/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ var contribIntegrations = map[string]struct {
"github.com/valyala/fasthttp": {"FastHTTP", false},
"github.com/zenazn/goji": {"Goji", false},
"log/slog": {"log/slog", false},
"github.com/uptrace/bun": {"Bun", false},
}

var (
Expand Down
2 changes: 1 addition & 1 deletion ddtrace/tracer/option_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ func TestAgentIntegration(t *testing.T) {
defer clearIntegrationsForTests()

cfg.loadContribIntegrations(nil)
assert.Equal(t, 56, len(cfg.integrations))
assert.Equal(t, 57, len(cfg.integrations))
for integrationName, v := range cfg.integrations {
assert.False(t, v.Instrumented, "integrationName=%s", integrationName)
}
Expand Down
3 changes: 3 additions & 0 deletions ddtrace/tracer/span.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ func (s *span) BaggageItem(key string) string {

// SetTag adds a set of key/value metadata to the span.
func (s *span) SetTag(key string, value interface{}) {
// To avoid dumping the memory address in case value is a pointer, we dereference it.
// Any pointer value that is a pointer to a pointer will be dumped as a string.
value = dereference(value)
s.Lock()
defer s.Unlock()
// We don't lock spans when flushing, so we could have a data race when
Expand Down
29 changes: 24 additions & 5 deletions ddtrace/tracer/span_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,13 @@ func TestSpanSetTag(t *testing.T) {
span.SetTag("struct", sharedinternal.MetaStructValue{Value: testValue})
require.Equal(t, testValue, span.MetaStruct["struct"])

s := "string"
span.SetTag("str_ptr", &s)
assert.Equal(s, span.Meta["str_ptr"])

span.SetTag("nil_str_ptr", (*string)(nil))
assert.Equal("", span.Meta["nil_str_ptr"])

assert.Panics(func() {
span.SetTag("panicStringer", &panicStringer{})
})
Expand Down Expand Up @@ -1024,18 +1031,18 @@ func TestSetUserPropagatedUserID(t *testing.T) {

func BenchmarkSetTagMetric(b *testing.B) {
span := newBasicSpan("bench.span")
keys := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
keys := strings.Split("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", "")

b.ResetTimer()
for i := 0; i < b.N; i++ {
k := string(keys[i%len(keys)])
k := keys[i%len(keys)]
span.SetTag(k, float64(12.34))
}
}

func BenchmarkSetTagString(b *testing.B) {
span := newBasicSpan("bench.span")
keys := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
keys := strings.Split("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", "")

b.ResetTimer()
for i := 0; i < b.N; i++ {
Expand All @@ -1044,13 +1051,25 @@ func BenchmarkSetTagString(b *testing.B) {
}
}

func BenchmarkSetTagStringPtr(b *testing.B) {
span := newBasicSpan("bench.span")
keys := strings.Split("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", "")
v := makePointer("some text")

b.ResetTimer()
for i := 0; i < b.N; i++ {
k := keys[i%len(keys)]
span.SetTag(k, v)
}
}

func BenchmarkSetTagStringer(b *testing.B) {
span := newBasicSpan("bench.span")
keys := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
keys := strings.Split("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", "")
value := &stringer{}
b.ResetTimer()
for i := 0; i < b.N; i++ {
k := string(keys[i%len(keys)])
k := keys[i%len(keys)]
span.SetTag(k, value)
}
}
Expand Down
8 changes: 2 additions & 6 deletions ddtrace/tracer/textmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ func getDatadogPropagator(cp *chainedPropagator) *propagator {
// if the reparenting ID is not set on the context, the span ID from datadog headers is used.
func overrideDatadogParentID(ctx, w3cCtx, ddCtx *spanContext) {
ctx.spanID = w3cCtx.spanID
if w3cCtx.reparentID != "" && w3cCtx.reparentID != "0000000000000000" {
if w3cCtx.reparentID != "" {
ctx.reparentID = w3cCtx.reparentID
} else if ddCtx != nil {
// NIT: could be done without using fmt.Sprintf? Is it worth it?
Expand Down Expand Up @@ -967,7 +967,7 @@ func composeTracestate(ctx *spanContext, priority int, oldState string) string {
if !ctx.isRemote {
b.WriteString(";p:")
b.WriteString(spanIDHexEncoded(ctx.SpanID(), 16))
} else if ctx.reparentID != "" && ctx.reparentID != "0000000000000000" {
} else if ctx.reparentID != "" {
b.WriteString(";p:")
b.WriteString(ctx.reparentID)
}
Expand Down Expand Up @@ -1202,10 +1202,6 @@ func parseTracestate(ctx *spanContext, header string) {
setPropagatingTag(ctx, "_dd.p."+keySuffix, val)
}
}
// if dd list-member is present and last parent is not set, set it to zeros
if ctx.reparentID == "" {
ctx.reparentID = "0000000000000000"
}
}
}

Expand Down
10 changes: 8 additions & 2 deletions ddtrace/tracer/textmap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1756,7 +1756,7 @@ func TestEnvVars(t *testing.T) {
},
out: []uint64{8687463697196027922, 1311768467284833366},
priority: 1,
lastParent: "0000000000000000",
lastParent: "",
},
}
for i, tc := range tests {
Expand Down Expand Up @@ -1839,7 +1839,13 @@ func TestEnvVars(t *testing.T) {
if tc.priority != 0 {
sctx.setSamplingPriority(int(tc.priority), samplernames.Unknown)
}
assert.Equal(s.(*span).Meta["_dd.parent_id"], tc.lastParent)

if tc.lastParent == "" {
assert.Empty(s.(*span).Meta["_dd.parent_id"])
} else {
assert.Equal(s.(*span).Meta["_dd.parent_id"], tc.lastParent)
}

assert.Equal(true, sctx.updated)

headers := TextMapCarrier(map[string]string{})
Expand Down
53 changes: 53 additions & 0 deletions ddtrace/tracer/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
func toFloat64(value interface{}) (f float64, ok bool) {
const max = (int64(1) << 53) - 1
const min = -max
// If any other type is added here, remember to add it to the type switch in
// the `span.SetTag` function to handle pointers to these supported types.
switch i := value.(type) {
case byte:
return float64(i), true
Expand Down Expand Up @@ -122,3 +124,54 @@ func parsePropagatableTraceTags(s string) (map[string]string, error) {
tags[key] = s[start:]
return tags, nil
}

func dereference(value any) any {
// Falling into one of the cases will dereference the pointer and return the
// value of the pointer. It adds one allocation due to casting.
switch value.(type) {
case *bool:
return dereferenceGeneric(value.(*bool))
case *string:
return dereferenceGeneric(value.(*string))
// Supported type by toFloat64
case *byte:
return dereferenceGeneric(value.(*byte))
case *float32:
return dereferenceGeneric(value.(*float32))
case *float64:
return dereferenceGeneric(value.(*float64))
case *int:
return dereferenceGeneric(value.(*int))
case *int8:
return dereferenceGeneric(value.(*int8))
case *int16:
return dereferenceGeneric(value.(*int16))
case *int32:
return dereferenceGeneric(value.(*int32))
case *int64:
return dereferenceGeneric(value.(*int64))
case *uint:
return dereferenceGeneric(value.(*uint))
case *uint16:
return dereferenceGeneric(value.(*uint16))
case *uint32:
return dereferenceGeneric(value.(*uint32))
case *uint64:
return dereferenceGeneric(value.(*uint64))
case *samplernames.SamplerName:
v := value.(*samplernames.SamplerName)
if v == nil {
return samplernames.Unknown
}
return *v
}
return value
}

func dereferenceGeneric[T any](value *T) T {
if value == nil {
var v T
return v
}
return *value
}
58 changes: 58 additions & 0 deletions ddtrace/tracer/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"gopkg.in/DataDog/dd-trace-go.v1/internal/samplernames"
)

func TestToFloat64(t *testing.T) {
Expand Down Expand Up @@ -115,3 +116,60 @@ func TestParsePropagatableTraceTags(t *testing.T) {
})
}
}

func TestDereference(t *testing.T) {
for i, tt := range []struct {
value interface{}
expected interface{}
}{
{makePointer(1), 1},
{makePointer(byte(1)), byte(1)},
{makePointer(int16(1)), int16(1)},
{makePointer(int32(1)), int32(1)},
{makePointer(int64(1)), int64(1)},
{makePointer(uint(1)), uint(1)},
{makePointer(uint16(1)), uint16(1)},
{makePointer(uint32(1)), uint32(1)},
{makePointer(uint64(1)), uint64(1)},
{makePointer("a"), "a"},
{makePointer(float32(1.25)), float32(1.25)},
{makePointer(float64(1.25)), float64(1.25)},
{makePointer(true), true},
{makePointer(false), false},
{makePointer(samplernames.SingleSpan), samplernames.SingleSpan},
{(*int)(nil), 0},
{(*byte)(nil), byte(0)},
{(*int16)(nil), int16(0)},
{(*int32)(nil), int32(0)},
{(*int64)(nil), int64(0)},
{(*uint)(nil), uint(0)},
{(*uint16)(nil), uint16(0)},
{(*uint32)(nil), uint32(0)},
{(*uint64)(nil), uint64(0)},
{(*string)(nil), ""},
{(*float32)(nil), float32(0)},
{(*float64)(nil), float64(0)},
{(*bool)(nil), false},
{(*samplernames.SamplerName)(nil), samplernames.Unknown},
{newSpan("test", "service", "resource", 1, 2, 0), "itself"}, // This test uses a value which type is not supported by dereference.
} {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
actual := dereference(tt.value)
// This is a special case where we want to compare the value itself
// because the dereference function returns the given value.
if tt.expected == "itself" {
if actual != tt.value {
t.Fatalf("expected: %#v, got: %#v", tt.value, actual)
}
return
}
if actual != tt.expected {
t.Fatalf("expected: %#v, got: %#v", tt.expected, actual)
}
})
}
}

func makePointer[T any](value T) *T {
return &value
}
12 changes: 12 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -289,3 +289,15 @@ require (
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
sigs.k8s.io/yaml v1.2.0 // indirect
)

// Retract experimental versions
retract (
v1.999.0-rc.8
v1.999.0-rc.7
v1.999.0-rc.6
v1.999.0-rc.5
v1.999.0-rc.4
v1.999.0-rc.3
v1.999.0-rc.2
v1.999.0-rc.1
)

0 comments on commit c6c0385

Please sign in to comment.