-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild.gradle.kts
317 lines (254 loc) · 10.5 KB
/
build.gradle.kts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import com.github.jk1.license.filter.LicenseBundleNormalizer
import com.github.jk1.license.render.InventoryMarkdownReportRenderer
plugins {
id("com.github.jk1.dependency-license-report")
id("otel.java-conventions")
id("otel.publish-conventions")
id("io.opentelemetry.instrumentation.javaagent-shadowing")
}
description = "OpenTelemetry Javaagent"
group = "io.opentelemetry.javaagent"
// this configuration collects libs that will be placed in the bootstrap classloader
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)
}
// exclude dependencies that are to be placed in bootstrap from agent libs - they won't be added to inst/
listOf(baseJavaagentLibs, javaagentLibs).forEach {
it.run {
exclude("io.opentelemetry", "opentelemetry-api")
exclude("io.opentelemetry", "opentelemetry-api-logs")
exclude("io.opentelemetry", "opentelemetry-semconv")
}
}
val licenseReportDependencies by configurations.creating {
extendsFrom(bootstrapLibs)
}
dependencies {
bootstrapLibs(project(":instrumentation-api"))
// opentelemetry-api is an api dependency of :instrumentation-api, but opentelemetry-api-logs is not
bootstrapLibs("io.opentelemetry:opentelemetry-api-logs")
bootstrapLibs(project(":instrumentation-api-semconv"))
bootstrapLibs(project(":instrumentation-annotations-support"))
bootstrapLibs(project(":javaagent-bootstrap"))
// extension-api contains both bootstrap packages and agent packages
bootstrapLibs(project(":javaagent-extension-api")) {
// exclude javaagent dependencies from the bootstrap classpath
exclude("net.bytebuddy")
exclude("org.ow2.asm")
exclude("io.opentelemetry", "opentelemetry-sdk")
exclude("io.opentelemetry", "opentelemetry-sdk-extension-autoconfigure")
exclude("io.opentelemetry", "opentelemetry-sdk-extension-autoconfigure-spi")
}
baseJavaagentLibs(project(":javaagent-extension-api"))
baseJavaagentLibs(project(":javaagent-tooling"))
baseJavaagentLibs(project(":javaagent-internal-logging-simple", configuration = "shadow"))
baseJavaagentLibs(project(":muzzle"))
baseJavaagentLibs(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.0:javaagent"))
baseJavaagentLibs(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.4:javaagent"))
baseJavaagentLibs(project(":instrumentation:opentelemetry-instrumentation-api:javaagent"))
baseJavaagentLibs(project(":instrumentation:opentelemetry-instrumentation-annotations-1.16: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-lambda:javaagent"))
baseJavaagentLibs(project(":instrumentation:internal:internal-reflection:javaagent"))
baseJavaagentLibs(project(":instrumentation:internal:internal-url-class-loader:javaagent"))
// concurrentlinkedhashmap-lru and weak-lock-free are copied in to the instrumentation-api module
licenseReportDependencies("com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2")
licenseReportDependencies("com.blogspot.mydailyjava:weak-lock-free:0.18")
// 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
licenseReportDependencies(project(":javaagent-tooling"))
licenseReportDependencies(project(":javaagent-internal-logging-simple"))
licenseReportDependencies(project(":javaagent-extension-api"))
testCompileOnly(project(":javaagent-bootstrap"))
testCompileOnly(project(":javaagent-extension-api"))
testImplementation("com.google.guava:guava")
testImplementation("io.opentelemetry:opentelemetry-sdk")
testImplementation("io.opentracing.contrib.dropwizard:dropwizard-opentracing:0.2.2")
}
val javaagentDependencies = dependencies
// collect all bootstrap and javaagent instrumentation dependencies
project(":instrumentation").subprojects {
val subProj = this
plugins.withId("otel.javaagent-bootstrap") {
javaagentDependencies.run {
add(bootstrapLibs.name, project(subProj.path))
}
}
plugins.withId("otel.javaagent-instrumentation") {
javaagentDependencies.run {
add(javaagentLibs.name, project(subProj.path))
}
}
plugins.withId("otel.sdk-extension") {
javaagentDependencies.run {
add(javaagentLibs.name, project(subProj.path))
}
}
}
tasks {
processResources {
from(rootProject.file("licenses")) {
into("META-INF/licenses")
}
}
val buildBootstrapLibs by registering(ShadowJar::class) {
configurations = listOf(bootstrapLibs)
// exclude the agent part of the javaagent-extension-api; these classes will be added in relocate tasks
exclude("io/opentelemetry/javaagent/extension/**")
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
archiveFileName.set("bootstrapLibs.jar")
}
val relocateBaseJavaagentLibs by registering(ShadowJar::class) {
configurations = listOf(baseJavaagentLibs)
excludeBootstrapClasses()
duplicatesStrategy = DuplicatesStrategy.FAIL
archiveFileName.set("baseJavaagentLibs-relocated.jar")
}
val relocateJavaagentLibs by registering(ShadowJar::class) {
configurations = listOf(javaagentLibs)
excludeBootstrapClasses()
duplicatesStrategy = DuplicatesStrategy.FAIL
archiveFileName.set("javaagentLibs-relocated.jar")
}
// Includes everything needed for OOTB experience
val shadowJar by existing(ShadowJar::class) {
dependsOn(buildBootstrapLibs)
from(zipTree(buildBootstrapLibs.get().archiveFile))
dependsOn(relocateJavaagentLibs)
isolateClasses(relocateJavaagentLibs.get().archiveFile)
duplicatesStrategy = DuplicatesStrategy.FAIL
archiveClassifier.set("")
manifest {
attributes(jar.get().manifest.attributes)
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
)
}
}
// Includes only the agent machinery and required instrumentations
val baseJavaagentJar by registering(ShadowJar::class) {
dependsOn(buildBootstrapLibs)
from(zipTree(buildBootstrapLibs.get().archiveFile))
dependsOn(relocateBaseJavaagentLibs)
isolateClasses(relocateBaseJavaagentLibs.get().archiveFile)
duplicatesStrategy = DuplicatesStrategy.FAIL
archiveClassifier.set("base")
manifest {
attributes(shadowJar.get().manifest.attributes)
}
}
jar {
// Empty jar that cannot be used for anything and isn't published.
archiveClassifier.set("dontuse")
}
val baseJar by configurations.creating {
isCanBeConsumed = true
isCanBeResolved = false
}
artifacts {
add("baseJar", baseJavaagentJar)
}
assemble {
dependsOn(shadowJar, baseJavaagentJar)
}
withType<Test>().configureEach {
dependsOn(shadowJar)
jvmArgs("-Dotel.javaagent.debug=true")
jvmArgumentProviders.add(JavaagentProvider(shadowJar.flatMap { it.archiveFile }))
testLogging {
events("started")
}
}
val cleanLicenses by registering(Delete::class) {
delete(rootProject.file("licenses"))
}
named("generateLicenseReport").configure {
dependsOn(cleanLicenses)
finalizedBy(":spotlessApply")
}
// Because we reconfigure publishing to only include the shadow jar, the Gradle metadata is not correct.
// Since we are fully bundled and have no dependencies, Gradle metadata wouldn't provide any advantage over
// the POM anyways so in practice we shouldn't be losing anything.
withType<GenerateModuleMetadata>().configureEach {
enabled = false
}
}
// Don't publish non-shadowed jar (shadowJar is in shadowRuntimeElements)
with(components["java"] as AdhocComponentWithVariants) {
configurations.forEach {
withVariantsFromConfiguration(configurations["apiElements"]) {
skip()
}
withVariantsFromConfiguration(configurations["runtimeElements"]) {
skip()
}
}
}
licenseReport {
outputDir = rootProject.file("licenses").absolutePath
renderers = arrayOf(InventoryMarkdownReportRenderer())
configurations = arrayOf(licenseReportDependencies.name)
excludeBoms = true
excludeGroups = arrayOf(
"io\\.opentelemetry\\.instrumentation",
"io\\.opentelemetry\\.javaagent",
"io\\.opentelemetry\\.dummy\\..*"
)
excludes = arrayOf(
"io.opentelemetry:opentelemetry-bom-alpha",
"opentelemetry-java-instrumentation:dependencyManagement"
)
filters = arrayOf(LicenseBundleNormalizer("$projectDir/license-normalizer-bundle.json", true))
}
fun CopySpec.isolateClasses(jar: Provider<RegularFile>) {
from(zipTree(jar)) {
// 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")
exclude("META-INF/INDEX.LIST")
exclude("META-INF/*.DSA")
exclude("META-INF/*.SF")
}
}
// exclude bootstrap projects from javaagent libs - they won't be added to inst/
fun ShadowJar.excludeBootstrapClasses() {
dependencies {
exclude(project(":instrumentation-api"))
exclude(project(":instrumentation-api-semconv"))
exclude(project(":instrumentation-annotations-support"))
exclude(project(":javaagent-bootstrap"))
}
// exclude the bootstrap part of the javaagent-extension-api
exclude("io/opentelemetry/javaagent/bootstrap/**")
}
class JavaagentProvider(
@InputFile
@PathSensitive(PathSensitivity.RELATIVE)
val agentJar: Provider<RegularFile>
) : CommandLineArgumentProvider {
override fun asArguments(): Iterable<String> = listOf(
"-javaagent:${file(agentJar).absolutePath}"
)
}