Simpler test agent (#3974)
* Trying to simplify testing agent * Simplified and verified it works * spotless * Code review comments * spotless
This commit is contained in:
parent
e30b082259
commit
3ae6b46930
|
@ -22,9 +22,3 @@ configurations.configureEach {
|
|||
exclude(module = "javaagent-bootstrap")
|
||||
}
|
||||
}
|
||||
|
||||
tasks {
|
||||
withType<Test>().configureEach {
|
||||
dependsOn(":testing:agent-for-testing:shadowJar")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,10 +18,17 @@ val bootstrapLibs by configurations.creating {
|
|||
isCanBeResolved = true
|
||||
isCanBeConsumed = false
|
||||
}
|
||||
// this configuration collects only required instrumentations and agent machinery
|
||||
val baseJavaagentLibs by configurations.creating {
|
||||
isCanBeResolved = true
|
||||
isCanBeConsumed = false
|
||||
}
|
||||
|
||||
// this configuration collects libs that will be placed in the agent classloader, isolated from the instrumented application code
|
||||
val javaagentLibs by configurations.creating {
|
||||
isCanBeResolved = true
|
||||
isCanBeConsumed = false
|
||||
extendsFrom(baseJavaagentLibs)
|
||||
}
|
||||
// this configuration collects just exporter libs (also placed in the agent classloader & isolated from the instrumented application)
|
||||
val exporterLibs by configurations.creating {
|
||||
|
@ -50,9 +57,17 @@ dependencies {
|
|||
bootstrapLibs(project(":javaagent-instrumentation-api"))
|
||||
bootstrapLibs("org.slf4j:slf4j-simple")
|
||||
|
||||
javaagentLibs(project(":javaagent-extension-api"))
|
||||
javaagentLibs(project(":javaagent-tooling"))
|
||||
javaagentLibs(project(":muzzle"))
|
||||
baseJavaagentLibs(project(":javaagent-extension-api"))
|
||||
baseJavaagentLibs(project(":javaagent-tooling"))
|
||||
baseJavaagentLibs(project(":muzzle"))
|
||||
baseJavaagentLibs(project(":instrumentation:opentelemetry-annotations-1.0:javaagent"))
|
||||
baseJavaagentLibs(project(":instrumentation:opentelemetry-api-1.0:javaagent"))
|
||||
baseJavaagentLibs(project(":instrumentation:executors:javaagent"))
|
||||
baseJavaagentLibs(project(":instrumentation:internal:internal-class-loader:javaagent"))
|
||||
baseJavaagentLibs(project(":instrumentation:internal:internal-eclipse-osgi-3.6:javaagent"))
|
||||
baseJavaagentLibs(project(":instrumentation:internal:internal-proxy:javaagent"))
|
||||
baseJavaagentLibs(project(":instrumentation:internal:internal-reflection:javaagent"))
|
||||
baseJavaagentLibs(project(":instrumentation:internal:internal-url-class-loader:javaagent"))
|
||||
|
||||
exporterLibs(project(":javaagent-exporters"))
|
||||
|
||||
|
@ -63,7 +78,7 @@ dependencies {
|
|||
licenseReportDependencies("com.blogspot.mydailyjava:weak-lock-free")
|
||||
// TODO ideally this would be :instrumentation instead of :javaagent-tooling
|
||||
// in case there are dependencies (accidentally) pulled in by instrumentation modules
|
||||
// but I couldn"t get that to work
|
||||
// but I couldn't get that to work
|
||||
licenseReportDependencies(project(":javaagent-tooling"))
|
||||
licenseReportDependencies(project(":javaagent-extension-api"))
|
||||
|
||||
|
@ -100,6 +115,16 @@ tasks {
|
|||
}
|
||||
}
|
||||
|
||||
val relocateBaseJavaagentLibs by registering(ShadowJar::class) {
|
||||
configurations = listOf(baseJavaagentLibs)
|
||||
|
||||
duplicatesStrategy = DuplicatesStrategy.FAIL
|
||||
|
||||
archiveFileName.set("baseJavaagentLibs-relocated.jar")
|
||||
|
||||
excludeBootstrapJars()
|
||||
}
|
||||
|
||||
val relocateJavaagentLibs by registering(ShadowJar::class) {
|
||||
configurations = listOf(javaagentLibs)
|
||||
|
||||
|
@ -107,13 +132,7 @@ tasks {
|
|||
|
||||
archiveFileName.set("javaagentLibs-relocated.jar")
|
||||
|
||||
// exclude bootstrap projects from javaagent libs - they won't be added to inst/
|
||||
dependencies {
|
||||
exclude(project(":instrumentation-api"))
|
||||
exclude(project(":instrumentation-api-annotation-support"))
|
||||
exclude(project(":javaagent-bootstrap"))
|
||||
exclude(project(":javaagent-instrumentation-api"))
|
||||
}
|
||||
excludeBootstrapJars()
|
||||
}
|
||||
|
||||
val relocateExporterLibs by registering(ShadowJar::class) {
|
||||
|
@ -160,8 +179,33 @@ tasks {
|
|||
}
|
||||
}
|
||||
|
||||
// Includes only the agent machinery and required instrumentations
|
||||
val baseJavaagentJar by registering(ShadowJar::class) {
|
||||
configurations = listOf(bootstrapLibs)
|
||||
|
||||
dependsOn(relocateBaseJavaagentLibs)
|
||||
isolateClasses(relocateBaseJavaagentLibs.get().outputs.files)
|
||||
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
|
||||
archiveClassifier.set("base")
|
||||
|
||||
manifest {
|
||||
attributes(shadowJar.get().manifest.attributes)
|
||||
}
|
||||
}
|
||||
|
||||
val baseJar by configurations.creating {
|
||||
isCanBeConsumed = true
|
||||
isCanBeResolved = false
|
||||
}
|
||||
|
||||
artifacts {
|
||||
add("baseJar", baseJavaagentJar)
|
||||
}
|
||||
|
||||
assemble {
|
||||
dependsOn(shadowJar, fullJavaagentJar)
|
||||
dependsOn(shadowJar, fullJavaagentJar, baseJavaagentJar)
|
||||
}
|
||||
|
||||
withType<Test>().configureEach {
|
||||
|
@ -223,3 +267,13 @@ fun CopySpec.isolateClasses(jars: Iterable<File>) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// exclude bootstrap projects from javaagent libs - they won't be added to inst/
|
||||
fun ShadowJar.excludeBootstrapJars() {
|
||||
dependencies {
|
||||
exclude(project(":instrumentation-api"))
|
||||
exclude(project(":instrumentation-api-annotation-support"))
|
||||
exclude(project(":javaagent-bootstrap"))
|
||||
exclude(project(":javaagent-instrumentation-api"))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,24 @@
|
|||
plugins {
|
||||
id("com.github.johnrengelman.shadow")
|
||||
id("otel.java-conventions")
|
||||
}
|
||||
|
||||
tasks.jar {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
dependencies {
|
||||
annotationProcessor("com.google.auto.service:auto-service")
|
||||
compileOnly("com.google.auto.service:auto-service")
|
||||
|
||||
implementation(project(":javaagent-extension-api"))
|
||||
implementation(project(":javaagent-instrumentation-api"))
|
||||
implementation(project(":javaagent-tooling"))
|
||||
compileOnly(project(":javaagent-extension-api"))
|
||||
compileOnly(project(":javaagent-instrumentation-api"))
|
||||
compileOnly(project(":javaagent-tooling"))
|
||||
|
||||
implementation("io.grpc:grpc-core:1.33.1")
|
||||
implementation("io.opentelemetry:opentelemetry-exporter-otlp")
|
||||
implementation("io.opentelemetry:opentelemetry-exporter-otlp-metrics")
|
||||
implementation("io.opentelemetry:opentelemetry-proto")
|
||||
implementation("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure")
|
||||
implementation("org.slf4j:slf4j-api")
|
||||
compileOnly("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure")
|
||||
compileOnly("org.slf4j:slf4j-api")
|
||||
}
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
|
||||
plugins {
|
||||
id("io.opentelemetry.instrumentation.javaagent-shadowing")
|
||||
|
||||
id("otel.java-conventions")
|
||||
id("otel.publish-conventions")
|
||||
}
|
||||
|
@ -10,119 +6,49 @@ plugins {
|
|||
description = "OpenTelemetry Javaagent for testing"
|
||||
group = "io.opentelemetry.javaagent"
|
||||
|
||||
// this configuration collects libs that will be placed in the bootstrap classloader
|
||||
val bootstrapLibs by configurations.creating {
|
||||
val agent by configurations.creating {
|
||||
isCanBeResolved = true
|
||||
isCanBeConsumed = false
|
||||
}
|
||||
// this configuration collects libs that will be placed in the agent classloader, isolated from the instrumented application code
|
||||
val javaagentLibs by configurations.creating {
|
||||
|
||||
val extensionLibs by configurations.creating {
|
||||
isCanBeResolved = true
|
||||
isCanBeConsumed = false
|
||||
|
||||
// exclude dependencies that are to be placed in bootstrap - they won't be added to inst/
|
||||
exclude("org.slf4j")
|
||||
exclude("io.opentelemetry", "opentelemetry-api")
|
||||
exclude("io.opentelemetry", "opentelemetry-api-metrics")
|
||||
exclude("io.opentelemetry", "opentelemetry-semconv")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
bootstrapLibs(project(":instrumentation-api"))
|
||||
bootstrapLibs(project(":instrumentation-api-annotation-support"))
|
||||
bootstrapLibs(project(":javaagent-bootstrap"))
|
||||
bootstrapLibs(project(":javaagent-instrumentation-api"))
|
||||
bootstrapLibs("org.slf4j:slf4j-simple")
|
||||
|
||||
javaagentLibs(project(":testing:agent-exporter"))
|
||||
javaagentLibs(project(":javaagent-extension-api"))
|
||||
javaagentLibs(project(":javaagent-tooling"))
|
||||
javaagentLibs(project(":muzzle"))
|
||||
|
||||
// Include instrumentations instrumenting core JDK classes tp ensure interoperability with other instrumentation
|
||||
javaagentLibs(project(":instrumentation:executors:javaagent"))
|
||||
// FIXME: we should enable this, but currently this fails tests for google http client
|
||||
// testImplementation project(":instrumentation:http-url-connection:javaagent")
|
||||
javaagentLibs(project(":instrumentation:internal:internal-class-loader:javaagent"))
|
||||
javaagentLibs(project(":instrumentation:internal:internal-eclipse-osgi-3.6:javaagent"))
|
||||
javaagentLibs(project(":instrumentation:internal:internal-proxy:javaagent"))
|
||||
javaagentLibs(project(":instrumentation:internal:internal-reflection:javaagent"))
|
||||
javaagentLibs(project(":instrumentation:internal:internal-url-class-loader:javaagent"))
|
||||
|
||||
// Many tests use OpenTelemetry API calls, e.g. via InstrumentationTestRunner.runWithSpan
|
||||
javaagentLibs(project(":instrumentation:opentelemetry-annotations-1.0:javaagent"))
|
||||
javaagentLibs(project(":instrumentation:opentelemetry-api-1.0:javaagent"))
|
||||
extensionLibs(project(":testing:agent-exporter", configuration = "shadow"))
|
||||
agent(project(":javaagent", configuration = "baseJar"))
|
||||
|
||||
testImplementation(project(":testing-common"))
|
||||
testImplementation("io.opentelemetry:opentelemetry-api")
|
||||
}
|
||||
|
||||
val javaagentDependencies = dependencies
|
||||
|
||||
// collect all bootstrap instrumentation dependencies
|
||||
project(":instrumentation").subprojects {
|
||||
val subProj = this
|
||||
|
||||
plugins.withId("otel.javaagent-bootstrap") {
|
||||
javaagentDependencies.run {
|
||||
add(bootstrapLibs.name, project(subProj.path))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks {
|
||||
val relocateJavaagentLibs by registering(ShadowJar::class) {
|
||||
configurations = listOf(javaagentLibs)
|
||||
|
||||
archiveFileName.set("javaagentLibs-relocated.jar")
|
||||
|
||||
// exclude bootstrap projects from javaagent libs - they won't be added to inst/
|
||||
dependencies {
|
||||
exclude(project(":instrumentation-api"))
|
||||
exclude(project(":instrumentation-api-annotation-support"))
|
||||
exclude(project(":javaagent-bootstrap"))
|
||||
exclude(project(":javaagent-instrumentation-api"))
|
||||
}
|
||||
// Extracts manifest from OpenTelemetry Java agent to reuse it later
|
||||
val agentManifest by registering(Copy::class) {
|
||||
dependsOn(agent)
|
||||
from(zipTree(agent.singleFile).matching {
|
||||
include("META-INF/MANIFEST.MF")
|
||||
})
|
||||
into("$buildDir/tmp")
|
||||
}
|
||||
|
||||
val shadowJar by existing(ShadowJar::class) {
|
||||
configurations = listOf(bootstrapLibs)
|
||||
|
||||
dependsOn(relocateJavaagentLibs)
|
||||
isolateClasses(relocateJavaagentLibs.get().outputs.files)
|
||||
|
||||
archiveClassifier.set("")
|
||||
|
||||
manifest {
|
||||
attributes(
|
||||
"Main-Class" to "io.opentelemetry.javaagent.OpenTelemetryAgent",
|
||||
"Agent-Class" to "io.opentelemetry.javaagent.OpenTelemetryAgent",
|
||||
"Premain-Class" to "io.opentelemetry.javaagent.OpenTelemetryAgent",
|
||||
"Can-Redefine-Classes" to true,
|
||||
"Can-Retransform-Classes" to true
|
||||
)
|
||||
jar {
|
||||
dependsOn(agentManifest)
|
||||
manifest.from("$buildDir/tmp/META-INF/MANIFEST.MF")
|
||||
from(zipTree(agent.singleFile))
|
||||
from(extensionLibs) {
|
||||
into("extensions")
|
||||
}
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
withType<Test>().configureEach {
|
||||
dependsOn(shadowJar)
|
||||
inputs.file(shadowJar.get().archiveFile)
|
||||
dependsOn(jar)
|
||||
|
||||
jvmArgs("-Dotel.javaagent.debug=true")
|
||||
jvmArgs("-javaagent:${shadowJar.get().archiveFile.get().asFile.absolutePath}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun CopySpec.isolateClasses(jars: Iterable<File>) {
|
||||
jars.forEach {
|
||||
from(zipTree(it)) {
|
||||
// important to keep prefix "inst" short, as it is prefixed to lots of strings in runtime mem
|
||||
into("inst")
|
||||
rename("(^.*)\\.class\$", "\$1.classdata")
|
||||
// Rename LICENSE file since it clashes with license dir on non-case sensitive FSs (i.e. Mac)
|
||||
rename("""^LICENSE$""", "LICENSE.renamed")
|
||||
jvmArgs("-javaagent:${jar.get().archiveFile.get().asFile.absolutePath}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue