Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 122 additions & 11 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ variables:
description: "Enable flaky tests"
value: "false"

JAVA_PROFILER_REF:
description: "When non-empty, clone DataDog/java-profiler at this Git ref (branch or tag), build ddprof, and use it as ddprof.jar for Gradle jobs instead of the Maven dependency."
value: "paul.fournillon/wallclock_precheck"

# One pipeline injection package size ratchet
OCI_PACKAGE_MAX_SIZE_BYTES: 40_000_000
LIB_INJECTION_IMAGE_MAX_SIZE_BYTES: 40_000_000
Expand Down Expand Up @@ -167,9 +171,21 @@ default:
echo "Failed to find base ref for PR" >&2
fi

# When build_java_profiler_ddprof ran, its artifact is available at custom-ddprof/ddprof.jar.
# Append root project property expected by dd-java-agent/ddprof-lib/build.gradle.
.inject_custom_ddprof_jar: &inject_custom_ddprof_jar
- |
if [ -f "${CI_PROJECT_DIR}/custom-ddprof/ddprof.jar" ]; then
echo "ddprof.jar=${CI_PROJECT_DIR}/custom-ddprof/ddprof.jar" >> gradle.properties
echo "Using custom ddprof.jar from java-profiler build"
fi

.gradle_build: &gradle_build
image: ${BUILDER_IMAGE_REPO}:${BUILDER_IMAGE_VERSION_PREFIX}base
stage: build
needs:
- job: build_java_profiler_ddprof
optional: true
variables:
MAVEN_OPTS: "-Xms256M -Xmx1024M"
GRADLE_WORKERS: 6
Expand Down Expand Up @@ -219,6 +235,7 @@ default:
org.gradle.java.installations.auto-download=false
org.gradle.java.installations.fromEnv=$JAVA_HOMES
EOF
- *inject_custom_ddprof_jar
- mkdir -p .gradle
- export GRADLE_USER_HOME=$(pwd)/.gradle
# replace maven central part by MAVEN_REPOSITORY_PROXY in .mvn/wrapper/maven-wrapper.properties
Expand Down Expand Up @@ -294,8 +311,73 @@ dd-octo-sts-pre-release-check:
max: 2
when: always

# Builds java-profiler from JAVA_PROFILER_REF and publishes custom-ddprof/ddprof.jar for downstream Gradle jobs.
# Uses :ddprof-lib:assembleReleaseJar (not assembleRelease, which is native-only). JDK 21+ for release + JDK 17+ for Gradle 9.
build_java_profiler_ddprof:
image: ${BUILDER_IMAGE_REPO}:${BUILDER_IMAGE_VERSION_PREFIX}base
stage: build
rules:
- if: '$JAVA_PROFILER_REF =~ /.+/'
when: on_success
variables:
FF_USE_FASTZIP: "true"
CACHE_COMPRESSION_LEVEL: "slowest"
KUBERNETES_CPU_REQUEST: 10
KUBERNETES_MEMORY_REQUEST: 20Gi
KUBERNETES_MEMORY_LIMIT: 20Gi
before_script:
- |
# java-profiler uses Gradle 9.x; Gradle requires JVM 17+. Builder image default java is often JDK 8.
if [ -n "${JAVA_21_HOME:-}" ] && [ -x "${JAVA_21_HOME}/bin/java" ]; then
export JAVA_HOME="$JAVA_21_HOME"
elif [ -n "${JAVA_17_HOME:-}" ] && [ -x "${JAVA_17_HOME}/bin/java" ]; then
export JAVA_HOME="$JAVA_17_HOME"
else
shopt -s nullglob
for d in /usr/lib/jvm/java-21-* /usr/lib/jvm/temurin-21-* /usr/lib/jvm/java-17-*; do
if [ -x "${d}/bin/java" ]; then
export JAVA_HOME="$d"
break
fi
done
shopt -u nullglob
fi
if [ -z "${JAVA_HOME:-}" ] || ! [ -x "${JAVA_HOME}/bin/java" ]; then
echo "Could not find JDK 17+ for Gradle 9 (set JAVA_21_HOME or JAVA_17_HOME, or install JDK 21 under /usr/lib/jvm)." >&2
ls -la /usr/lib/jvm 2>/dev/null || true
exit 1
fi
export PATH="${JAVA_HOME}/bin:${PATH}"
java -version
script:
- |
set -euo pipefail
mkdir -p "${CI_PROJECT_DIR}/custom-ddprof"
SRCDIR="${CI_PROJECT_DIR}/java-profiler-src"
rm -rf "$SRCDIR"
git clone --depth 1 --branch "$JAVA_PROFILER_REF" https://github.com/DataDog/java-profiler.git "$SRCDIR"
cd "$SRCDIR"
chmod +x ./gradlew
./gradlew --version
# assembleRelease is the native link/assemble task only; the packaged jar is assembleReleaseJar.
./gradlew :ddprof-lib:assembleReleaseJar -Pskip-tests -Pskip-gtest
JAR=$(find ddprof-lib/build/libs -maxdepth 1 -type f \( -name 'ddprof-*.jar' \) ! -name '*-sources*' ! -name '*-javadoc*' | head -1)
if [ -z "$JAR" ] || [ ! -f "$JAR" ]; then
echo "No ddprof jar found under ddprof-lib/build/libs" >&2
ls -la ddprof-lib/build/libs 2>/dev/null || ls -laR ddprof-lib/build 2>/dev/null || true
exit 1
fi
cp "$JAR" "${CI_PROJECT_DIR}/custom-ddprof/ddprof.jar"
ls -la "${CI_PROJECT_DIR}/custom-ddprof/"
artifacts:
when: on_success
paths:
- custom-ddprof/ddprof.jar

