-
Notifications
You must be signed in to change notification settings - Fork 324
Rewrite build-time instrumentation as compilation post-processor (using Gradle lazy APIs) #9475
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
Hi! 👋 Thanks for your pull request! 🎉 To help us review it, please make sure to:
If you need help, please check our contributing guidelines. |
AlexeyKuznetsov-DD
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just curious, what would be the benefit? Faster build?
248b4eb to
3094d50
Compare
|
Status report The new approach of the instrument post-processing works in almost all simple projects, e.g. Important The diff was made by this custom tool https://github.com/bric3/jardiff
|
aa6d660 to
0067ada
Compare
|
Just a minor comment. Probably it make sense to refactor this plugin to Kotlin. |
0067ada to
210d17c
Compare
d3a2cd2 to
899f804
Compare
The current implementation was using bad practices in various ways, `project.afterEvaluate`, task creation, explicit `dependsOn` # Conflicts: # buildSrc/src/main/groovy/InstrumentPlugin.groovy # buildSrc/src/main/groovy/MuzzlePlugin.groovy # dd-java-agent/instrumentation/jetty-9/build.gradle # Conflicts: # buildSrc/src/main/groovy/InstrumentPlugin.groovy # buildSrc/src/test/groovy/InstrumentPluginTest.groovy # dd-java-agent/instrumentation/play/play-2.4/build.gradle # dd-java-agent/instrumentation/play/play-2.6/build.gradle
…utions to instrument plugin
…and configuration
899f804 to
9b5556c
Compare
Yes, but I'd rather do it, in a second pass. Once this settles down. |
BenchmarksStartupParameters
See matching parameters
SummaryFound 0 performance improvements and 0 performance regressions! Performance is the same for 56 metrics, 9 unstable metrics. Startup time reports for petclinicgantt
title petclinic - global startup overhead: candidate=1.58.0-SNAPSHOT~ef1632183d, baseline=1.59.0-SNAPSHOT~cb69759fb3
dateFormat X
axisFormat %s
section tracing
Agent [baseline] (1.087 s) : 0, 1087191
Total [baseline] (10.818 s) : 0, 10818319
Agent [candidate] (1.101 s) : 0, 1100606
Total [candidate] (10.922 s) : 0, 10922354
section appsec
Agent [baseline] (1.276 s) : 0, 1275612
Total [baseline] (11.219 s) : 0, 11218554
Agent [candidate] (1.268 s) : 0, 1268068
Total [candidate] (10.989 s) : 0, 10989038
section iast
Agent [baseline] (1.226 s) : 0, 1226373
Total [baseline] (11.208 s) : 0, 11208044
Agent [candidate] (1.229 s) : 0, 1228651
Total [candidate] (11.138 s) : 0, 11137860
section profiling
Agent [baseline] (1.207 s) : 0, 1206854
Total [baseline] (10.917 s) : 0, 10917070
Agent [candidate] (1.215 s) : 0, 1214767
Total [candidate] (11.002 s) : 0, 11002394
gantt
title petclinic - break down per module: candidate=1.58.0-SNAPSHOT~ef1632183d, baseline=1.59.0-SNAPSHOT~cb69759fb3
dateFormat X
axisFormat %s
section tracing
crashtracking [baseline] (1.184 ms) : 0, 1184
crashtracking [candidate] (1.208 ms) : 0, 1208
BytebuddyAgent [baseline] (652.519 ms) : 0, 652519
BytebuddyAgent [candidate] (661.043 ms) : 0, 661043
GlobalTracer [baseline] (283.496 ms) : 0, 283496
GlobalTracer [candidate] (286.757 ms) : 0, 286757
AppSec [baseline] (32.638 ms) : 0, 32638
AppSec [candidate] (33.172 ms) : 0, 33172
Debugger [baseline] (68.305 ms) : 0, 68305
Debugger [candidate] (69.012 ms) : 0, 69012
Remote Config [baseline] (645.3 µs) : 0, 645
Remote Config [candidate] (687.229 µs) : 0, 687
Telemetry [baseline] (9.025 ms) : 0, 9025
Telemetry [candidate] (9.035 ms) : 0, 9035
Flare Poller [baseline] (3.778 ms) : 0, 3778
Flare Poller [candidate] (3.836 ms) : 0, 3836
section appsec
crashtracking [baseline] (1.195 ms) : 0, 1195
crashtracking [candidate] (1.189 ms) : 0, 1189
BytebuddyAgent [baseline] (696.03 ms) : 0, 696030
BytebuddyAgent [candidate] (692.657 ms) : 0, 692657
GlobalTracer [baseline] (260.039 ms) : 0, 260039
GlobalTracer [candidate] (259.34 ms) : 0, 259340
AppSec [baseline] (172.852 ms) : 0, 172852
AppSec [candidate] (172.118 ms) : 0, 172118
Debugger [baseline] (70.736 ms) : 0, 70736
Debugger [candidate] (68.697 ms) : 0, 68697
Remote Config [baseline] (799.235 µs) : 0, 799
Remote Config [candidate] (828.104 µs) : 0, 828
Telemetry [baseline] (9.647 ms) : 0, 9647
Telemetry [candidate] (9.421 ms) : 0, 9421
Flare Poller [baseline] (3.992 ms) : 0, 3992
Flare Poller [candidate] (3.788 ms) : 0, 3788
IAST [baseline] (24.753 ms) : 0, 24753
IAST [candidate] (24.57 ms) : 0, 24570
section iast
crashtracking [baseline] (1.179 ms) : 0, 1179
crashtracking [candidate] (1.195 ms) : 0, 1195
BytebuddyAgent [baseline] (791.739 ms) : 0, 791739
BytebuddyAgent [candidate] (794.094 ms) : 0, 794094
GlobalTracer [baseline] (257.378 ms) : 0, 257378
GlobalTracer [candidate] (257.708 ms) : 0, 257708
AppSec [baseline] (34.598 ms) : 0, 34598
AppSec [candidate] (34.719 ms) : 0, 34719
Debugger [baseline] (66.061 ms) : 0, 66061
Debugger [candidate] (65.749 ms) : 0, 65749
Remote Config [baseline] (593.788 µs) : 0, 594
Remote Config [candidate] (565.294 µs) : 0, 565
Telemetry [baseline] (8.58 ms) : 0, 8580
Telemetry [candidate] (8.529 ms) : 0, 8529
Flare Poller [baseline] (3.642 ms) : 0, 3642
Flare Poller [candidate] (3.544 ms) : 0, 3544
IAST [baseline] (27.0 ms) : 0, 27000
IAST [candidate] (26.964 ms) : 0, 26964
section profiling
crashtracking [baseline] (1.225 ms) : 0, 1225
crashtracking [candidate] (1.221 ms) : 0, 1221
BytebuddyAgent [baseline] (702.708 ms) : 0, 702708
BytebuddyAgent [candidate] (709.41 ms) : 0, 709410
GlobalTracer [baseline] (220.899 ms) : 0, 220899
GlobalTracer [candidate] (223.294 ms) : 0, 223294
AppSec [baseline] (32.192 ms) : 0, 32192
AppSec [candidate] (32.652 ms) : 0, 32652
Debugger [baseline] (68.617 ms) : 0, 68617
Debugger [candidate] (67.961 ms) : 0, 67961
Remote Config [baseline] (666.769 µs) : 0, 667
Remote Config [candidate] (663.821 µs) : 0, 664
Telemetry [baseline] (9.038 ms) : 0, 9038
Telemetry [candidate] (8.944 ms) : 0, 8944
Flare Poller [baseline] (3.78 ms) : 0, 3780
Flare Poller [candidate] (3.761 ms) : 0, 3761
ProfilingAgent [baseline] (97.747 ms) : 0, 97747
ProfilingAgent [candidate] (96.748 ms) : 0, 96748
Profiling [baseline] (98.326 ms) : 0, 98326
Profiling [candidate] (97.32 ms) : 0, 97320
Startup time reports for insecure-bankgantt
title insecure-bank - global startup overhead: candidate=1.58.0-SNAPSHOT~ef1632183d, baseline=1.59.0-SNAPSHOT~cb69759fb3
dateFormat X
axisFormat %s
section tracing
Agent [baseline] (1.088 s) : 0, 1087650
Total [baseline] (8.786 s) : 0, 8785516
Agent [candidate] (1.086 s) : 0, 1086113
Total [candidate] (8.761 s) : 0, 8760678
section iast
Agent [baseline] (1.226 s) : 0, 1225631
Total [baseline] (9.326 s) : 0, 9325738
Agent [candidate] (1.234 s) : 0, 1234179
Total [candidate] (9.346 s) : 0, 9346271
gantt
title insecure-bank - break down per module: candidate=1.58.0-SNAPSHOT~ef1632183d, baseline=1.59.0-SNAPSHOT~cb69759fb3
dateFormat X
axisFormat %s
section tracing
crashtracking [baseline] (1.193 ms) : 0, 1193
crashtracking [candidate] (1.18 ms) : 0, 1180
BytebuddyAgent [baseline] (653.513 ms) : 0, 653513
BytebuddyAgent [candidate] (652.811 ms) : 0, 652811
GlobalTracer [baseline] (283.385 ms) : 0, 283385
GlobalTracer [candidate] (283.474 ms) : 0, 283474
AppSec [baseline] (32.684 ms) : 0, 32684
AppSec [candidate] (32.773 ms) : 0, 32773
Debugger [baseline] (67.756 ms) : 0, 67756
Debugger [candidate] (66.92 ms) : 0, 66920
Remote Config [baseline] (649.944 µs) : 0, 650
Remote Config [candidate] (645.604 µs) : 0, 646
Telemetry [baseline] (8.992 ms) : 0, 8992
Telemetry [candidate] (8.976 ms) : 0, 8976
Flare Poller [baseline] (3.815 ms) : 0, 3815
Flare Poller [candidate] (3.816 ms) : 0, 3816
section iast
crashtracking [baseline] (1.189 ms) : 0, 1189
crashtracking [candidate] (1.192 ms) : 0, 1192
BytebuddyAgent [baseline] (792.413 ms) : 0, 792413
BytebuddyAgent [candidate] (799.065 ms) : 0, 799065
GlobalTracer [baseline] (257.071 ms) : 0, 257071
GlobalTracer [candidate] (258.26 ms) : 0, 258260
AppSec [baseline] (34.638 ms) : 0, 34638
AppSec [candidate] (32.932 ms) : 0, 32932
Debugger [baseline] (64.987 ms) : 0, 64987
Debugger [candidate] (67.109 ms) : 0, 67109
Remote Config [baseline] (598.235 µs) : 0, 598
Remote Config [candidate] (586.469 µs) : 0, 586
Telemetry [baseline] (8.528 ms) : 0, 8528
Telemetry [candidate] (8.491 ms) : 0, 8491
Flare Poller [baseline] (3.571 ms) : 0, 3571
Flare Poller [candidate] (3.527 ms) : 0, 3527
IAST [baseline] (27.069 ms) : 0, 27069
IAST [candidate] (27.264 ms) : 0, 27264
LoadParameters
See matching parameters
SummaryFound 0 performance improvements and 3 performance regressions! Performance is the same for 13 metrics, 20 unstable metrics.
Request duration reports for insecure-bankgantt
title insecure-bank - request duration [CI 0.99] : candidate=1.58.0-SNAPSHOT~ef1632183d, baseline=1.59.0-SNAPSHOT~cb69759fb3
dateFormat X
axisFormat %s
section baseline
no_agent (1.174 ms) : 1163, 1185
. : milestone, 1174,
iast (3.216 ms) : 3173, 3258
. : milestone, 3216,
iast_FULL (5.737 ms) : 5680, 5794
. : milestone, 5737,
iast_GLOBAL (3.591 ms) : 3540, 3643
. : milestone, 3591,
profiling (2.025 ms) : 2007, 2043
. : milestone, 2025,
tracing (1.876 ms) : 1860, 1892
. : milestone, 1876,
section candidate
no_agent (1.163 ms) : 1151, 1174
. : milestone, 1163,
iast (3.174 ms) : 3134, 3214
. : milestone, 3174,
iast_FULL (5.758 ms) : 5701, 5815
. : milestone, 5758,
iast_GLOBAL (3.562 ms) : 3512, 3613
. : milestone, 3562,
profiling (2.229 ms) : 2207, 2252
. : milestone, 2229,
tracing (1.795 ms) : 1780, 1811
. : milestone, 1795,
Request duration reports for petclinicgantt
title petclinic - request duration [CI 0.99] : candidate=1.58.0-SNAPSHOT~ef1632183d, baseline=1.59.0-SNAPSHOT~cb69759fb3
dateFormat X
axisFormat %s
section baseline
no_agent (17.98 ms) : 17800, 18161
. : milestone, 17980,
appsec (18.21 ms) : 18027, 18392
. : milestone, 18210,
code_origins (17.682 ms) : 17506, 17858
. : milestone, 17682,
iast (17.533 ms) : 17359, 17708
. : milestone, 17533,
profiling (19.805 ms) : 19604, 20006
. : milestone, 19805,
tracing (17.724 ms) : 17547, 17900
. : milestone, 17724,
section candidate
no_agent (18.894 ms) : 18698, 19091
. : milestone, 18894,
appsec (18.3 ms) : 18114, 18486
. : milestone, 18300,
code_origins (18.641 ms) : 18452, 18831
. : milestone, 18641,
iast (18.092 ms) : 17915, 18269
. : milestone, 18092,
profiling (19.042 ms) : 18851, 19234
. : milestone, 19042,
tracing (17.439 ms) : 17266, 17612
. : milestone, 17439,
DacapoParameters
See matching parameters
SummaryFound 0 performance improvements and 0 performance regressions! Performance is the same for 11 metrics, 1 unstable metrics. Execution time for biojavagantt
title biojava - execution time [CI 0.99] : candidate=1.58.0-SNAPSHOT~ef1632183d, baseline=1.59.0-SNAPSHOT~cb69759fb3
dateFormat X
axisFormat %s
section baseline
no_agent (14.715 s) : 14715000, 14715000
. : milestone, 14715000,
appsec (14.773 s) : 14773000, 14773000
. : milestone, 14773000,
iast (18.073 s) : 18073000, 18073000
. : milestone, 18073000,
iast_GLOBAL (17.897 s) : 17897000, 17897000
. : milestone, 17897000,
profiling (14.932 s) : 14932000, 14932000
. : milestone, 14932000,
tracing (14.608 s) : 14608000, 14608000
. : milestone, 14608000,
section candidate
no_agent (15.252 s) : 15252000, 15252000
. : milestone, 15252000,
appsec (14.637 s) : 14637000, 14637000
. : milestone, 14637000,
iast (18.52 s) : 18520000, 18520000
. : milestone, 18520000,
iast_GLOBAL (17.562 s) : 17562000, 17562000
. : milestone, 17562000,
profiling (14.796 s) : 14796000, 14796000
. : milestone, 14796000,
tracing (14.761 s) : 14761000, 14761000
. : milestone, 14761000,
Execution time for tomcatgantt
title tomcat - execution time [CI 0.99] : candidate=1.58.0-SNAPSHOT~ef1632183d, baseline=1.59.0-SNAPSHOT~cb69759fb3
dateFormat X
axisFormat %s
section baseline
no_agent (1.475 ms) : 1464, 1487
. : milestone, 1475,
appsec (3.723 ms) : 3501, 3945
. : milestone, 3723,
iast (2.227 ms) : 2161, 2293
. : milestone, 2227,
iast_GLOBAL (2.267 ms) : 2200, 2333
. : milestone, 2267,
profiling (2.111 ms) : 2055, 2167
. : milestone, 2111,
tracing (2.053 ms) : 2001, 2105
. : milestone, 2053,
section candidate
no_agent (1.474 ms) : 1463, 1486
. : milestone, 1474,
appsec (3.693 ms) : 3477, 3909
. : milestone, 3693,
iast (2.226 ms) : 2160, 2291
. : milestone, 2226,
iast_GLOBAL (2.267 ms) : 2201, 2333
. : milestone, 2267,
profiling (2.097 ms) : 2042, 2152
. : milestone, 2097,
tracing (2.061 ms) : 2009, 2112
. : milestone, 2061,
|
InstrumentPlugin as compilation post-processor and lazy
a485d08 to
83aa2a4
Compare
InstrumentPlugin as compilation post-processor and lazy83aa2a4 to
5311fd3
Compare
AlexeyKuznetsov-DD
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, left minor notes and questions.
buildSrc/src/main/groovy/datadog/gradle/plugin/instrument/BuildTimeInstrumentationPlugin.groovy
Show resolved
Hide resolved
| logger.info('[BuildTimeInstrumentationPlugin] Applying buildTimeInstrumentationPlugin configuration as compile task input') | ||
| it.inputs.files(project.configurations.named(BUILD_TIME_INSTRUMENTATION_PLUGIN_CONFIGURATION)) | ||
|
|
||
| if (it.source.isEmpty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this check? if it was already checked on line 103?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, maybe this can be removed.
| it.inputs.property("javaVersion", javaVersion) | ||
|
|
||
| it.inputs.property("plugins", extension.plugins) | ||
|
|
||
| it.inputs.files(extension.additionalClasspath) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor - remove empty lines to keep lines logically together.
| it.inputs.property("javaVersion", javaVersion) | |
| it.inputs.property("plugins", extension.plugins) | |
| it.inputs.files(extension.additionalClasspath) | |
| it.inputs.property("javaVersion", javaVersion) | |
| it.inputs.property("plugins", extension.plugins) | |
| it.inputs.files(extension.additionalClasspath) |
| tmpUninstrumentedClasses | ||
| ) | ||
|
|
||
| // This were the post processing happens, i.e. were the instrumentation is applied |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor: I would re-phrase this comment a bit, probably make it short: // Apply instrumentation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // This were the post processing happens, i.e. were the instrumentation is applied | |
| // Post-process classes with instrumentation |
buildSrc/src/main/groovy/datadog/gradle/plugin/instrument/ByteBuddyInstrumenter.groovy
Show resolved
Hide resolved
| logger.info( | ||
| "[InstrumentPostProcessingAction] About to instrument classes \n" + | ||
| " javaVersion=${javaVersion}, \n" + | ||
| " plugins=${plugins.get()}, \n" + | ||
| " instrumentingClassPath=${instrumentingClassPath.files}, \n" + | ||
| " rawClassesDirectory=${compilerOutputDirectory.get().asFile}" | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor: can we use multiline string here?
| logger.info('[BuildTimeInstrumentationPlugin] Applying buildTimeInstrumentationPlugin configuration as compile task input') | ||
| it.inputs.files(project.configurations.named(BUILD_TIME_INSTRUMENTATION_PLUGIN_CONFIGURATION)) | ||
|
|
||
| if (it.source.isEmpty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, maybe this can be removed.
| tmpUninstrumentedClasses | ||
| ) | ||
|
|
||
| // This were the post processing happens, i.e. were the instrumentation is applied |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // This were the post processing happens, i.e. were the instrumentation is applied | |
| // Post-process classes with instrumentation |
| it.dependencies.add(subProj.dependencies.project(path: ':dd-java-agent:agent-tooling', configuration: 'instrumentPluginClasspath')) | ||
| it.dependencies.add(subProj.dependencies.project( | ||
| path: ':dd-java-agent:agent-tooling', | ||
| configuration: 'buildTimeInstrumentationPlugin' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note: Maybe I'll rename this configuration to avoid confusion with the instrumentation plugin.
Something like
configuration: 'buildTimeInstrumentationPlugin'
configuration: 'buildTimeInstrumentationToolingPlugins'

What Does This Do
Disclaimer: This only touches the build part (i.e. Gradle).
The current
InstrumentPluginuses eager gradle API and inject a task to run after the compile task, and in doing so, exchanging their output. This approach is uncommon, create as many instrument task as they are compile tasks, and make it harder to predict compilation output.This PR rethink the approach to a compilation post-processor. So instead of injecting a task in the gradle task graph, each compile task have a post-processor action.
Also, the plugin is renamed to
dd-trace-java.build-time-instrumentationfor better expressing intent. (Related configuration points are also renamed),In doing so, it makes the intent of this plug-in easier to grasp.
On another note, the single Groovy file has been spread to distinct types.
Motivation
dd-trace-java.build-time-instrumentationwas chosen to aligndd-trace-java.call-site-instrumentation. Also, searching these string will bring more focused results.Avoid Gradle eager API, avoid messing with compile tasks avoid,
Helps going toward convention plug-ins.
Additional Notes
Related PRs
Related to
MuzzlePlugin#9315CallSiteInstrumentationPlugin#9316Blocked by
afterEvaluate#9752testJvmConstraintsGradle extension to replace extra properties #9892:dd-java-agent:testing#10218jetty-server-9.0project setup to multiple modules #9683What does this plugin
ℹ️ italic word indicate Gradle linguo.
buildTimeInstrumentationname (previouslyinstrument)buildTimeInstrumentationPluginname (previouslyinstrumentPluginClasspath)Currently, this build time instrumentation is applied on instrumentation modules :
datadog.trace.agent.tooling.muzzle.MuzzleGradlePlugin: Creates muzzle-references at compile time for classes extendingInstrumenterModule. This generates metadata about instrumentation compatibility.datadog.trace.agent.tooling.bytebuddy.NewTaskForGradlePlugin: Used fordatadog.trace.instrumentation.java.concurrent.WrapRunnableAsNewTaskInstrumentationinstrumentation, to replacedatadog.trace.bootstrap.instrumentation.java.concurrent.NewTaskForPlaceholder#newTaskForbyjava.util.concurrent.AbstractExecutorService#newTaskFor(java.lang.Runnable, T)(which is protected and not accessible during compilation).datadog.trace.agent.tooling.bytebuddy.reqctx.RewriteRequestContextAdvicePlugin: Transforms classes annotated with @RequiresRequestContext to inject request context handling....and in the otel agent
datadog.opentelemetry.tooling.shim.OtelShimGradlePlugin: Injects Datadog's OpenTelemetry shim into specific OpenTelemetry API classes like DefaultOpenTelemetry, GlobalOpenTelemetry$ObfuscatedOpenTelemetry, ThreadLocalContextStorage, etc. This allows intercepting OpenTelemetry API calls at build-time.Additional checks
As in #9514 I also checked the produced jars between
masterand this branch using myjardifftool I already mentioned there (I crafted it for validating #9514, other tools didn't work or didn't perform what was needed).Note
🔗 https://github.com/bric3/jardiff
Shortcomings:
Ran the following command on this branch (folder
dd-trace-java-copy-2), and onmaster(folderdd-trace-java-copy-1).The following assumes that
jardiffis actually this commandjava -jar jardiff/build/libs/jardiff-0.1.0-SNAPSHOT.jar, and assuming this is a Java 25. Also, while not strictly necessary the following snippets usedeltato render the diff.The following difference have been checked:
dd-java-agentjardiff ../dd-trace-java-copy-{1,2}/dd-java-agent/build/libs/dd-java-agent-1.58.0-SNAPSHOT.jar \ -c classdata \ --exclude "**/*.yaml,**/*.MF,**/*.version,*.version,*.txt" \ | delta --syntax-theme=GitHub --lightNo differences: