Resource Detectors in OpenTelemetry Java

Resource detectors automatically detect and collect information about the environment in which your application is running. This information is attached to telemetry data (traces, metrics, and logs) to provide additional context for monitoring and debugging.

OpenTelemetry Java provides several built-in resource detectors, and you can create custom detectors to gather application-specific information.

By default, OpenTelemetry Java uses basic resource detection, but you can configure additional detectors:

java
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.resources.ResourceBuilder;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;

Resource resource = ResourceBuilder.createDefault()
    .put(ResourceAttributes.SERVICE_NAME, "user-api")
    .put(ResourceAttributes.SERVICE_VERSION, "1.0.0")
    .build();

OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
    .setResource(resource)
    .buildAndRegisterGlobal();

Built-in detectors

Environment Variable Detector

OpenTelemetry Java automatically detects resource attributes from OTEL_RESOURCE_ATTRIBUTES and OTEL_SERVICE_NAME environment variables.

Environment variables:

bash
export OTEL_SERVICE_NAME="user-api"
export OTEL_RESOURCE_ATTRIBUTES="service.version=1.2.0,deployment.environment=production"

Default Resource Detection

The default resource includes several built-in detectors:

java
import io.opentelemetry.sdk.resources.Resource;

// This automatically includes:
// - Process information (PID, executable name)
// - Runtime information (JVM version, OS details)
// - Environment variables
// - System properties
Resource resource = Resource.getDefault();

Manual Service Information

Specify service information manually:

java
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;

Resource resource = Resource.getDefault()
    .merge(Resource.builder()
        .put(ResourceAttributes.SERVICE_NAME, "user-api")
        .put(ResourceAttributes.SERVICE_VERSION, "1.2.0")
        .put(ResourceAttributes.SERVICE_INSTANCE_ID, "instance-1")
        .build());

Cloud detectors

OpenTelemetry Java provides resource detectors for major cloud platforms. Since Java Agent v2.2.0, cloud resource detectors for AWS and GCP are included but disabled by default for performance reasons.

AWS Resource Detector

For AWS environments, add the AWS resource detector dependency:

xml
<dependency>
    <groupId>io.opentelemetry.contrib</groupId>
    <artifactId>opentelemetry-aws-resources</artifactId>
</dependency>
java
import io.opentelemetry.contrib.aws.resource.Ec2Resource;
import io.opentelemetry.contrib.aws.resource.EcsResource;
import io.opentelemetry.contrib.aws.resource.EksResource;

Resource resource = Resource.getDefault()
    .merge(Ec2Resource.get())
    .merge(EcsResource.get())
    .merge(EksResource.get());

When using the Java Agent, enable AWS detectors with:

bash
-Dotel.resource.providers.aws.enabled=true

GCP Resource Detector

For Google Cloud Platform environments:

xml
<dependency>
    <groupId>io.opentelemetry.contrib</groupId>
    <artifactId>opentelemetry-gcp-resources</artifactId>
</dependency>
java
import io.opentelemetry.contrib.gcp.resource.GcpResource;

Resource resource = Resource.getDefault()
    .merge(GcpResource.create());

When using the Java Agent, enable GCP detectors with:

bash
-Dotel.resource.providers.gcp.enabled=true

Custom resource detector

Create custom detectors by implementing ResourceProvider:

java
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.api.common.Attributes;

public class CustomResourceProvider implements ResourceProvider {

    @Override
    public Resource createResource(ConfigProperties config) {
        return Resource.create(
            Attributes.builder()
                .put("deployment.datacenter", getDataCenter())
                .put("application.team", "platform")
                .put("host.name", System.getProperty("hostname", "unknown"))
                .build()
        );
    }

    private String getDataCenter() {
        return System.getenv("DATACENTER") != null ?
            System.getenv("DATACENTER") : "unknown";
    }
}

Register the custom provider by creating a file META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider:

text
com.example.CustomResourceProvider

Programmatic custom resource

Add custom attributes programmatically:

java
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.api.common.Attributes;

Resource customResource = Resource.create(
    Attributes.builder()
        .put("host.name", System.getProperty("hostname", "localhost"))
        .put("process.pid", ProcessHandle.current().pid())
        .put("deployment.environment", "production")
        .put("service.namespace", "ecommerce")
        .build()
);

Resource finalResource = Resource.getDefault()
    .merge(customResource);

Resource attributes validation

Validate and debug resource attributes:

java
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.api.common.AttributeKey;

public class ResourceDebugger {

    public static void printResourceAttributes(Resource resource) {
        System.out.println("Resource attributes:");
        resource.getAttributes().forEach((key, value) -> {
            System.out.println("  " + key.getKey() + " = " + value);
        });
    }

    public static void validateService(Resource resource) {
        String serviceName = resource.getAttribute(ResourceAttributes.SERVICE_NAME);
        if (serviceName == null || serviceName.isEmpty()) {
            throw new IllegalStateException("Service name is required");
        }

        String serviceVersion = resource.getAttribute(ResourceAttributes.SERVICE_VERSION);
        if (serviceVersion == null || serviceVersion.isEmpty()) {
            System.out.println("Warning: Service version not specified");
        }
    }
}

// Usage
Resource resource = Resource.getDefault();
ResourceDebugger.printResourceAttributes(resource);
ResourceDebugger.validateService(resource);

OpenTelemetry APM

Uptrace is a OpenTelemetry backend that supports distributed tracing, metrics, and logs. You can use it to monitor applications and troubleshoot issues.

Uptrace comes with an intuitive query builder, rich dashboards, alerting rules with notifications, and integrations for most languages and frameworks.

Uptrace can process billions of spans and metrics on a single server and allows you to monitor your applications at 10x lower cost.

In just a few minutes, you can try Uptrace by visiting the cloud demo (no login required) or running it locally with Docker. The source code is available on GitHub.

What's next?