build:
needs:
- job: build_java_profiler_ddprof
optional: true
- job: maven-central-pre-release-check
optional: true
- job: dd-octo-sts-pre-release-check
Expand Down Expand Up @@ -406,7 +488,9 @@ publish-artifacts-to-s3:
spotless:
extends: .gradle_build
stage: tests
needs: []
needs:
- job: build_java_profiler_ddprof
optional: true
variables:
GRADLE_MEMORY_MAX: 6G
script:
Expand All @@ -416,15 +500,19 @@ spotless:
check-instrumentation-naming:
extends: .gradle_build
stage: tests
needs: [ ]
needs:
- job: build_java_profiler_ddprof
optional: true
script:
- ./gradlew --version
- ./gradlew checkInstrumentationNaming

config-inversion-linter:
extends: .gradle_build
stage: tests
needs: []
needs:
- job: build_java_profiler_ddprof
optional: true
script:
- ./gradlew --version
- ./gradlew checkConfigurations
Expand All @@ -433,7 +521,10 @@ test_published_artifacts:
extends: .gradle_build
image: ${BUILDER_IMAGE_REPO}:${BUILDER_IMAGE_VERSION_PREFIX}7 # Needs Java7 for some tests
stage: tests
needs: [ build ]
needs:
- job: build_java_profiler_ddprof
optional: true
- build
variables:
CACHE_TYPE: "lib"
script:
Expand All @@ -460,7 +551,10 @@ test_published_artifacts:

.check_job:
extends: .gradle_build
needs: [ build ]
needs:
- job: build_java_profiler_ddprof
optional: true
- build
stage: tests
variables:
CACHE_TYPE: "lib"
Expand Down Expand Up @@ -496,7 +590,9 @@ test_published_artifacts:

check_build_src:
extends: .check_job
needs: []
needs:
- job: build_java_profiler_ddprof
optional: true
variables:
GRADLE_TARGET: ":buildSrc:build"

Expand Down Expand Up @@ -531,7 +627,10 @@ check_debugger:

muzzle:
extends: .gradle_build
needs: [ build_tests ]
needs:
- job: build_java_profiler_ddprof
optional: true
- build_tests
stage: tests
parallel:
matrix:
Expand Down Expand Up @@ -563,7 +662,10 @@ muzzle:

