Skip to content

Commit e0bec00

Browse files
authored
Merge branch 'master' into adrien.boitreaud/capture-emr-step-id
2 parents 34af8f9 + 7f5d704 commit e0bec00

140 files changed

Lines changed: 1532 additions & 6988 deletions

File tree

Some content is hidden

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

.github/workflows/analyze-changes.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
${{ runner.os }}-gradle-
3131
3232
- name: Initialize CodeQL
33-
uses: github/codeql-action/init@9e907b5e64f6b83e7804b09294d44122997950d6 # v4.32.3
33+
uses: github/codeql-action/init@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
3434
with:
3535
languages: 'java'
3636
build-mode: 'manual'
@@ -49,7 +49,7 @@ jobs:
4949
--build-cache --parallel --stacktrace --no-daemon --max-workers=4
5050
5151
- name: Perform CodeQL Analysis and upload results to GitHub Security tab
52-
uses: github/codeql-action/analyze@9e907b5e64f6b83e7804b09294d44122997950d6 # v4.32.3
52+
uses: github/codeql-action/analyze@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
5353

5454
trivy:
5555
name: Analyze changes with Trivy
@@ -101,7 +101,7 @@ jobs:
101101
ls -laR "./workspace/.trivy"
102102
103103
- name: Run Trivy security scanner
104-
uses: aquasecurity/trivy-action@c1824fd6edce30d7ab345a9989de00bbd46ef284 # v0.34.0
104+
uses: aquasecurity/trivy-action@e368e328979b113139d6f9068e03accaed98a518 # v0.34.1
105105
with:
106106
scan-type: rootfs
107107
scan-ref: './workspace/.trivy/'
@@ -114,7 +114,7 @@ jobs:
114114
TRIVY_JAVA_DB_REPOSITORY: ghcr.io/aquasecurity/trivy-java-db,public.ecr.aws/aquasecurity/trivy-java-db
115115

116116
- name: Upload Trivy scan results to GitHub Security tab
117-
uses: github/codeql-action/upload-sarif@9e907b5e64f6b83e7804b09294d44122997950d6 # v4.32.3
117+
uses: github/codeql-action/upload-sarif@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
118118
if: always()
119119
with:
120120
sarif_file: 'trivy-results.sarif'

.github/workflows/create-release-branch.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Create Release Branch
1+
name: Create Release Branch and Pin System Tests
22

33
on:
44
push:
@@ -37,9 +37,9 @@ jobs:
3737
id: define-release-branch
3838
run: |
3939
TAG=${{ steps.determine-tag.outputs.tag }}
40-
echo "branch=test/${TAG%.0}.x" >> "$GITHUB_OUTPUT" # TODO: change back to release/ branch after testing
40+
echo "branch=release/${TAG%.0}.x" >> "$GITHUB_OUTPUT"
4141
42-
- name: Checkout dd-trace-java at tag
42+
- name: Check out repo at tag
4343
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # 6.0.2
4444
with:
4545
ref: ${{ steps.determine-tag.outputs.tag }}
@@ -75,7 +75,7 @@ jobs:
7575
scope: DataDog/dd-trace-java
7676
policy: self.pin-system-tests.create-pr
7777

78-
- name: Checkout dd-trace-java at release branch
78+
- name: Check out repo at release branch
7979
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # 6.0.2
8080
with:
8181
ref: ${{ needs.create-release-branch.outputs.release-branch-name }}
@@ -85,7 +85,7 @@ jobs:
8585
run: |
8686
echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
8787
88-
- name: Define pin-system-tests branch name
88+
- name: Define pin-system-tests branch name from date
8989
id: define-pin-branch
9090
run: echo "branch=ci/pin-system-tests-$(date +'%Y%m%d')" >> $GITHUB_OUTPUT
9191

.github/workflows/pin-system-tests.yaml

Lines changed: 0 additions & 113 deletions
This file was deleted.

.gitlab-ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ variables:
2929
GRADLE_VERSION: "8.14.4" # must match gradle-wrapper.properties
3030
MAVEN_REPOSITORY_PROXY: "https://depot-read-api-java.us1.ddbuild.io/magicmirror/magicmirror/@current/"
3131
GRADLE_PLUGIN_PROXY: "https://depot-read-api-java.us1.ddbuild.io/magicmirror/magicmirror/@current/"
32-
BUILDER_IMAGE_VERSION_PREFIX: "v26.01-" # use either an empty string (e.g. "") for latest images or a version followed by a hyphen (e.g. "v25.05-")
32+
BUILDER_IMAGE_VERSION_PREFIX: "v26.02-" # use either an empty string (e.g. "") for latest images or a version followed by a hyphen (e.g. "v25.05-")
3333
REPO_NOTIFICATION_CHANNEL: "#apm-java-escalations"
3434
DEFAULT_TEST_JVMS: /^(8|11|17|21|25|stable)$/ # the latest "stable" version is 26
3535
PROFILE_TESTS:

