Skip to content

Commit 0ec9f09

Browse files
authored
Merge branch 'main' into dario.castane/langplat-286/origin-detection
2 parents 10ca778 + 998add0 commit 0ec9f09

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1310
-316
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/bin/bash
2+
3+
for file in "$@"; do
4+
temp_file="tempfile.xml"
5+
6+
# force write a new line at the end of the gotestsum-report.xml, or else
7+
# the loop will skip the last line.
8+
# fixes issue with a missing </testsuites>
9+
echo -e "\n" >> $file
10+
11+
while read p; do
12+
# we might try to report gotestsum-report.xml multiple times, so don't
13+
# calculate codeowners more times than we need
14+
if [[ "$p" =~ \<testcase && ! "$p" =~ "file=" ]]; then
15+
class=$(echo "$p" | grep -o '.v1/[^"]*"')
16+
file_name=$(echo "${class:3}" | sed 's/.$//') # trim off the edges to get the path
17+
new_line=$(echo "$p" | sed "s|<testcase \([^>]*\)>|<testcase \1 file=\"$file_name\">|")
18+
echo "$new_line" >> "$temp_file"
19+
else
20+
echo "$p" >> "$temp_file"
21+
fi
22+
done < $file
23+
24+
mv "$temp_file" $file
25+
done

.github/actions/dd-ci-upload/action.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ runs:
4242
curl -L --fail "https://github.com/DataDog/datadog-ci/releases/latest/download/datadog-ci_${{ env.DD_CI_CLI_BUILD }}" --output datadog-ci
4343
chmod +x datadog-ci
4444
45+
- name: Add CodeOwners to JUnit files
46+
shell: bash
47+
run: cd ./.github/actions/add-codeowners && ./codeowners.sh ${{ inputs.files }}
48+
4549
- name: Upload the JUnit files
4650
shell: bash
4751
run: |

.github/workflows/unit-integration-tests.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,12 @@ jobs:
144144
image: redis:3.2
145145
ports:
146146
- 6379:6379
147+
valkey:
148+
image: valkey/valkey:8
149+
env:
150+
VALKEY_EXTRA_FLAGS: "--port 6380 --requirepass password-for-default"
151+
ports:
152+
- 6380:6380
147153
elasticsearch2:
148154
image: elasticsearch:2
149155
env:

contrib/database/sql/metrics.go

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,27 @@ var interval = 10 * time.Second
3333