muzzle-dep-report:
extends: .gradle_build
needs: [ build_tests ]
needs:
- job: build_java_profiler_ddprof
optional: true
- build_tests
stage: tests
variables:
CACHE_TYPE: "inst"
Expand Down Expand Up @@ -600,7 +702,10 @@ muzzle-dep-report:
extends: .gradle_build
image: ${BUILDER_IMAGE_REPO}:${BUILDER_IMAGE_VERSION_PREFIX}$testJvm
tags: [ "docker-in-docker:amd64" ] # use docker-in-docker runner for testcontainers
needs: [ build_tests ]
needs:
- job: build_java_profiler_ddprof
optional: true
- build_tests
stage: tests
variables:
GRADLE_PARAMS: "-PskipFlakyTests"
Expand Down Expand Up @@ -898,7 +1003,10 @@ deploy_to_di_backend:manual:
deploy_to_maven_central:
extends: .gradle_build
stage: publish
needs: [ build ]
needs:
- job: build_java_profiler_ddprof
optional: true
- build
variables:
CACHE_TYPE: "lib"
rules:
Expand Down Expand Up @@ -926,7 +1034,10 @@ deploy_to_maven_central:
deploy_snapshot_with_ddprof_snapshot:
extends: .gradle_build
stage: publish
needs: [ build ]
needs:
- job: build_java_profiler_ddprof
optional: true
- build
variables:
CACHE_TYPE: "lib"
rules:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,17 @@ public void recordTraceRoot(long rootSpanId, String endpoint, String operation)
}
}

/** Monotonic tick count for TaskBlock and wall-clock off-CPU interval timing. */
public long getCurrentTicks() {
return profiler.getCurrentTicks();
}

int encode(CharSequence constant) {
// java-profiler ContextSetter no longer exposes value encoding.
// Keep API contract by returning "not encoded" (0), which callers already handle.
return 0;
}

public int operationNameOffset() {
return offsetOf(OPERATION);
}
Expand Down Expand Up @@ -454,4 +465,24 @@ void recordQueueTimeEvent(
}
}
}

void recordTaskBlockEvent(
long startTicks, long spanId, long rootSpanId, long blocker, long unblockingSpanId) {
if (profiler != null) {
long endTicks = profiler.getCurrentTicks();
profiler.recordTaskBlock(startTicks, endTicks, spanId, rootSpanId, blocker, unblockingSpanId);
}
}

void parkEnter(long spanId, long rootSpanId) {
if (profiler != null) {
profiler.parkEnter(spanId, rootSpanId);
}
}

void parkExit(long blocker, long unblockingSpanId) {
if (profiler != null) {
profiler.parkExit(blocker, unblockingSpanId);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,53 @@ public void onDetach() {
}
}

@Override
public int encode(CharSequence constant) {
return DDPROF.encode(constant);
}

@Override
public int encodeOperationName(CharSequence constant) {
if (SPAN_NAME_INDEX >= 0) {
return DDPROF.encode(constant);
}
return 0;
}

@Override
public int encodeResourceName(CharSequence constant) {
if (RESOURCE_NAME_INDEX >= 0) {
return DDPROF.encode(constant);
}
return 0;
}

@Override
public String name() {
return "ddprof";
}

@Override
public long getCurrentTicks() {
return DDPROF.getCurrentTicks();
}

@Override
public void recordTaskBlock(
long startTicks, long spanId, long rootSpanId, long blocker, long unblockingSpanId) {
DDPROF.recordTaskBlockEvent(startTicks, spanId, rootSpanId, blocker, unblockingSpanId);
}

@Override
public void parkEnter(long spanId, long rootSpanId) {
DDPROF.parkEnter(spanId, rootSpanId);
}

@Override
public void parkExit(long blocker, long unblockingSpanId) {
DDPROF.parkExit(blocker, unblockingSpanId);
}

public void clearContext() {
DDPROF.clearSpanContext();
DDPROF.clearContextValue(SPAN_NAME_INDEX);
Expand Down
Loading
Loading