Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
cf9d250
add missing declarative config resource providers
zeitlinger Jul 10, 2025
70cc64c
add missing declarative config resource providers
zeitlinger Jul 10, 2025
cadc237
add missing declarative config resource providers
zeitlinger Jul 10, 2025
a128a8f
prevent that view config file is loaded
zeitlinger Jul 10, 2025
677bf18
pr review
zeitlinger Jul 16, 2025
b594dfb
add docs
zeitlinger Jul 16, 2025
6219ad9
pr feedback
zeitlinger Jul 17, 2025
9ffb655
pr review
zeitlinger Aug 16, 2025
acce028
fix
zeitlinger Aug 20, 2025
e082955
pr feedback
zeitlinger Aug 21, 2025
27d6dc7
pr feedback
zeitlinger Aug 21, 2025
582adac
separate resource extraction from supported interfaces
zeitlinger Aug 22, 2025
e242758
separate resource extraction from supported interfaces
zeitlinger Aug 22, 2025
40a3106
separate resource extraction from supported interfaces
zeitlinger Aug 22, 2025
7a0a61e
separate resource extraction from supported interfaces
zeitlinger Aug 22, 2025
850a699
./gradlew spotlessApply
otelbot[bot] Aug 22, 2025
a33147f
fix
zeitlinger Aug 22, 2025
550bc66
fix rebase
zeitlinger Aug 29, 2025
77f3fbc
./gradlew spotlessApply
otelbot[bot] Aug 29, 2025
dd20147
set enabled in test
zeitlinger Sep 2, 2025
b2b21db
add smoke test
zeitlinger Sep 5, 2025
194d2cb
add smoke test
zeitlinger Sep 5, 2025
03ef3ed
pr review
zeitlinger Sep 11, 2025
db3a54a
pr review
zeitlinger Sep 11, 2025
c69a836
pr review
zeitlinger Sep 11, 2025
a47828c
pr review
zeitlinger Sep 11, 2025
48a4105
pr review
zeitlinger Sep 11, 2025
b808538
pr review
zeitlinger Sep 11, 2025
3a44358
pr review
zeitlinger Sep 11, 2025
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
1 change: 1 addition & 0 deletions instrumentation/resources/library/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ dependencies {
compileOnly("io.opentelemetry:opentelemetry-api-incubator")
implementation("io.opentelemetry:opentelemetry-sdk-common")
implementation("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi")
compileOnly("io.opentelemetry:opentelemetry-sdk-extension-incubator")
implementation("io.opentelemetry.semconv:opentelemetry-semconv")

annotationProcessor("com.google.auto.service:auto-service")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ public <T> AttributeBuilder add(AttributeKey<T> key, Function<D, Optional<T>> ge
}

private Set<AttributeKey<?>> filteredKeys;

private final Map<AttributeKey<Object>, Function<D, Optional<?>>> attributeGetters =
new HashMap<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,57 +5,25 @@

package io.opentelemetry.instrumentation.resources;

import static java.util.logging.Level.FINE;

import com.google.auto.service.AutoService;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.instrumentation.resources.internal.JarServiceNameResourceExtractor;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
import io.opentelemetry.sdk.autoconfigure.spi.internal.ConditionalResourceProvider;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.semconv.ServiceAttributes;
import java.nio.file.Path;
import java.util.Map;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.logging.Logger;

/**
* A {@link ResourceProvider} that will attempt to detect the application name from the jar name.
* A {@link ResourceProvider} that will attempt to detect the <code>service.name</code> from the
* main jar file name.
*/
@AutoService(ResourceProvider.class)
public final class JarServiceNameDetector implements ConditionalResourceProvider {

private static final Logger logger = Logger.getLogger(JarServiceNameDetector.class.getName());

private final Supplier<Optional<Path>> jarPathSupplier;

@SuppressWarnings("unused") // SPI
public JarServiceNameDetector() {
this(MainJarPathHolder::getJarPath);
}

private JarServiceNameDetector(Supplier<Optional<Path>> jarPathSupplier) {
this.jarPathSupplier = jarPathSupplier;
}

// visible for tests
JarServiceNameDetector(MainJarPathFinder jarPathFinder) {
this(() -> Optional.ofNullable(jarPathFinder.detectJarPath()));
}

@Override
public Resource createResource(ConfigProperties config) {
return jarPathSupplier
.get()
.map(
jarPath -> {
String serviceName = getServiceName(jarPath);
logger.log(
FINE, "Auto-detected service name from the jar file name: {0}", serviceName);
return Resource.create(Attributes.of(ServiceAttributes.SERVICE_NAME, serviceName));
})
.orElseGet(Resource::empty);
return new JarServiceNameResourceExtractor().extract();
}

@Override
Expand All @@ -67,12 +35,6 @@ public boolean shouldApply(ConfigProperties config, Resource existing) {
&& "unknown_service:java".equals(existing.getAttribute(ServiceAttributes.SERVICE_NAME));
}

private static String getServiceName(Path jarPath) {
String jarName = jarPath.getFileName().toString();
int dotIndex = jarName.lastIndexOf(".");
return dotIndex == -1 ? jarName : jarName.substring(0, dotIndex);
}

@Override
public int order() {
// make it run later than the SpringBootServiceNameDetector
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,79 +5,48 @@

package io.opentelemetry.instrumentation.resources;

import static java.util.logging.Level.FINE;

import com.google.auto.service.AutoService;
import io.opentelemetry.instrumentation.resources.internal.ManifestResourceExtractor;
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.semconv.ServiceAttributes;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.logging.Logger;

/**
* A {@link ResourceProvider} that will attempt to detect the <code>service.name</code> and <code>
* service.version</code> from META-INF/MANIFEST.MF.
*/
@AutoService(ResourceProvider.class)
public final class ManifestResourceProvider extends AttributeResourceProvider<Manifest> {

private static final Logger logger = Logger.getLogger(ManifestResourceProvider.class.getName());
public final class ManifestResourceProvider extends AttributeResourceProvider<Resource> {

@SuppressWarnings("unused") // SPI
public ManifestResourceProvider() {
this(MainJarPathHolder::getJarPath, ManifestResourceProvider::readManifest);
this(() -> new ManifestResourceExtractor().extract());
}

private ManifestResourceProvider(
Supplier<Optional<Path>> jarPathSupplier, Function<Path, Optional<Manifest>> manifestReader) {
// Visible for testing
ManifestResourceProvider(Supplier<Resource> resourceSupplier) {
super(
new AttributeProvider<Manifest>() {
new AttributeProvider<Resource>() {
@Override
public Optional<Manifest> readData() {
return jarPathSupplier.get().flatMap(manifestReader);
public Optional<Resource> readData() {
return Optional.of(resourceSupplier.get());
}

@Override
public void registerAttributes(Builder<Manifest> builder) {
public void registerAttributes(Builder<Resource> builder) {
builder
.add(
ServiceAttributes.SERVICE_NAME,
manifest -> {
String serviceName =
manifest.getMainAttributes().getValue("Implementation-Title");
return Optional.ofNullable(serviceName);
})
r -> Optional.ofNullable(r.getAttribute(ServiceAttributes.SERVICE_NAME)))
.add(
ServiceAttributes.SERVICE_VERSION,
manifest -> {
String serviceVersion =
manifest.getMainAttributes().getValue("Implementation-Version");
return Optional.ofNullable(serviceVersion);
});
r -> Optional.ofNullable(r.getAttribute(ServiceAttributes.SERVICE_VERSION)));
}
});
}

// Visible for testing
ManifestResourceProvider(
MainJarPathFinder jarPathFinder, Function<Path, Optional<Manifest>> manifestReader) {
this(() -> Optional.ofNullable(jarPathFinder.detectJarPath()), manifestReader);
}

private static Optional<Manifest> readManifest(Path jarPath) {
try (JarFile jarFile = new JarFile(jarPath.toFile(), false)) {
return Optional.of(jarFile.getManifest());
} catch (IOException exception) {
logger.log(FINE, "Error reading manifest", exception);
return Optional.empty();
}
}

@Override
public int order() {
// make it run later than SpringBootServiceNameDetector
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.instrumentation.resources.internal.ProcessArguments;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.semconv.SchemaUrls;
import java.io.File;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@
@AutoService(ComponentProvider.class)
public class ContainerResourceComponentProvider extends ResourceComponentProvider {
public ContainerResourceComponentProvider() {
super("container", ContainerResource::get);
super("container", p -> ContainerResource.get());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@
@AutoService(ComponentProvider.class)
public class HostResourceComponentProvider extends ResourceComponentProvider {
public HostResourceComponentProvider() {
super("host", () -> HostResource.get().merge(HostIdResource.get()).merge(OsResource.get()));
super("host", p -> HostResource.get().merge(HostIdResource.get()).merge(OsResource.get()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.resources.internal;

import com.google.auto.service.AutoService;
import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider;

/**
* Declarative config jar resource provider.
*
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
* at any time.
*/
@SuppressWarnings("rawtypes")
@AutoService(ComponentProvider.class)
public class JarResourceComponentProvider extends ResourceComponentProvider {
public JarResourceComponentProvider() {
super("jar", p -> new JarServiceNameResourceExtractor().extract());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.resources.internal;

import static java.util.logging.Level.FINE;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.semconv.ServiceAttributes;
import java.nio.file.Path;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.logging.Logger;

/**
* A resource extractor that will attempt to detect the <code>service.name</code> from the main jar
* file name.
*
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
* at any time.
*/
public final class JarServiceNameResourceExtractor {

private static final Logger logger =
Logger.getLogger(JarServiceNameResourceExtractor.class.getName());

private final Supplier<Optional<Path>> jarPathSupplier;

public JarServiceNameResourceExtractor() {
this(MainJarPathHolder::getJarPath);
}

// visible for tests
JarServiceNameResourceExtractor(MainJarPathFinder jarPathFinder) {
this(() -> Optional.ofNullable(jarPathFinder.detectJarPath()));
}

private JarServiceNameResourceExtractor(Supplier<Optional<Path>> jarPathSupplier) {
this.jarPathSupplier = jarPathSupplier;
}

public Resource extract() {
return jarPathSupplier
.get()
.map(
jarPath -> {
String serviceName = getServiceName(jarPath);
logger.log(
FINE, "Auto-detected service name from the jar file name: {0}", serviceName);
return Resource.create(Attributes.of(ServiceAttributes.SERVICE_NAME, serviceName));
})
.orElseGet(Resource::empty);
}

private static String getServiceName(Path jarPath) {
String jarName = jarPath.getFileName().toString();
int dotIndex = jarName.lastIndexOf(".");
return dotIndex == -1 ? jarName : jarName.substring(0, dotIndex);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.resources;
package io.opentelemetry.instrumentation.resources.internal;

import java.nio.file.Files;
import java.nio.file.InvalidPathException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.resources;
package io.opentelemetry.instrumentation.resources.internal;

import java.nio.file.Path;
import java.util.Optional;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.resources.internal;

import com.google.auto.service.AutoService;
import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider;

/**
* Declarative config manifest resource provider.
*
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
* at any time.
*/
@SuppressWarnings("rawtypes")
@AutoService(ComponentProvider.class)
public class ManifestResourceComponentProvider extends ResourceComponentProvider {
public ManifestResourceComponentProvider() {
super("manifest", p -> new ManifestResourceExtractor().extract());
}
}
Loading