Skip to content
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -249,33 +249,3 @@ if (otelProps.testLatestDeps) {
}
}
}

tasks {
val generateInstrumentationVersionFile by registering {
val name = computeInstrumentationName()
val version = project.version as String
inputs.property("instrumentation.name", name)
inputs.property("instrumentation.version", version)

val propertiesDir = layout.buildDirectory.dir("generated/instrumentationVersion/META-INF/io/opentelemetry/instrumentation/")
outputs.dir(propertiesDir)

doLast {
File(propertiesDir.get().asFile, "$name.properties").writeText("version=$version")
}
}
}

fun computeInstrumentationName(): String {
val name = when (projectDir.name) {
"javaagent", "library", "library-autoconfigure" -> projectDir.parentFile.name
else -> project.name
}
return "io.opentelemetry.$name"
}

sourceSets {
main {
output.dir("build/generated/instrumentationVersion", "builtBy" to "generateInstrumentationVersionFile")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
plugins {
`java-library`
}

dependencies {
compileOnly("javax.annotation:javax.annotation-api:1.3.2")
}

tasks {
val generateInstrumentationVersionFile by registering {
val name = computeInstrumentationName()
val version = project.version as String
inputs.property("instrumentation.name", name)
inputs.property("instrumentation.version", version)

val propertiesDir = layout.buildDirectory.dir("generated/instrumentationVersion/META-INF/io/opentelemetry/instrumentation/")
outputs.dir(propertiesDir)

doLast {
val outputDir = propertiesDir.get().asFile
outputDir.mkdirs()
File(outputDir, "$name.properties").writeText("version=$version")
}
Comment thread
laurit marked this conversation as resolved.
}

val generateInstrumentationVersionClass by registering {
val name = computeInstrumentationName()
val version = project.version as String
inputs.property("instrumentation.name", name)
inputs.property("instrumentation.version", version)

// The same logic is duplicated in EmbeddedInstrumentationProperties
// Strip trailing version suffix and remove dashes.
// If the module name contains a non-trailing version number e.g. jaxrs-3.0-jersey-3.0 replace
// the dot with underscore. This is needed to turn the module name into valid package name, java
// package name segments cannot start with a number.
val moduleName = name.replace("(-[0-9.]*)$".toRegex(), "")
.replace("-", "")
.replace("([0-9]+)\\.([0-9]+)".toRegex(), "$1_$2")
// Extract trailing version number and replace dots with underscores so it could be used as a
// package name segment.
val baseVersion = name.replace(".*?([0-9.]*)$".toRegex(), "$1")
.replace(".", "_")
val packageName = moduleName + if (baseVersion.isNotEmpty()) ".v$baseVersion" else ""

val classDir = layout.buildDirectory.dir("generated/instrumentationVersionClass/${packageName.replace('.', '/')}/internal")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note that the package name will be something like io.opentelemetry.okhttp.v3_0 which doesn't get shaded

outputs.dir(classDir)

doLast {
val outputDir = classDir.get().asFile
outputDir.mkdirs()
File(outputDir, "InstrumentationVersion.java").writeText("""
package $packageName.internal;

import javax.annotation.Generated;

/** Autogenerated class do not edit. */
@Generated("otel.instrumentation-version")
public final class InstrumentationVersion {
public static final String VERSION = "$version";

private InstrumentationVersion() {}
}
""".trimIndent())
}
}

project.tasks.matching { it.name == "compileJava" || it.name == "sourcesJar"
|| it.name == "compileKotlin" || it.name == "kotlinSourcesJar" }.configureEach {
dependsOn(generateInstrumentationVersionFile, generateInstrumentationVersionClass)
}

named<Checkstyle>("checkstyleMain") {
exclude("**/InstrumentationVersion.java")
}
}

fun computeInstrumentationName(): String {
val name = when (projectDir.name) {
"javaagent", "library", "library-autoconfigure" -> projectDir.parentFile.name
else -> project.name
}
return "io.opentelemetry.$name"
}

sourceSets {
main {
output.dir("build/generated/instrumentationVersion", "builtBy" to "generateInstrumentationVersionFile")
java {
srcDir(layout.buildDirectory.dir("generated/instrumentationVersionClass"))
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
plugins {
id("io.opentelemetry.instrumentation.javaagent-instrumentation")

id("otel.javaagent-testing")
id("otel.publish-conventions")

id("io.opentelemetry.instrumentation.javaagent-instrumentation")
id("otel.instrumentation-version")
}

extra["mavenGroupId"] = "io.opentelemetry.javaagent.instrumentation"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ plugins {
id("otel.jacoco-conventions")
id("otel.java-conventions")
id("otel.publish-conventions")
id("otel.instrumentation-version")
}

extra["mavenGroupId"] = "io.opentelemetry.instrumentation"
Expand Down
2 changes: 2 additions & 0 deletions instrumentation-api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ dependencies {
testImplementation("io.opentelemetry.javaagent:opentelemetry-testing-common")
testImplementation("io.opentelemetry:opentelemetry-sdk-testing")
testImplementation("io.opentelemetry:opentelemetry-exporter-common")
// used for testing embedded instrumentation properties
testImplementation(project(":instrumentation:okhttp:okhttp-3.0:library"))

jmhImplementation(project(":instrumentation-api-incubator"))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,6 @@ public final class InstrumenterBuilder<REQUEST, RESPONSE> {
this.openTelemetry = openTelemetry;
this.instrumentationName = instrumentationName;
this.spanNameExtractor = spanNameExtractor;
this.instrumentationVersion =
EmbeddedInstrumentationProperties.findVersion(instrumentationName);
}

/**
Expand Down Expand Up @@ -302,6 +300,10 @@ private Instrumenter<REQUEST, RESPONSE> buildInstrumenter(
}

Tracer buildTracer() {
if (instrumentationVersion == null) {
instrumentationVersion = EmbeddedInstrumentationProperties.findVersion(instrumentationName);
}

TracerBuilder tracerBuilder =
openTelemetry.getTracerProvider().tracerBuilder(instrumentationName);
if (instrumentationVersion != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import javax.annotation.Nullable;

/**
Expand Down Expand Up @@ -54,6 +55,46 @@ public static String findVersion(String instrumentationName) {

@Nullable
private static String loadVersion(String instrumentationName) {
String version = loadVersionFromClass(instrumentationName);
if (version == null) {
Comment thread
laurit marked this conversation as resolved.
version = loadVersionFromProperties(instrumentationName);
}
return version;
}

private static final Pattern STRIP_VERSION_SUFFIX = Pattern.compile("(-[0-9.]*)$");
private static final Pattern NORMALIZE_VERSION = Pattern.compile("([0-9]+)\\.([0-9]+)");
private static final Pattern EXTRACT_VERSION = Pattern.compile(".*?([0-9.]*)$");

// visible for testing
@Nullable
static String loadVersionFromClass(String instrumentationName) {
// The same logic is duplicated in otel.instrumentation-version
// Strip trailing version suffix and remove dashes
String moduleName =
STRIP_VERSION_SUFFIX.matcher(instrumentationName).replaceAll("").replace("-", "");
// If the module name contains a non-trailing version number e.g. jaxrs-3.0-jersey-3.0 replace
// the dot with underscore. This is needed to turn the module name into valid package name, java
// package name segments cannot start with a number.
moduleName = NORMALIZE_VERSION.matcher(moduleName).replaceAll("$1_$2");
// Extract trailing version number and replace dots with underscores so it could be used as a
// package name segment.
String baseVersion =
EXTRACT_VERSION.matcher(instrumentationName).replaceAll("$1").replace(".", "_");
String packageName = moduleName + (baseVersion.isEmpty() ? "" : ".v" + baseVersion);

try {
Class<?> clazz =
Class.forName(packageName + ".internal.InstrumentationVersion", false, loader);
return clazz.getField("VERSION").get(null).toString();
} catch (ReflectiveOperationException e) {
return null;
}
}

// visible for testing
@Nullable
static String loadVersionFromProperties(String instrumentationName) {
String path =
"META-INF/io/opentelemetry/instrumentation/" + instrumentationName + ".properties";
try (InputStream in = loader.getResourceAsStream(path)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.api.internal;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.jupiter.api.Test;

class EmbeddedInstrumentationPropertiesTest {

@Test
void loadVersionFromClass() {
assertThat(
EmbeddedInstrumentationProperties.loadVersionFromClass("io.opentelemetry.okhttp-3.0"))
.isNotEmpty();
assertThat(EmbeddedInstrumentationProperties.loadVersionFromClass("does-not-exist")).isNull();
}

@Test
void loadVersionFromProperties() {
assertThat(
EmbeddedInstrumentationProperties.loadVersionFromProperties(
"io.opentelemetry.okhttp-3.0"))
.isNotEmpty();
assertThat(EmbeddedInstrumentationProperties.loadVersionFromProperties("does-not-exist"))
.isNull();
}
}
1 change: 1 addition & 0 deletions instrumentation/jdbc/library/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ tasks {
into("build/extracted/shadow-javaagent")
exclude("META-INF/**")
exclude("io/opentelemetry/javaagent/bootstrap/**")
exclude("**/InstrumentationVersion.class")
}

// this will be included in bootstrap module
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ tasks {
dependsOn(shadowJar)
from(zipTree(shadowJar.get().archiveFile))
exclude("META-INF/**")
exclude("**/InstrumentationVersion.class")
into("build/extracted/shadow")
}

Expand Down
3 changes: 3 additions & 0 deletions javaagent/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@ tasks {
filesMatching("META-INF/io/opentelemetry/instrumentation/**") {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
filesMatching("**/InstrumentationVersion.class") {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
exclude("META-INF/LICENSE")
exclude("META-INF/NOTICE")
exclude("META-INF/maven/**")
Expand Down
Loading