3434
// pollDBStats calls (*DB).Stats on the db at a predetermined interval. It pushes the DBStats off to the statsd client.
3535
// the caller should always ensure that db & statsd are non-nil
36-
func pollDBStats(statsd internal.StatsdClient, db *sql.DB) {
36+
func pollDBStats(statsd internal.StatsdClient, db *sql.DB, stop chan struct{}) {
3737
log.Debug("DB stats will be gathered and sent every %v.", interval)
38-
for range time.NewTicker(interval).C {
39-
log.Debug("Reporting DB.Stats metrics...")
40-
stat := db.Stats()
41-
statsd.Gauge(MaxOpenConnections, float64(stat.MaxOpenConnections), []string{}, 1)
42-
statsd.Gauge(OpenConnections, float64(stat.OpenConnections), []string{}, 1)
43-
statsd.Gauge(InUse, float64(stat.InUse), []string{}, 1)
44-
statsd.Gauge(Idle, float64(stat.Idle), []string{}, 1)
45-
statsd.Gauge(WaitCount, float64(stat.WaitCount), []string{}, 1)
46-
statsd.Timing(WaitDuration, stat.WaitDuration, []string{}, 1)
47-
statsd.Gauge(MaxIdleClosed, float64(stat.MaxIdleClosed), []string{}, 1)
48-
statsd.Gauge(MaxIdleTimeClosed, float64(stat.MaxIdleTimeClosed), []string{}, 1)
49-
statsd.Gauge(MaxLifetimeClosed, float64(stat.MaxLifetimeClosed), []string{}, 1)
38+
ticker := time.NewTicker(interval)
39+
defer ticker.Stop()
40+
for {
41+
select {
42+
case <-ticker.C:
43+
log.Debug("Reporting DB.Stats metrics...")
44+
stat := db.Stats()
45+
statsd.Gauge(MaxOpenConnections, float64(stat.MaxOpenConnections), []string{}, 1)
46+
statsd.Gauge(OpenConnections, float64(stat.OpenConnections), []string{}, 1)
47+
statsd.Gauge(InUse, float64(stat.InUse), []string{}, 1)
48+
statsd.Gauge(Idle, float64(stat.Idle), []string{}, 1)
49+
statsd.Gauge(WaitCount, float64(stat.WaitCount), []string{}, 1)
50+
statsd.Timing(WaitDuration, stat.WaitDuration, []string{}, 1)
51+
statsd.Gauge(MaxIdleClosed, float64(stat.MaxIdleClosed), []string{}, 1)
52+
statsd.Gauge(MaxIdleTimeClosed, float64(stat.MaxIdleTimeClosed), []string{}, 1)
53+
statsd.Gauge(MaxLifetimeClosed, float64(stat.MaxLifetimeClosed), []string{}, 1)
54+
case <-stop:
55+
return
56+
}
5057
}
5158
}
5259

contrib/database/sql/metrics_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@
66
package sql
77

88
import (
9+
"sync"
910
"testing"
1011

12+
"github.com/DataDog/datadog-go/v5/statsd"
13+
"github.com/lib/pq"
1114
"github.com/stretchr/testify/assert"
15+
"github.com/stretchr/testify/require"
1216
"gopkg.in/DataDog/dd-trace-go.v1/internal/globalconfig"
1317
)
1418

@@ -64,3 +68,22 @@ func TestStatsTags(t *testing.T) {
6468
})
6569
resetGlobalConfig()
6670
}
71+
72+
func TestPollDBStatsStop(t *testing.T) {
73+
driverName := "postgres"
74+
Register(driverName, &pq.Driver{}, WithServiceName("postgres-test"), WithAnalyticsRate(0.2))
75+
defer unregister(driverName)
76+
db, err := Open(driverName, "postgres://postgres:[email protected]:5432/postgres?sslmode=disable")
77+
require.NoError(t, err)
78+
defer db.Close()
79+
80+
var wg sync.WaitGroup
81+
stop := make(chan struct{})
82+
wg.Add(1)
83+
go func() {
84+
defer wg.Done()
85+
pollDBStats(&statsd.NoOpClientDirect{}, db, stop)
86+
}()
87+
close(stop)
88+
wg.Wait()
89+
}

contrib/database/sql/sql.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ type tracedConnector struct {
139139
connector driver.Connector
140140
driverName string
141141
cfg *config
142+
dbClose chan struct{}
142143
}
143144

144145
func (t *tracedConnector) Connect(ctx context.Context) (driver.Conn, error) {
@@ -171,6 +172,13 @@ func (t *tracedConnector) Driver() driver.Driver {
171172
return t.connector.Driver()
172173
}
173174

175+
// Close closes the dbClose channel
176+
// This method will be invoked when DB.Close() is called, which we expect to occur only once: https://cs.opensource.google/go/go/+/refs/tags/go1.23.4:src/database/sql/sql.go;l=918-950
177+
func (t *tracedConnector) Close() error {
178+
close(t.dbClose)
179+
return nil
180+
}
181+
174182
// from Go stdlib implementation of sql.Open
175183
type dsnConnector struct {
176184
dsn string
@@ -208,10 +216,11 @@ func OpenDB(c driver.Connector, opts ...Option) *sql.DB {
208216
connector: c,
209217
driverName: driverName,
210218
cfg: cfg,
219+
dbClose: make(chan struct{}),
211220
}
212221
db := sql.OpenDB(tc)
213222
if cfg.dbStats && cfg.statsdClient != nil {
214-
go pollDBStats(cfg.statsdClient, db)
223+
go pollDBStats(cfg.statsdClient, db, tc.dbClose)
215224
}
216225
return db
217226
}

contrib/database/sql/sql_test.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,12 +281,13 @@ func TestOpenOptions(t *testing.T) {
281281
var tg statsdtest.TestStatsdClient
282282
Register(driverName, &pq.Driver{})
283283
defer unregister(driverName)
284-
_, err := Open(driverName, dsn, withStatsdClient(&tg), WithDBStats())
284+
db, err := Open(driverName, dsn, withStatsdClient(&tg), WithDBStats())
285285
require.NoError(t, err)
286286

287287
// The polling interval has been reduced to 500ms for the sake of this test, so at least one round of `pollDBStats` should be complete in 1s
288288
deadline := time.Now().Add(1 * time.Second)
289289
wantStats := []string{MaxOpenConnections, OpenConnections, InUse, Idle, WaitCount, WaitDuration, MaxIdleClosed, MaxIdleTimeClosed, MaxLifetimeClosed}
290+
var calls1 []string
290291
for {
291292
if time.Now().After(deadline) {
292293
t.Fatalf("Stats not collected in expected interval of %v", interval)
@@ -300,11 +301,16 @@ func TestOpenOptions(t *testing.T) {
300301
}
301302
}
302303
// all expected stats have been collected; exit out of loop, test should pass
304+
calls1 = calls
303305
break
304306
}
305307
// not all stats have been collected yet, try again in 50ms
306308
time.Sleep(50 * time.Millisecond)
307309
}
310+
// Close DB and assert the no further stats have been collected; db.Close should stop the pollDBStats goroutine.
311+
db.Close()
312+
time.Sleep(50 * time.Millisecond)
313+
assert.Equal(t, calls1, tg.CallNames())
308314
})
309315
}
310316

