Sylvain Juge

Automatic cloud resource attributes with OpenTelemetry Java

Capturing cloud resource attributes allow to describe application cloud deployment details. In this article we describe three distinct ways to enable them for Java applications using OpenTelemetry

Automatic cloud resource attributes with OpenTelemetry Java

With OpenTelemetry, the observed entities (application, services, processes, …) are described through resource attributes. The definitions and the values of those attributes are defined in the semantic conventions.
In practice, for a typical java application running in a cloud environment like Google Cloud Platform (GCP), Amazon Web Services (AWS) or Azure, it means capturing the name of the cloud provider, the cloud service name or availability zone in addition to per-provider attributes. Those attributes are then used to describe and qualify the observability signals (logs, traces, metrics), defined by semantic conventions in the cloud resource attributes section.

When using the OpenTelemetry Java SDK or the OpenTelemetry instrumentation agent, those attributes are not automatically captured by default. In this article we will show you first how to enable them with the SDK, then using the instrumentation agent and then we will show you how using the Elastic OpenTelemetry Distribution makes it even easier.

OpenTelemetry Java SDK

The OpenTelemetry Java SDK does not capture any cloud resource attributes, however it provides a pluggable service provider interface to register resource attributes providers and application developers have to provide the implementations.

Implementations for GCP and AWS are already included in the OpenTelemetry Java Contrib repo, so if you are using one of those cloud providers then it's mostly a matter of adding those providers to your application dependencies. Thanks to autoconfiguration those should be automatically included and enabled once they are added to the application classpath. The SDK documentation provides all the details to add and configure those in your application.

If you are using a cloud provider for which no such implementation is available, then you still have the option to provide your own which is a straightforward implementation of the ResourceProvider SPI (Service Provider Interface). In order to keep things consistent, you will have to rely on the existing cloud semantic conventions.

For example here is an example of a simple cloud resource attributes provider for a fictitious cloud provider named "potatoes".

package potatoes;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.semconv.incubating.CloudIncubatingAttributes;

public class PotatoesResourceProvider implements ResourceProvider {

@Override
public Resource createResource(ConfigProperties configProperties) {
   return Resource.create(Attributes.of(
           CloudIncubatingAttributes.CLOUD_PROVIDER, "potatoes",
           CloudIncubatingAttributes.CLOUD_PLATFORM, "french-fries",
           CloudIncubatingAttributes.CLOUD_REGION, "garden"
           ));
  }
}

OpenTelemetry Java instrumentation

The OpenTelemetry Java Instrumentation provides a java agent that instruments the application at runtime automatically for an extensive set of frameworks and libraries (see supported technologies).

Using instrumentation means that the application bytecode and the embedded libraries are modified automatically to make them behave as if explicit modifications were made in their source code to call the OpenTelemetry SDK in order to create traces, spans and metrics.

When an application is deployed with the OpenTelemetry instrumentation agent, the cloud resource attributes for GCP and AWS are included but not enabled by default since version 2.2.0. You can enable them through configuration by setting the following properties:

  • For AWS:

    otel.resource.providers.aws.enabled=true

  • For GCP:

    otel.resource.providers.gcp.enabled=true

Elastic OpenTelemetry Java Distribution

The Elastic OpenTelemetry Java distribution relies on the OpenTelemetry Java instrumentation which we often refer to as the Vanilla OpenTelemetry, and it thus inherits all of its features.

One major difference though is that the resource attributes providers for GCP and AWS are included and enabled by default to provide a better onboarding experience without extra configuration.

The minor cost to this is that it might make the application startup slightly slower due to having to call an HTTP(S) endpoint. This overhead is usually negligible compared to application startup but can become significant for some setups.

In order to reduce the startup overhead, or when the cloud provider is known in advance, you can selectively disable unused provider implementations through configuration:

  • For AWS:

    otel.resource.providers.aws.enabled=false

  • For GCP:

    otel.resource.providers.gcp.enabled=false

Conclusion

With this blogpost we have introduced what OpenTelemetry cloud resource attributes are and how they can be used and configured into application deployments using either OpenTelemetry SDK/API and Instrumentation agents.

When using the Elastic OpenTelemetry Java distribution, those resource providers are automatically provided and enabled for an easy and simple onboarding experience.

Another very interesting aspect of the cloud resource attribute providers available in the opentelemetry-java-contrib repository is that they are maintained by their respective vendors (Google and Amazon). For the end-user it means those implementations should be quite well tested and be robust to changes in the underlying infrastructure. For solution vendors like Elastic, it means we don't have to re-implement and reverse-engineer the infrastructure details of every cloud provider, hence proving that investing in those common components is a net win for the broader OpenTelemetry community.

Share this article