{"id":1933,"date":"2024-06-19T16:03:18","date_gmt":"2024-06-19T16:03:18","guid":{"rendered":"https:\/\/www.w3computing.com\/articles\/?p=1933"},"modified":"2024-06-19T16:03:24","modified_gmt":"2024-06-19T16:03:24","slug":"how-to-implement-distributed-tracing-in-java-with-opentelemetry","status":"publish","type":"post","link":"https:\/\/www.w3computing.com\/articles\/how-to-implement-distributed-tracing-in-java-with-opentelemetry\/","title":{"rendered":"How to Implement Distributed Tracing in Java with OpenTelemetry"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Distributed tracing is an essential component in the realm of microservices and distributed systems. It allows developers to monitor and observe the flow of requests across different services, providing insights into the performance and behavior of the system. OpenTelemetry is an open-source observability framework that provides tools, APIs, and SDKs for collecting and exporting telemetry data (traces, metrics, and logs) from applications.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In this tutorial, we will delve into how to implement distributed tracing in Java using OpenTelemetry. This guide is designed for developers with intermediate to advanced knowledge of Java and experience in working with microservices or distributed systems.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Before we begin, ensure you have the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A working knowledge of Java.<\/li>\n\n\n\n<li>Familiarity with Maven or Gradle build tools.<\/li>\n\n\n\n<li>Basic understanding of microservices architecture.<\/li>\n\n\n\n<li>An IDE or text editor set up for Java development.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Understanding Distributed Tracing<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Distributed tracing is the method of tracking requests as they flow through various services in a distributed system. Each step of the request is recorded, providing a comprehensive view of the request lifecycle. Key concepts include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Trace<\/strong>: Represents the entire journey of a request from start to finish.<\/li>\n\n\n\n<li><strong>Span<\/strong>: A single unit of work in a trace. It has a start time and a duration.<\/li>\n\n\n\n<li><strong>Context Propagation<\/strong>: Passing trace information across service boundaries.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Introduction to OpenTelemetry<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">OpenTelemetry is a collection of tools, APIs, and SDKs used to instrument, generate, collect, and export telemetry data. It supports multiple programming languages and provides interoperability with various observability backends.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Key Components<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>API<\/strong>: Defines the interfaces for creating and manipulating telemetry data.<\/li>\n\n\n\n<li><strong>SDK<\/strong>: Provides default implementations of the API, including exporters.<\/li>\n\n\n\n<li><strong>Exporters<\/strong>: Send collected data to backend systems like Jaeger, Zipkin, or Prometheus.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Setting Up the Project<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">We will start by creating a new Java project. You can use either Maven or Gradle as your build tool. For this tutorial, we will use Maven.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Creating a Maven Project<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Create a new directory for your project and navigate to it:<\/li>\n<\/ol>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"Shell Session\" data-shcb-language-slug=\"shell\"><span><code class=\"hljs language-shell\">   mkdir opentelemetry-tutorial\n   cd opentelemetry-tutorial<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Shell Session<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">shell<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<ol class=\"wp-block-list\" start=\"2\">\n<li>Generate a new Maven project:<\/li>\n<\/ol>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Shell Session\" data-shcb-language-slug=\"shell\"><span><code class=\"hljs language-shell\">   mvn archetype:generate -DgroupId=com.example -DartifactId=opentelemetry-tutorial -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false\n   cd opentelemetry-tutorial<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Shell Session<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">shell<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<ol class=\"wp-block-list\" start=\"3\">\n<li>Open the <code>pom.xml<\/code> file and add the necessary dependencies for OpenTelemetry:<\/li>\n<\/ol>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">project<\/span> <span class=\"hljs-attr\">xmlns<\/span>=<span class=\"hljs-string\">\"http:\/\/maven.apache.org\/POM\/4.0.0\"<\/span> <span class=\"hljs-attr\">xmlns:xsi<\/span>=<span class=\"hljs-string\">\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"<\/span>\n    <span class=\"hljs-attr\">xsi:schemaLocation<\/span>=<span class=\"hljs-string\">\"http:\/\/maven.apache.org\/POM\/4.0.0 http:\/\/maven.apache.org\/xsd\/maven-4.0.0.xsd\"<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">modelVersion<\/span>&gt;<\/span>4.0.0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">modelVersion<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>com.example<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>opentelemetry-tutorial<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">version<\/span>&gt;<\/span>1.0-SNAPSHOT<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">version<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependencies<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>io.opentelemetry<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>opentelemetry-api<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">version<\/span>&gt;<\/span>1.10.0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">version<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>io.opentelemetry<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>opentelemetry-sdk<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">version<\/span>&gt;<\/span>1.10.0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">version<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>io.opentelemetry<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>opentelemetry-exporter-jaeger<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">version<\/span>&gt;<\/span>1.10.0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">version<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>io.opentelemetry<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>opentelemetry-context<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">version<\/span>&gt;<\/span>1.10.0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">version<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>io.opentelemetry<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>opentelemetry-extension-trace-propagators<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">version<\/span>&gt;<\/span>1.10.0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">version<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependencies<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">build<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">plugins<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">plugin<\/span>&gt;<\/span>\n                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>org.apache.maven.plugins<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>\n                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>maven-compiler-plugin<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>\n                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">version<\/span>&gt;<\/span>3.8.1<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">version<\/span>&gt;<\/span>\n                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">configuration<\/span>&gt;<\/span>\n                    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">source<\/span>&gt;<\/span>11<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">source<\/span>&gt;<\/span>\n                    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">target<\/span>&gt;<\/span>11<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">target<\/span>&gt;<\/span>\n                <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">configuration<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">plugin<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">plugins<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">build<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">project<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Integrating OpenTelemetry with a Java Application<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Adding Dependencies<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The dependencies for OpenTelemetry include the API, SDK, context propagation, and an exporter for sending traces to Jaeger. We have already added these dependencies in the <code>pom.xml<\/code> file.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Initializing OpenTelemetry SDK<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Next, we need to initialize the OpenTelemetry SDK in our application. Create a class named <code>OpenTelemetryConfig<\/code> to handle this configuration.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">package<\/span> com.example;\n\n<span class=\"hljs-keyword\">import<\/span> io.opentelemetry.api.GlobalOpenTelemetry;\n<span class=\"hljs-keyword\">import<\/span> io.opentelemetry.api.OpenTelemetry;\n<span class=\"hljs-keyword\">import<\/span> io.opentelemetry.api.trace.Tracer;\n<span class=\"hljs-keyword\">import<\/span> io.opentelemetry.exporter.jaeger.JaegerGrpcSpanExporter;\n<span class=\"hljs-keyword\">import<\/span> io.opentelemetry.sdk.OpenTelemetrySdk;\n<span class=\"hljs-keyword\">import<\/span> io.opentelemetry.sdk.resources.Resource;\n<span class=\"hljs-keyword\">import<\/span> io.opentelemetry.sdk.trace.SdkTracerProvider;\n<span class=\"hljs-keyword\">import<\/span> io.opentelemetry.sdk.trace.export.BatchSpanProcessor;\n<span class=\"hljs-keyword\">import<\/span> io.opentelemetry.semconv.resource.attributes.ResourceAttributes;\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">OpenTelemetryConfig<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> String SERVICE_NAME = <span class=\"hljs-string\">\"opentelemetry-tutorial\"<\/span>;\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> OpenTelemetry <span class=\"hljs-title\">initOpenTelemetry<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n        <span class=\"hljs-comment\">\/\/ Create a Jaeger exporter<\/span>\n        JaegerGrpcSpanExporter jaegerExporter = JaegerGrpcSpanExporter.builder()\n                .setEndpoint(<span class=\"hljs-string\">\"http:\/\/localhost:14250\"<\/span>)\n                .build();\n\n        <span class=\"hljs-comment\">\/\/ Create a resource to identify this service<\/span>\n        Resource serviceNameResource = Resource.create(\n                ResourceAttributes.SERVICE_NAME, SERVICE_NAME);\n\n        <span class=\"hljs-comment\">\/\/ Create a tracer provider<\/span>\n        SdkTracerProvider tracerProvider = SdkTracerProvider.builder()\n                .addSpanProcessor(BatchSpanProcessor.builder(jaegerExporter).build())\n                .setResource(serviceNameResource)\n                .build();\n\n        <span class=\"hljs-comment\">\/\/ Initialize OpenTelemetry SDK<\/span>\n        OpenTelemetrySdk openTelemetrySdk = OpenTelemetrySdk.builder()\n                .setTracerProvider(tracerProvider)\n                .buildAndRegisterGlobal();\n\n        <span class=\"hljs-keyword\">return<\/span> openTelemetrySdk;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> Tracer <span class=\"hljs-title\">getTracer<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n        <span class=\"hljs-keyword\">return<\/span> GlobalOpenTelemetry.getTracer(SERVICE_NAME);\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Creating and Exporting Spans<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Spans represent individual units of work. Let&#8217;s create a simple application that uses spans.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Create a class named <code>HelloService<\/code>:<\/li>\n<\/ol>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">package<\/span> com.example;\n\n<span class=\"hljs-keyword\">import<\/span> io.opentelemetry.api.trace.Span;\n<span class=\"hljs-keyword\">import<\/span> io.opentelemetry.api.trace.Tracer;\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">HelloService<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> Tracer tracer;\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">HelloService<\/span><span class=\"hljs-params\">(Tracer tracer)<\/span> <\/span>{\n        <span class=\"hljs-keyword\">this<\/span>.tracer = tracer;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">sayHello<\/span><span class=\"hljs-params\">(String name)<\/span> <\/span>{\n        Span span = tracer.spanBuilder(<span class=\"hljs-string\">\"sayHello\"<\/span>).startSpan();\n        span.addEvent(<span class=\"hljs-string\">\"Saying hello to \"<\/span> + name);\n        System.out.println(<span class=\"hljs-string\">\"Hello, \"<\/span> + name);\n        span.end();\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<ol class=\"wp-block-list\" start=\"2\">\n<li>Create a <code>Main<\/code> class to run the application:<\/li>\n<\/ol>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">package<\/span> com.example;\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Main<\/span> <\/span>{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">(String&#91;] args)<\/span> <\/span>{\n        OpenTelemetryConfig.initOpenTelemetry();\n        HelloService helloService = <span class=\"hljs-keyword\">new<\/span> HelloService(OpenTelemetryConfig.getTracer());\n        helloService.sayHello(<span class=\"hljs-string\">\"World\"<\/span>);\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Context Propagation<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Context propagation ensures that trace information is passed across service boundaries. OpenTelemetry provides several context propagation mechanisms, including W3C Trace Context and B3 Propagation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To demonstrate context propagation, we&#8217;ll simulate a simple HTTP call between two services using the <code>okhttp<\/code> library.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Add the <code>okhttp<\/code> dependency to your <code>pom.xml<\/code> file:<\/li>\n<\/ol>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>com.squareup.okhttp3<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>okhttp<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">version<\/span>&gt;<\/span>4.9.3<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">version<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependency<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<ol class=\"wp-block-list\" start=\"2\">\n<li>Create a <code>HttpService<\/code> class to make HTTP requests:<\/li>\n<\/ol>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">package<\/span> com.example;\n\n<span class=\"hljs-keyword\">import<\/span> io.opentelemetry.api.trace.Span;\n<span class=\"hljs-keyword\">import<\/span> io.opentelemetry.api.trace.Tracer;\n<span class=\"hljs-keyword\">import<\/span> io.opentelemetry.context.Context;\n<span class=\"hljs-keyword\">import<\/span> io.opentelemetry.context.Scope;\n<span class=\"hljs-keyword\">import<\/span> io.opentelemetry.extension.trace.propagation.TraceMultiPropagator;\n<span class=\"hljs-keyword\">import<\/span> io.opentelemetry.extension.trace.propagation.W3CTraceContextPropagator\n\n;\n<span class=\"hljs-keyword\">import<\/span> okhttp3.OkHttpClient;\n<span class=\"hljs-keyword\">import<\/span> okhttp3.Request;\n<span class=\"hljs-keyword\">import<\/span> okhttp3.Response;\n\n<span class=\"hljs-keyword\">import<\/span> java.io.IOException;\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">HttpService<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> Tracer tracer;\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> OkHttpClient client;\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">HttpService<\/span><span class=\"hljs-params\">(Tracer tracer)<\/span> <\/span>{\n        <span class=\"hljs-keyword\">this<\/span>.tracer = tracer;\n        <span class=\"hljs-keyword\">this<\/span>.client = <span class=\"hljs-keyword\">new<\/span> OkHttpClient();\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">makeRequest<\/span><span class=\"hljs-params\">(String url)<\/span> <span class=\"hljs-keyword\">throws<\/span> IOException <\/span>{\n        Span span = tracer.spanBuilder(<span class=\"hljs-string\">\"makeRequest\"<\/span>).startSpan();\n        <span class=\"hljs-keyword\">try<\/span> (Scope scope = span.makeCurrent()) {\n            span.addEvent(<span class=\"hljs-string\">\"Making request to \"<\/span> + url);\n\n            Request request = <span class=\"hljs-keyword\">new<\/span> Request.Builder()\n                    .url(url)\n                    .build();\n\n            Response response = client.newCall(request).execute();\n            span.addEvent(<span class=\"hljs-string\">\"Received response with status code: \"<\/span> + response.code());\n        } <span class=\"hljs-keyword\">finally<\/span> {\n            span.end();\n        }\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<ol class=\"wp-block-list\" start=\"3\">\n<li>Modify the <code>Main<\/code> class to use the <code>HttpService<\/code>:<\/li>\n<\/ol>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">package<\/span> com.example;\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Main<\/span> <\/span>{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">(String&#91;] args)<\/span> <span class=\"hljs-keyword\">throws<\/span> IOException <\/span>{\n        OpenTelemetryConfig.initOpenTelemetry();\n        HelloService helloService = <span class=\"hljs-keyword\">new<\/span> HelloService(OpenTelemetryConfig.getTracer());\n        helloService.sayHello(<span class=\"hljs-string\">\"World\"<\/span>);\n\n        HttpService httpService = <span class=\"hljs-keyword\">new<\/span> HttpService(OpenTelemetryConfig.getTracer());\n        httpService.makeRequest(<span class=\"hljs-string\">\"http:\/\/example.com\"<\/span>);\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Using OpenTelemetry with Spring Boot<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Spring Boot simplifies the process of setting up and running a microservice. Integrating OpenTelemetry with Spring Boot involves adding the necessary dependencies and configuring the tracing components.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Create a new Spring Boot project using Spring Initializr (https:\/\/start.spring.io\/) with the following dependencies:<\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Spring Web<\/li>\n\n\n\n<li>Spring Boot Actuator<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Add the OpenTelemetry dependencies to your <code>pom.xml<\/code>:<\/li>\n<\/ol>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>io.opentelemetry<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>opentelemetry-api<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">version<\/span>&gt;<\/span>1.10.0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">version<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>io.opentelemetry<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>opentelemetry-sdk<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">version<\/span>&gt;<\/span>1.10.0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">version<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>io.opentelemetry<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>opentelemetry-exporter-jaeger<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">version<\/span>&gt;<\/span>1.10.0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">version<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>io.opentelemetry<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>opentelemetry-extension-trace-propagators<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">version<\/span>&gt;<\/span>1.10.0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">version<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>io.opentelemetry.instrumentation<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>opentelemetry-spring-boot-autoconfigure<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">version<\/span>&gt;<\/span>1.10.0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">version<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependency<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<ol class=\"wp-block-list\" start=\"3\">\n<li>Configure OpenTelemetry in your Spring Boot application. Create a <code>OpenTelemetryConfig<\/code> class:<\/li>\n<\/ol>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">package<\/span> com.example;\n\n<span class=\"hljs-keyword\">import<\/span> io.opentelemetry.api.GlobalOpenTelemetry;\n<span class=\"hljs-keyword\">import<\/span> io.opentelemetry.api.OpenTelemetry;\n<span class=\"hljs-keyword\">import<\/span> io.opentelemetry.exporter.jaeger.JaegerGrpcSpanExporter;\n<span class=\"hljs-keyword\">import<\/span> io.opentelemetry.sdk.OpenTelemetrySdk;\n<span class=\"hljs-keyword\">import<\/span> io.opentelemetry.sdk.resources.Resource;\n<span class=\"hljs-keyword\">import<\/span> io.opentelemetry.sdk.trace.SdkTracerProvider;\n<span class=\"hljs-keyword\">import<\/span> io.opentelemetry.sdk.trace.export.BatchSpanProcessor;\n<span class=\"hljs-keyword\">import<\/span> io.opentelemetry.semconv.resource.attributes.ResourceAttributes;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.context.annotation.Bean;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.context.annotation.Configuration;\n\n<span class=\"hljs-meta\">@Configuration<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">OpenTelemetryConfig<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> String SERVICE_NAME = <span class=\"hljs-string\">\"spring-boot-opentelemetry\"<\/span>;\n\n    <span class=\"hljs-meta\">@Bean<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> OpenTelemetry <span class=\"hljs-title\">openTelemetry<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n        JaegerGrpcSpanExporter jaegerExporter = JaegerGrpcSpanExporter.builder()\n                .setEndpoint(<span class=\"hljs-string\">\"http:\/\/localhost:14250\"<\/span>)\n                .build();\n\n        Resource resource = Resource.create(\n                ResourceAttributes.SERVICE_NAME, SERVICE_NAME);\n\n        SdkTracerProvider tracerProvider = SdkTracerProvider.builder()\n                .addSpanProcessor(BatchSpanProcessor.builder(jaegerExporter).build())\n                .setResource(resource)\n                .build();\n\n        OpenTelemetrySdk openTelemetrySdk = OpenTelemetrySdk.builder()\n                .setTracerProvider(tracerProvider)\n                .buildAndRegisterGlobal();\n\n        <span class=\"hljs-keyword\">return<\/span> openTelemetrySdk;\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<ol class=\"wp-block-list\" start=\"4\">\n<li>Create a simple controller to demonstrate tracing:<\/li>\n<\/ol>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">package<\/span> com.example;\n\n<span class=\"hljs-keyword\">import<\/span> org.springframework.web.bind.annotation.GetMapping;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.web.bind.annotation.RestController;\n<span class=\"hljs-keyword\">import<\/span> io.opentelemetry.api.trace.Span;\n<span class=\"hljs-keyword\">import<\/span> io.opentelemetry.api.trace.Tracer;\n\n<span class=\"hljs-meta\">@RestController<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">HelloController<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> Tracer tracer;\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">HelloController<\/span><span class=\"hljs-params\">(Tracer tracer)<\/span> <\/span>{\n        <span class=\"hljs-keyword\">this<\/span>.tracer = tracer;\n    }\n\n    <span class=\"hljs-meta\">@GetMapping<\/span>(<span class=\"hljs-string\">\"\/hello\"<\/span>)\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> String <span class=\"hljs-title\">hello<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n        Span span = tracer.spanBuilder(<span class=\"hljs-string\">\"hello\"<\/span>).startSpan();\n        span.addEvent(<span class=\"hljs-string\">\"Handling \/hello request\"<\/span>);\n        String message = <span class=\"hljs-string\">\"Hello, World!\"<\/span>;\n        span.addEvent(<span class=\"hljs-string\">\"Returning response: \"<\/span> + message);\n        span.end();\n        <span class=\"hljs-keyword\">return<\/span> message;\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Exporting Traces to a Backend<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To view traces, we need to export them to a tracing backend like Jaeger. We have already configured Jaeger exporter in our <code>OpenTelemetryConfig<\/code> classes.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Running Jaeger<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">To run Jaeger locally, use the following Docker command:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"Shell Session\" data-shcb-language-slug=\"shell\"><span><code class=\"hljs language-shell\">docker run -d --name jaeger \\\n  -e COLLECTOR_ZIPKIN_HTTP_PORT=9411 \\\n  -p 5775:5775\/udp \\\n  -p 6831:6831\/udp \\\n  -p 6832:6832\/udp \\\n  -p 5778:5778 \\\n  -p 16686:16686 \\\n  -p 14268:14268 \\\n  -p 14250:14250 \\\n  -p 9411:9411 \\\n  jaegertracing\/all-in-one:1.25<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Shell Session<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">shell<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Access the Jaeger UI at <code>http:\/\/localhost:16686<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Visualizing Traces with Jaeger<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Once Jaeger is running, you can start your Java application and make some requests. Open the Jaeger UI and search for traces. You should see traces from your application with detailed information about each span.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Advanced Topics<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Custom Instrumentation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">OpenTelemetry allows you to instrument your code to capture specific events or metrics.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">Span span = tracer.spanBuilder(<span class=\"hljs-string\">\"custom-operation\"<\/span>).startSpan();\n<span class=\"hljs-keyword\">try<\/span> (Scope scope = span.makeCurrent()) {\n    <span class=\"hljs-comment\">\/\/ Your custom logic here<\/span>\n    span.addEvent(<span class=\"hljs-string\">\"Custom event\"<\/span>);\n} <span class=\"hljs-keyword\">finally<\/span> {\n    span.end();\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Sampling<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Sampling controls the amount of telemetry data collected. By default, OpenTelemetry samples all traces. You can configure a different sampling strategy:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">SdkTracerProvider tracerProvider = SdkTracerProvider.builder()\n    .setSampler(Sampler.traceIdRatioBased(<span class=\"hljs-number\">0.5<\/span>)) <span class=\"hljs-comment\">\/\/ Sample 50% of traces<\/span>\n    .build();<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Resource Attributes<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Resource attributes provide additional context about your service. You can add custom resource attributes:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">Resource resource = Resource.builder()\n    .put(ResourceAttributes.SERVICE_NAME, <span class=\"hljs-string\">\"my-service\"<\/span>)\n    .put(ResourceAttributes.SERVICE_INSTANCE_ID, <span class=\"hljs-string\">\"instance-1\"<\/span>)\n    .build();<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Best Practices<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Instrument Key Operations<\/strong>: Focus on instrumenting critical paths and key operations.<\/li>\n\n\n\n<li><strong>Use Context Propagation<\/strong>: Ensure context is propagated across service boundaries for end-to-end tracing.<\/li>\n\n\n\n<li><strong>Configure Sampling<\/strong>: Adjust sampling rates to balance performance and data collection.<\/li>\n\n\n\n<li><strong>Leverage Exporters<\/strong>: Use appropriate exporters to send telemetry data to observability backends.<\/li>\n\n\n\n<li><strong>Monitor Performance<\/strong>: Keep an eye on the performance impact of instrumentation and adjust as necessary.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Implementing distributed tracing in Java with OpenTelemetry provides deep insights into the behavior and performance of your distributed system. By following this tutorial, you have learned how to set up OpenTelemetry, create and export spans, propagate context, and visualize traces using Jaeger. These techniques will help you monitor and debug your applications more effectively, ensuring a more resilient and performant system. Remember, observability is an ongoing process. Continuously refine your instrumentation and tracing strategies to adapt to the evolving needs of your system.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Distributed tracing is an essential component in the realm of microservices and distributed systems. It allows developers to monitor and observe the flow of requests across different services, providing insights into the performance and behavior of the system. OpenTelemetry is an open-source observability framework that provides tools, APIs, and SDKs for collecting and exporting [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_genesis_hide_title":false,"_genesis_hide_breadcrumbs":false,"_genesis_hide_singular_image":false,"_genesis_hide_footer_widgets":false,"_genesis_custom_body_class":"","_genesis_custom_post_class":"","_genesis_layout":"","_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[5,4],"tags":[],"class_list":["post-1933","post","type-post","status-publish","format-standard","category-java","category-programming-languages","entry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>How to Implement Distributed Tracing in Java with OpenTelemetry<\/title>\n<meta name=\"description\" content=\"Distributed tracing is an essential component in the realm of microservices and distributed systems. It allows developers to monitor\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.w3computing.com\/articles\/how-to-implement-distributed-tracing-in-java-with-opentelemetry\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to Implement Distributed Tracing in Java with OpenTelemetry\" \/>\n<meta property=\"og:description\" content=\"Distributed tracing is an essential component in the realm of microservices and distributed systems. It allows developers to monitor\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.w3computing.com\/articles\/how-to-implement-distributed-tracing-in-java-with-opentelemetry\/\" \/>\n<meta property=\"article:published_time\" content=\"2024-06-19T16:03:18+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-06-19T16:03:24+00:00\" \/>\n<meta name=\"author\" content=\"w3compadmin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"w3compadmin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"TechArticle\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/how-to-implement-distributed-tracing-in-java-with-opentelemetry\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/how-to-implement-distributed-tracing-in-java-with-opentelemetry\\\/\"},\"author\":{\"name\":\"w3compadmin\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\"},\"headline\":\"How to Implement Distributed Tracing in Java with OpenTelemetry\",\"datePublished\":\"2024-06-19T16:03:18+00:00\",\"dateModified\":\"2024-06-19T16:03:24+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/how-to-implement-distributed-tracing-in-java-with-opentelemetry\\\/\"},\"wordCount\":862,\"articleSection\":[\"Java\",\"Programming Languages\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/how-to-implement-distributed-tracing-in-java-with-opentelemetry\\\/\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/how-to-implement-distributed-tracing-in-java-with-opentelemetry\\\/\",\"name\":\"How to Implement Distributed Tracing in Java with OpenTelemetry\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#website\"},\"datePublished\":\"2024-06-19T16:03:18+00:00\",\"dateModified\":\"2024-06-19T16:03:24+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\"},\"description\":\"Distributed tracing is an essential component in the realm of microservices and distributed systems. It allows developers to monitor\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/how-to-implement-distributed-tracing-in-java-with-opentelemetry\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/how-to-implement-distributed-tracing-in-java-with-opentelemetry\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/how-to-implement-distributed-tracing-in-java-with-opentelemetry\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Articles Home\",\"item\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Programming Languages\",\"item\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/programming-languages\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"How to Implement Distributed Tracing in Java with OpenTelemetry\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#website\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/\",\"name\":\"Developer Articles Hub\",\"description\":\"\",\"alternateName\":\"Developer Articles\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\",\"name\":\"w3compadmin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266\",\"contentUrl\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266\",\"caption\":\"w3compadmin\"},\"sameAs\":[\"http:\\\/\\\/w3computing.com\\\/articles\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"How to Implement Distributed Tracing in Java with OpenTelemetry","description":"Distributed tracing is an essential component in the realm of microservices and distributed systems. It allows developers to monitor","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.w3computing.com\/articles\/how-to-implement-distributed-tracing-in-java-with-opentelemetry\/","og_locale":"en_US","og_type":"article","og_title":"How to Implement Distributed Tracing in Java with OpenTelemetry","og_description":"Distributed tracing is an essential component in the realm of microservices and distributed systems. It allows developers to monitor","og_url":"https:\/\/www.w3computing.com\/articles\/how-to-implement-distributed-tracing-in-java-with-opentelemetry\/","article_published_time":"2024-06-19T16:03:18+00:00","article_modified_time":"2024-06-19T16:03:24+00:00","author":"w3compadmin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"w3compadmin","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"TechArticle","@id":"https:\/\/www.w3computing.com\/articles\/how-to-implement-distributed-tracing-in-java-with-opentelemetry\/#article","isPartOf":{"@id":"https:\/\/www.w3computing.com\/articles\/how-to-implement-distributed-tracing-in-java-with-opentelemetry\/"},"author":{"name":"w3compadmin","@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561"},"headline":"How to Implement Distributed Tracing in Java with OpenTelemetry","datePublished":"2024-06-19T16:03:18+00:00","dateModified":"2024-06-19T16:03:24+00:00","mainEntityOfPage":{"@id":"https:\/\/www.w3computing.com\/articles\/how-to-implement-distributed-tracing-in-java-with-opentelemetry\/"},"wordCount":862,"articleSection":["Java","Programming Languages"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.w3computing.com\/articles\/how-to-implement-distributed-tracing-in-java-with-opentelemetry\/","url":"https:\/\/www.w3computing.com\/articles\/how-to-implement-distributed-tracing-in-java-with-opentelemetry\/","name":"How to Implement Distributed Tracing in Java with OpenTelemetry","isPartOf":{"@id":"https:\/\/www.w3computing.com\/articles\/#website"},"datePublished":"2024-06-19T16:03:18+00:00","dateModified":"2024-06-19T16:03:24+00:00","author":{"@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561"},"description":"Distributed tracing is an essential component in the realm of microservices and distributed systems. It allows developers to monitor","breadcrumb":{"@id":"https:\/\/www.w3computing.com\/articles\/how-to-implement-distributed-tracing-in-java-with-opentelemetry\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.w3computing.com\/articles\/how-to-implement-distributed-tracing-in-java-with-opentelemetry\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.w3computing.com\/articles\/how-to-implement-distributed-tracing-in-java-with-opentelemetry\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Articles Home","item":"https:\/\/www.w3computing.com\/articles\/"},{"@type":"ListItem","position":2,"name":"Programming Languages","item":"https:\/\/www.w3computing.com\/articles\/programming-languages\/"},{"@type":"ListItem","position":3,"name":"How to Implement Distributed Tracing in Java with OpenTelemetry"}]},{"@type":"WebSite","@id":"https:\/\/www.w3computing.com\/articles\/#website","url":"https:\/\/www.w3computing.com\/articles\/","name":"Developer Articles Hub","description":"","alternateName":"Developer Articles","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.w3computing.com\/articles\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561","name":"w3compadmin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266","url":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266","contentUrl":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266","caption":"w3compadmin"},"sameAs":["http:\/\/w3computing.com\/articles"]}]}},"featured_image_src":null,"featured_image_src_square":null,"author_info":{"display_name":"w3compadmin","author_link":"https:\/\/www.w3computing.com\/articles\/author\/w3compadmin\/"},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/1933","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/comments?post=1933"}],"version-history":[{"count":2,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/1933\/revisions"}],"predecessor-version":[{"id":1935,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/1933\/revisions\/1935"}],"wp:attachment":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/media?parent=1933"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/categories?post=1933"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/tags?post=1933"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}