contrib/go-redis/redis.v7/redis.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func additionalTagOptions(client redis.UniversalClient) []ddtrace.StartSpanOptio
7979
opt := clientOptions.Options()
8080
if opt.Addr == "FailoverClient" {
8181
additionalTags = []ddtrace.StartSpanOption{
82-
tracer.Tag("out.db", strconv.Itoa(opt.DB)),
82+
tracer.Tag(ext.TargetDB, strconv.Itoa(opt.DB)),
8383
tracer.Tag(ext.RedisDatabaseIndex, opt.DB),
8484
}
8585
} else {
@@ -91,7 +91,7 @@ func additionalTagOptions(client redis.UniversalClient) []ddtrace.StartSpanOptio
9191
additionalTags = []ddtrace.StartSpanOption{
9292
tracer.Tag(ext.TargetHost, host),
9393
tracer.Tag(ext.TargetPort, port),
94-
tracer.Tag("out.db", strconv.Itoa(opt.DB)),
94+
tracer.Tag(ext.TargetDB, strconv.Itoa(opt.DB)),
9595
tracer.Tag(ext.RedisDatabaseIndex, opt.DB),
9696
}
9797
}

contrib/go-redis/redis.v8/redis.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ func additionalTagOptions(client redis.UniversalClient) []ddtrace.StartSpanOptio
7878
opt := clientOptions.Options()
7979
if opt.Addr == "FailoverClient" {
8080
additionalTags = []ddtrace.StartSpanOption{
81-
tracer.Tag("out.db", strconv.Itoa(opt.DB)),
81+
tracer.Tag(ext.TargetDB, strconv.Itoa(opt.DB)),
8282
tracer.Tag(ext.RedisDatabaseIndex, opt.DB),
8383
}
8484
} else {
@@ -90,7 +90,7 @@ func additionalTagOptions(client redis.UniversalClient) []ddtrace.StartSpanOptio
9090
additionalTags = []ddtrace.StartSpanOption{
9191
tracer.Tag(ext.TargetHost, host),
9292
tracer.Tag(ext.TargetPort, port),
93-
tracer.Tag("out.db", strconv.Itoa(opt.DB)),
93+
tracer.Tag(ext.TargetDB, strconv.Itoa(opt.DB)),
9494
tracer.Tag(ext.RedisDatabaseIndex, opt.DB),
9595
}
9696
}

