A set of vendor-agnostic Gradle plugins to ease building Java applications that leverage instrumentation agents in development and/or in production
The work on this software project is in no way associated with my employer nor with the role I'm having at my employer. Any requests for changes will be decided upon exclusively by myself based on my personal preferences. I maintain this project as much or as little as my spare time permits.
This Gradle plugin tightly integrates with the Gradle application plugin
to make instrumenting your application build by Gradle easy! Simply register the javaagent-application
plugin and
then specify the javaagent you would like to attach in the dependencies block
plugins {
application
id("com.ryandens.javaagent-application") version "0.6.1"
}
application {
mainClass.set("yourMainClassName")
}
dependencies {
javaagent("io.opentelemetry.javaagent:opentelemetry-javaagent:1.11.1")
}
Now, when you run the ApplicationPlugin's run
task, your application will be instrumented with the javaagent specified
by the javaagent
Gradle configuration! In addition, the distributions created by the distTar
and distZip
ApplicationPlugin tasks include the javaagent JAR in the archive's dependency directory. Finally, the distribution
start scripts have been modified to automatically attach the agent via the command line -javaagent
flag.
Jib is a build tool for containerizing Java applications without a Docker
daemon. This project integrates with the jib-gradle-plugin
via the jib-extensions API to add the javaagent JAR as a new
layer in the container image and modifies the entrypoint of the container to automatically attach the agent at runtime
via the command line -javaagent
flag. Simply register the javaagent-jib
plugin and then specify the javaagent you
would like to attach in the dependencies block.
plugins {
java
id("com.google.cloud.tools.jib") version "3.1.4"
id("com.ryandens.javaagent-jib") version "0.6.1"
}
jib.container {
mainClass = "yourMainClassName"
}
dependencies {
javaagent("io.opentelemetry.javaagent:opentelemetry-javaagent:1.11.1")
}
The Gradle Java Plugin creates a test task that launches a forked JVM from the build for testing purposes. The
com.ryandens.javaagent-test
plugin automatically configures the jvm to be launched with the javaagents specified by
the javaagent
configuration attached. This enables the use of runtime analysis via javaagents for projects. Common
uses cases for this include collecting telemetry data from test runs or leveraging an Interactive Application Security
Testing (IAST) product.
plugins {
java
id("com.ryandens.javaagent-test") version "0.6.1"
}
tasks.named<Test>("test") {
useJUnitPlatform()
}
dependencies {
javaagent("io.opentelemetry.javaagent:opentelemetry-javaagent:1.11.1")
testJavaagent("com.ryandens.example:agent:1.0.0") // only attached to test task but ignored by other gradle plugins in this project.
}
OpenTelemetry is a set of tools that enable distributed tracing. OpenTelemetry Instrumentation for Java is a project that is often consumed as a javaagent in order to instrument OSS libraries with distributed tracing logic. There are many distributions of this agent by specific vendors. In addition, OpenTelemetry offers a number of extension points that consumers of the libraries and vendors can take advantage of.
This integration strives to make it easier for consumers of OpenTelemetry distributions to modify their chosen distributions with other extensions and instrumentation modules. This is desirable because OpenTelemetry provides a high-level API for instrumentation which makes writing instrumentation modules using their API a lot more approachable for those unfamiliar with bytecode manipulation.
This integration can be used by applying the javaagent-otel-modification
plugin, specifying the OTel distribution you would like to
extend and the libraries or projects you would like to extend it with. In addition, this plugin also applies the
JavaagentBasePlugin and registers the outputted
extended OpenTelemetry agent as a project dependency with the javaagent
configuration. This does effectively nothing
on its own, but allows for seamless integration with plugins that leverage the javaagent
configuration (such as
javaagent-application
and javaagent-jib
) so that the extended OpenTelemetry agent is configured is included in the
desired application distribution or execution method.
plugins {
application
id("com.ryandens.javaagent-otel-modification") version "0.6.1"
id("com.ryandens.javaagent-application") version "0.6.1"
}
dependencies {
// the otel configuration is used to identify the desired distribution to modify
otel("io.opentelemetry.javaagent:opentelemetry-javaagent:1.12.0")
// the otelExtension configuration expects a shaded JAR that conforms to OTel's rules
otelExtension("io.opentelemetry.contrib:opentelemetry-samplers:1.12.0-alpha")
// the otelInstrumentation expects a project whose references to the OTel API have been relocated in order to match the agent's shaded class names. Note, this plugin will rename the files from .class -> .classdata
otelInstrumentation(project(":custom-instrumentation"))
}
application {
// Define the main class for the application.
mainClass.set("com.ryandens.javaaagent.example.App")
}
setOf(tasks.distTar, tasks.distZip).forEach {
it.configure {
dependsOn(tasks.extendedAgent)
}
}