.gitlab/find-gh-base-ref.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ if [[ $CI_COMMIT_BRANCH =~ ^(master|release/.*)$ ]]; then
1414
exit 1
1515
fi
1616

17+
# See .test_job declaration
18+
if [[ $CI_COMMIT_BRANCH =~ ^(mq-working-branch-|gh-readonly-queue/) ]]; then
19+
echo "CI_COMMIT_BRANCH is a merge queue branch, skipping base ref detection" >&2
20+
exit 1
21+
fi
22+
1723
CURRENT_HEAD_SHA="$(git rev-parse HEAD)"
1824
if [[ -z "${CURRENT_HEAD_SHA:-}" ]]; then
1925
echo "Failed to determine current HEAD SHA" >&2

buildSrc/src/main/kotlin/datadog/gradle/plugin/dump/DumpHangedTestPlugin.kt

Lines changed: 33 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import java.util.concurrent.ScheduledExecutorService
2020
import java.util.concurrent.ScheduledFuture
2121
import java.util.concurrent.TimeUnit
2222
import javax.inject.Inject
23+
import kotlin.jvm.optionals.getOrElse
2324

2425
/**
2526
* Plugin to collect thread and heap dumps for hanged tests.
@@ -120,43 +121,27 @@ class DumpHangedTestPlugin : Plugin<Project> {
120121

121122
dumpsDir.mkdirs()
122123

123-
fun file(name: String, ext: String = "log") =
124-
File(dumpsDir, "$name-${System.currentTimeMillis()}.$ext")
124+
ProcessHandle.current().children()
125+
.filter { it.info().commandLine().getOrElse { "" }.contains("Gradle Test Executor") }
126+
.forEach { process ->
127+
collectDump(dumpsDir, process)
125128

126-
// Collect all JVMs pids.
127-
val allJavaProcessesFile = file("all-java-processes")
128-
runCmd(Redirect.to(allJavaProcessesFile), "jcmd", "-l")
129-
130-
// On IBM JDK thread dump can be collected by signaling the matching `Gradle Test Executor` process with `kill -3`.
131-
// It will be writen into `/tmp/javacore.YYYYMMDD.HHMMSS.PID.SEQ.txt
132-
if (isIbm8(allJavaProcessesFile)) {
133-
val allProcessesFile = file("all-processes")
134-
runCmd(Redirect.to(allProcessesFile), "ps", "-ef")
135-
extractPidsIbm8(allProcessesFile).forEach { ibm8Pid ->
136-
runCmd(Redirect.INHERIT, "kill", "-3", ibm8Pid)
137-
}
138-
} else {
139-
val pids = extractPids(allJavaProcessesFile)
140-
141-
pids.forEach { pid ->
142-
// Collect heap dump by pid.
143-
val heapDumpPath = file("${pid}-heap-dump", "hprof").absolutePath
144-
runCmd(Redirect.INHERIT, "jcmd", pid, "GC.heap_dump", heapDumpPath)
145-
146-
// Collect thread dump by pid.
147-
val threadDumpFile = file("${pid}-thread-dump")
148-
runCmd(Redirect.to(threadDumpFile), "jcmd", pid, "Thread.print", "-l")
129+
process.children().forEach { child ->
130+
collectDump(dumpsDir, child)
131+
}
149132
}
150133

151-
// Just in case collect all thread dumps by using special PID `0`.
152-
val allThreadsFile = file("all-thread-dumps")
153-
runCmd(Redirect.to(allThreadsFile), "jcmd", "0", "Thread.print", "-l")
154-
}
134+
// Just in case collect all thread dumps by using special PID `0`.
135+
val allThreadsFile = file(dumpsDir, "all-thread-dumps")
136+
runCmd(Redirect.to(allThreadsFile), "jcmd", "0", "Thread.print", "-l")
155137
} catch (e: Throwable) {
156138
t.logger.warn("Taking dumps failed with error: ${e.message ?: e.javaClass.name}, for ${t.path}")
157139
}
158140
}
159141

142+
private fun file(baseDir: File, name: String, ext: String = "log") =
143+
File(baseDir, "$name-${System.currentTimeMillis()}.$ext")
144+
160145
private fun cleanup(t: Task) {
161146
val future = t.extra
162147
.takeIf { it.has(DUMP_FUTURE_KEY) }
@@ -183,23 +168,24 @@ class DumpHangedTestPlugin : Plugin<Project> {
183168
}
184169
}
185170

186-
private fun isIbm8(file: File): Boolean =
187-
file.readLines().any { it.contains("-PtestJvm=ibm8") }
188-
189-
private fun extractPids(file: File): List<String> =
190-
file.readLines()
191-
.filter { it.contains("Gradle Test Executor") }
192-
.map { it.substringBefore(' ') }
193-
194-
private fun extractPidsIbm8(file: File): List<String> =
195-
file.readLines()
196-
.filter { it.contains("Gradle Test Executor") }
197-
.filter { it.contains("ibm", ignoreCase = true) }
198-
.mapNotNull(::extractPid)
199-
200-
private val whitespaceRegex = Regex("\\s+")
171+
private fun collectDump(
172+
baseDir: File,
173+
process: ProcessHandle
174+
) {
175+
val pid = process.pid().toString()
201176

202-
// ps -ef format produce output like: UID PID PPID ...
203-
private fun extractPid(line: String): String? =
204-
line.trimStart().split(whitespaceRegex, limit = 3).getOrNull(1)
177+
if (process.info().command().getOrElse { "" }.contains("/ibm8")) {
178+
// On IBM JDK thread dump can be collected by signaling process with `kill -3`.
179+
// It will be writen into `/tmp/javacore.YYYYMMDD.HHMMSS.PID.SEQ.txt
180+
runCmd(Redirect.INHERIT, "kill", "-3", pid)
181+
} else {
182+
// Collect heap dump by pid.
183+
val heapDumpPath = file(baseDir, "$pid-heap-dump", "hprof").absolutePath
184+
runCmd(Redirect.INHERIT, "jcmd", pid, "GC.heap_dump", heapDumpPath)
185+
186+
// Collect thread dump by pid.
187+
val threadDumpFile = file(baseDir, "$pid-thread-dump", "log")
188+
runCmd(Redirect.to(threadDumpFile), "jcmd", pid, "Thread.print", "-l")
189+
}
190+
}
205191
}

dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/BaseDecorator.java

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import datadog.trace.api.Config;
88
import datadog.trace.api.DDTags;
99
import datadog.trace.api.Functions;
10+
import datadog.trace.api.TagMap;
1011
import datadog.trace.api.cache.QualifiedClassNameCache;
1112
import datadog.trace.bootstrap.instrumentation.api.AgentScope;
1213
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
@@ -40,17 +41,29 @@ public String apply(Class<?> clazz) {
4041
Functions.PrefixJoin.of("."));
4142

4243
protected final boolean traceAnalyticsEnabled;
43-
protected final Double traceAnalyticsSampleRate;
44+
protected final double traceAnalyticsSampleRate;
45+
46+
private final TagMap.Entry traceAnalyticsEntry;
47+
48+
// Deliberately not volatile, reading null and repeating the calculation is safe
49+
private TagMap.Entry cachedComponentEntry = null;
4450

4551
protected BaseDecorator() {
4652
final Config config = Config.get();
4753
final String[] instrumentationNames = instrumentationNames();
54+
4855
this.traceAnalyticsEnabled =
4956
instrumentationNames.length > 0
5057
&& config.isTraceAnalyticsIntegrationEnabled(
5158
traceAnalyticsDefault(), instrumentationNames);
59+
5260
this.traceAnalyticsSampleRate =
5361
(double) config.getInstrumentationAnalyticsSampleRate(instrumentationNames);
62+
63+
this.traceAnalyticsEntry =
64+
this.traceAnalyticsEnabled
65+
? TagMap.Entry.create(DDTags.ANALYTICS_SAMPLE_RATE, traceAnalyticsSampleRate)
66+
: null;
5467
}
5568

5669
protected abstract String[] instrumentationNames();
@@ -59,6 +72,20 @@ protected BaseDecorator() {
5972

6073
protected abstract CharSequence component();
6174

75+
/** Caches the component TagMap.Entry, so it isn't recreated for every trace */
76+
protected final TagMap.Entry componentEntry() {
77+
// DQH = Tried calling component() in the constructor, but that had issues with static
78+
// field ordering. That was caught be an integration test, but I didn't want to risk
79+
// breaking other integrations where the test is not as thorough.
80+
81+
// This approach while more complicated doesn't have any field initialization ordering issues.
82+
TagMap.Entry componentEntry = cachedComponentEntry;
83+
if (componentEntry == null) {
84+
cachedComponentEntry = componentEntry = TagMap.Entry.create(Tags.COMPONENT, component());
85+
}
86+
return componentEntry;
87+
}
88+
6289
protected boolean traceAnalyticsDefault() {
6390
return false;
6491
}
@@ -67,12 +94,17 @@ public AgentSpan afterStart(final AgentSpan span) {
6794
if (spanType() != null) {
6895
span.setSpanType(spanType());
6996
}
97+
98+
span.setTag(componentEntry());
99+
100+
// DQH - Could retrieve the value from componentEntry and cast to avoid the virtual call,
101+
// unclear which option is better here
70102
final CharSequence component = component();
71-
span.setTag(Tags.COMPONENT, component);
72103
span.context().setIntegrationName(component);
73-
if (traceAnalyticsEnabled) {
74-
span.setMetric(DDTags.ANALYTICS_SAMPLE_RATE, traceAnalyticsSampleRate);
75-
}
104+
105+
// null handled by setMetric
106+
span.setMetric(traceAnalyticsEntry);
107+
76108
return span;
77109
}
78110

0 commit comments

Comments
 (0)