contrib/go-redis/redis/redis.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ func (c *Pipeliner) execWithContext(ctx context.Context) ([]redis.Cmder, error)
130130
tracer.ResourceName("redis"),
131131
tracer.Tag(ext.TargetHost, p.host),
132132
tracer.Tag(ext.TargetPort, p.port),
133-
tracer.Tag("out.db", strconv.Itoa(p.db)),
133+
tracer.Tag(ext.TargetDB, strconv.Itoa(p.db)),
134134
tracer.Tag(ext.Component, componentName),
135135
tracer.Tag(ext.SpanKind, ext.SpanKindClient),
136136
tracer.Tag(ext.DBSystem, ext.DBSystemRedis),
@@ -202,7 +202,7 @@ func createWrapperFromClient(tc *Client) func(oldProcess func(cmd redis.Cmder) e
202202
tracer.ResourceName(parts[0]),
203203
tracer.Tag(ext.TargetHost, p.host),
204204
tracer.Tag(ext.TargetPort, p.port),
205-
tracer.Tag("out.db", strconv.Itoa(p.db)),
205+
tracer.Tag(ext.TargetDB, strconv.Itoa(p.db)),
206206
tracer.Tag("redis.raw_command", raw),
207207
tracer.Tag("redis.args_length", strconv.Itoa(length)),
208208
tracer.Tag(ext.Component, componentName),

contrib/gorm.io/gorm.v1/orchestrion.yml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,18 @@ aspects:
1313
join-point:
1414
function-call: gorm.io/gorm.Open
1515
advice:
16-
- replace-function: gopkg.in/DataDog/dd-trace-go.v1/contrib/gorm.io/gorm.v1.Open
16+
- wrap-expression:
17+
imports:
18+
gorm: gorm.io/gorm
19+
gormtrace: gopkg.in/DataDog/dd-trace-go.v1/contrib/gorm.io/gorm.v1
20+
template: |-
21+
func() (*gorm.DB, error) {
22+
db, err := {{ . }}
23+
if err != nil {
24+
return nil, err
25+
}
26+
if err := db.Use(gormtrace.NewTracePlugin()); err != nil {
27+
return nil, err
28+
}
29+
return db, nil
30+
}()

contrib/internal/httptrace/httptrace.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ import (
1111
"context"
1212
"fmt"
1313
"gopkg.in/DataDog/dd-trace-go.v1/internal/log"
14+
"gopkg.in/DataDog/dd-trace-go.v1/internal/telemetry"
1415
"net/http"
1516
"strconv"
1617
"strings"
18+
"sync"
1719

1820
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace"
1921
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext"
@@ -27,6 +29,8 @@ var (
2729
cfg = newConfig()
2830
)
2931

32+
var reportTelemetryConfigOnce sync.Once
33+
3034
type inferredSpanCreatedCtxKey struct{}
3135

3236
type FinishSpanFunc = func(status int, errorFn func(int) bool, opts ...tracer.FinishOption)
@@ -37,6 +41,15 @@ func StartRequestSpan(r *http.Request, opts ...ddtrace.StartSpanOption) (tracer.
3741
// Append our span options before the given ones so that the caller can "overwrite" them.
3842
// TODO(): rework span start option handling (https://github.com/DataDog/dd-trace-go/issues/1352)
3943

44+
// we cannot track the configuration in newConfig because it's called during init() and the the telemetry client
45+
// is not initialized yet
46+
reportTelemetryConfigOnce.Do(func() {
47+
telemetry.GlobalClient.ConfigChange([]telemetry.Configuration{
48+
{Name: "inferred_proxy_services_enabled", Value: cfg.inferredProxyServicesEnabled},
49+
})
50+
log.Debug("internal/httptrace: telemetry.ConfigChange called with cfg: %v:", cfg)
51+
})
52+
4053
var ipTags map[string]string
4154
if cfg.traceClientIP {
4255
ipTags, _ = httpsec.ClientIPTags(r.Header, true, r.RemoteAddr)

contrib/jackc/pgx.v5/metrics.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ var interval = 10 * time.Second
3535

3636
// pollPoolStats calls (*pgxpool).Stats on the pool at a predetermined interval. It pushes the pool Stats off to the statsd client.
3737
func pollPoolStats(statsd internal.StatsdClient, pool *pgxpool.Pool) {
38+
// TODO: Create stop condition for pgx on db.Close
3839
log.Debug("contrib/jackc/pgx.v5: Traced pool connection found: Pool stats will be gathered and sent every %v.", interval)
3940
for range time.NewTicker(interval).C {
4041
log.Debug("contrib/jackc/pgx.v5: Reporting pgxpool.Stat metrics...")

contrib/net/http/orchestrion.client.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ aspects:
5555
ddtrace: gopkg.in/DataDog/dd-trace-go.v1/ddtrace
5656
os: os
5757
links:
58+
- gopkg.in/DataDog/dd-trace-go.v1/internal
5859
- gopkg.in/DataDog/dd-trace-go.v1/internal/appsec
5960
- gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/httpsec
6061
- gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer
@@ -87,6 +88,12 @@ aspects:
8788
//go:linkname __dd_httptrace_GetErrorCodesFromInput gopkg.in/DataDog/dd-trace-go.v1/contrib/internal/httptrace.GetErrorCodesFromInput
8889
func __dd_httptrace_GetErrorCodesFromInput(string) func(int) bool
8990
91+
//go:linkname __dd_httptrace_UrlFromRequest gopkg.in/DataDog/dd-trace-go.v1/contrib/internal/httptrace.UrlFromRequest
92+
func __dd_httptrace_UrlFromRequest(*Request, bool) string
93+
94+
//go:linkname __dd_internal_BoolEnv gopkg.in/DataDog/dd-trace-go.v1/internal.BoolEnv
95+
func __dd_internal_BoolEnv(string, bool) bool
96+
9097
type __dd_tracer_HTTPHeadersCarrier Header
9198
func (c __dd_tracer_HTTPHeadersCarrier) Set(key, val string) {
9299
Header(c).Set(key, val)
@@ -97,6 +104,8 @@ aspects:
97104
return statusCode >= 400 && statusCode < 500
98105
}
99106
107+
var __dd_queryStringEnabled = __dd_internal_BoolEnv("DD_TRACE_HTTP_CLIENT_TAG_QUERY_STRING", true)
108+
100109
func init() {
101110
v := os.Getenv("DD_TRACE_HTTP_CLIENT_ERROR_STATUSES")
102111
if fn := __dd_httptrace_GetErrorCodesFromInput(v); fn != nil {
@@ -130,7 +139,7 @@ aspects:
130139
__dd_tracer_SpanType(ext.SpanTypeHTTP),
131140
__dd_tracer_ResourceName(resourceName),
132141
__dd_tracer_Tag(ext.HTTPMethod, {{ $req }}.Method),
133-
__dd_tracer_Tag(ext.HTTPURL, url.String()),
142+
__dd_tracer_Tag(ext.HTTPURL, __dd_httptrace_UrlFromRequest({{ $req }}, __dd_queryStringEnabled)),
134143
__dd_tracer_Tag(ext.Component, "net/http"),
135144
__dd_tracer_Tag(ext.SpanKind, ext.SpanKindClient),
136145
__dd_tracer_Tag(ext.NetworkDestinationName, url.Hostname()),

contrib/redis/go-redis.v9/redis.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ func additionalTagOptions(client redis.UniversalClient) []ddtrace.StartSpanOptio
7878
opt := clientOptions.Options()
7979
if opt.Addr == "FailoverClient" {
8080
additionalTags = []ddtrace.StartSpanOption{
81-
tracer.Tag("out.db", strconv.Itoa(opt.DB)),
81+
tracer.Tag(ext.TargetDB, strconv.Itoa(opt.DB)),
8282
}
8383
} else {
8484
host, port, err := net.SplitHostPort(opt.Addr)
@@ -89,7 +89,7 @@ func additionalTagOptions(client redis.UniversalClient) []ddtrace.StartSpanOptio
8989
additionalTags = []ddtrace.StartSpanOption{
9090
tracer.Tag(ext.TargetHost, host),
9191
tracer.Tag(ext.TargetPort, port),
92-
tracer.Tag("out.db", strconv.Itoa(opt.DB)),
92+
tracer.Tag(ext.TargetDB, strconv.Itoa(opt.DB)),
9393
}
9494
}
9595
} else if clientOptions, ok := client.(clusterOptions); ok {

0 commit comments

Comments
 (0)