Search code examples
javatracespring-cloud-sleuthazure-monitoringopen-telemetry

Exporting Spring Cloud Sleuth spans automatically using Azure Monitor OpenTelemetry Exporter client library for Java


I'm trying to use Azure Monitor OpenTelemetry Exporter client library for Java to export all traces/spans from Spring Cloud Sleuth to Azure Monitor. This integration seems to only work with the newest version of Spring Cloud Sleuth after the recent dependency version updates.

However instead of using azureMonitorExporter.export(spanData) manually, I would like to export all traces/spans automatically for the whole application by just adding a configuration for Azure exporter. This could then easily be added to a new project.

I don't have much experience using Spring/Sleuth/OpenTelemetry, but AzureMonitorExporter implements SpanExporter, so I thought one option could be to create a configuration class that contains the following.

@Bean
public SpanExporter exporter() {
    return new AzureMonitorExporterBuilder()
        .instrumentationKey("{KEY}")
        .buildExporter();
};

And then it could be used in the main class using:

@Autowired
SpanExporter exporter;

However I'm not sure if this is the right way or how to continue from here to actually get the exporter to start exporting traces/spans automatically to Azure monitor.

My pom.xml looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.2-SNAPSHOT</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>trace-demo-5-updated</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>trace-demo-5-updated</name>
<description>Demo project for Spring Boot</description>

<properties>
    <java.version>11</java.version>
    <spring-cloud.version>2020.0.0-SNAPSHOT</spring-cloud.version>
</properties>

<dependencies>
    <!-- Sleuth with Brave tracer implementation -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-sleuth</artifactId>

    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    
    <dependency>
      <groupId>com.azure</groupId>
      <artifactId>opentelemetry-exporters-azuremonitor</artifactId>
      <version>1.0.0-beta.1</version>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web-services</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-sleuth-otel</artifactId>
        <version>3.0.0-M6</version>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

<repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/milestone</url>
    </repository>
    <repository>
        <id>spring-snapshots</id>
        <name>Spring Snapshots</name>
        <url>https://repo.spring.io/snapshot</url>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
    </repository>
</repositories>
<pluginRepositories>
    <pluginRepository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/milestone</url>
    </pluginRepository>
    <pluginRepository>
        <id>spring-snapshots</id>
        <name>Spring Snapshots</name>
        <url>https://repo.spring.io/snapshot</url>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
    </pluginRepository>
</pluginRepositories>

Solution

  • Update (2020-01-26):

    With today's release of Spring Cloud Sleuth OTel (spring-cloud-sleuth-otel:1.0.0-M3) and The OTel upgrade in the Azure SDK, your original issue should disappear.

    Original Answer

    (TL;DR: last paragraph)

    The Sleuth 3.0 Migration Guide can help you out a lot here. Sleuth supports two tracing systems Brave (default) and OpenTelemetry (incubator).

    In order to use OpenTelemetry, you need to remove Brave (just exclude spring-cloud-sleuth-brave) and add OpenTelemetry (spring-cloud-sleuth-otel-autoconfigure with spring-cloud-sleuth-otel-dependencies). See the docs I linked.

    After you do this, your SpanExporter should be used, here's a pom.xml I created based on yours. Btw, adding a sample project (e.g.: in a GitHub repo) could help a lot for everyone who is trying to help so that they don't need to create one themselves.

    Unfortunately, this still won't work, you will still face with this exception at startup:
    Caused by: java.lang.ClassNotFoundException: io.opentelemetry.common.AttributeValue

    This is because opentelemetry-exporters-azuremonitor:1.0.0-beta.1 depends on OpenTelemetry 0.8.0 while the latest spring-cloud-sleuth-otel (1.0.0-M2, we released it today) is using the latest OpenTelemetry (0.13.1). Also, OpenTelemetry introduced breaking changes between minor versions, e.g.: the AttributeValue class was removed in OpenTelemetry 0.9.1.

    Sleuth supports OpenTelemetry since Sleuth 3.0.0-M5, The OpenTelemetry version was 0.10 back then so there is no Sleuth version available that would support an OpenTelemetry version as old as opentelemetry-exporters-azuremonitor:1.0.0-beta.1 needs.

    So the solution would be fixing your pom.xml and opentelemetry-exporters-azuremonitor supporting the latest OpenTelemetry.