Reputation: 3
I have the following simple code:
package com.example;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Scope;
import io.opentelemetry.exporter.logging.LoggingSpanExporter;
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
public class ManualOpenTelemetryExample {
public static void main(String[] args) {
// Step 1: Set up the OTLP exporter to send data to Dynatrace
OtlpGrpcSpanExporter otlpExporter = OtlpGrpcSpanExporter.builder()
.setEndpoint("<YOUR_DYNATRACE_ENDPOINT>") // Replace with your Dynatrace endpoint
.addHeader("Authorization", "Api-Token <YOUR_API_TOKEN>") // Replace with your Dynatrace API token
.build();
// Step 2: Set up the LoggingSpanExporter for debugging
LoggingSpanExporter loggingExporter = LoggingSpanExporter.create();
// Step 3: Set up the BatchSpanProcessor with the OTLP exporter
BatchSpanProcessor spanProcessor = BatchSpanProcessor.builder(otlpExporter).build();
// Step 4: Set up the TracerProvider with both processors
SdkTracerProvider tracerProvider = SdkTracerProvider.builder()
.addSpanProcessor(spanProcessor)
.addSpanProcessor(SimpleSpanProcessor.create(loggingExporter)) // Add logging exporter
.build();
// Step 5: Initialize OpenTelemetry with the TracerProvider
OpenTelemetrySdk openTelemetry = OpenTelemetrySdk.builder()
.setTracerProvider(tracerProvider)
.build();
// Step 6: Get a Tracer
Tracer tracer = openTelemetry.getTracer("manual-instrumentation-example", "1.0.0");
// Step 7: Simulate a workflow with multiple spans
simulateWork(tracer);
// Step 8: Shutdown the tracer provider to flush spans
tracerProvider.shutdown();
}
/**
* Simulates a workflow with multiple spans.
*/
private static void simulateWork(Tracer tracer) {
// Create a parent span for the entire workflow
Span parentSpan = tracer.spanBuilder("workflow-operation").startSpan();
try (Scope parentScope = parentSpan.makeCurrent()) {
// Add attributes to the parent span
parentSpan.setAttribute("service.name", "my-java-service");
parentSpan.setAttribute("environment", "production");
// Simulate step 1: Fetch data
simulateStep(tracer, "fetch-data", 200);
// Simulate step 2: Process data
simulateStep(tracer, "process-data", 300);
// Simulate step 3: Save data
simulateStep(tracer, "save-data", 100);
// Simulate step 4: Send notification
simulateStep(tracer, "send-notification", 150);
} finally {
// End the parent span
parentSpan.end();
}
}
/**
* Simulates a single step in the workflow.
*
* @param tracer The OpenTelemetry tracer.
* @param stepName The name of the step.
* @param durationMs The duration of the step in milliseconds.
*/
private static void simulateStep(Tracer tracer, String stepName, long durationMs) {
// Create a span for the step
Span stepSpan = tracer.spanBuilder(stepName).startSpan();
try (Scope stepScope = stepSpan.makeCurrent()) {
// Add attributes to the step span
stepSpan.setAttribute("step.name", stepName);
stepSpan.setAttribute("step.duration.ms", durationMs);
// Simulate work by sleeping
System.out.println("Executing step: " + stepName);
Thread.sleep(durationMs);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// End the step span
stepSpan.end();
}
}
}
All I want to do is to create one simple java process just to test creating ingest span into Dynatrace. But I'm always ended with the following error:
$ mvn exec:java -Dexec.mainClass="com.example.ManualOpenTelemetryExample"
[INFO] Scanning for projects...
[INFO]
[INFO] --------------< com.example:manual-opentelemetry-example >--------------
[INFO] Building manual-opentelemetry-example 1.0-SNAPSHOT
[INFO] from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- exec:3.5.0:java (default-cli) @ manual-opentelemetry-example ---
Executing step: fetch-data
Feb 03, 2025 3:11:25 PM io.opentelemetry.exporter.logging.LoggingSpanExporter export
INFO: 'fetch-data' : b6176f27f93041eda5e3ea2c20e27870 7942d9ee73773df1 INTERNAL [tracer: manual-instrumentation-example:1.0.0] AttributesMap{data={step.duration.ms=200, step.name=fetch-data}, capacity=128, totalAddedValues=2}
Executing step: process-data
Feb 03, 2025 3:11:25 PM io.opentelemetry.exporter.logging.LoggingSpanExporter export
INFO: 'process-data' : b6176f27f93041eda5e3ea2c20e27870 d3b9bc007fb9e028 INTERNAL [tracer: manual-instrumentation-example:1.0.0] AttributesMap{data={step.duration.ms=300, step.name=process-data}, capacity=128, totalAddedValues=2}
Executing step: save-data
Feb 03, 2025 3:11:26 PM io.opentelemetry.exporter.logging.LoggingSpanExporter export
INFO: 'save-data' : b6176f27f93041eda5e3ea2c20e27870 778ede14f1ca0d99 INTERNAL [tracer: manual-instrumentation-example:1.0.0] AttributesMap{data={step.duration.ms=100, step.name=save-data}, capacity=128, totalAddedValues=2}
Executing step: send-notification
Feb 03, 2025 3:11:26 PM io.opentelemetry.exporter.logging.LoggingSpanExporter export
INFO: 'send-notification' : b6176f27f93041eda5e3ea2c20e27870 17ce27eecaee9ac4 INTERNAL [tracer: manual-instrumentation-example:1.0.0] AttributesMap{data={step.duration.ms=150, step.name=send-notification}, capacity=128, totalAddedValues=2}
Feb 03, 2025 3:11:26 PM io.opentelemetry.exporter.logging.LoggingSpanExporter export
INFO: 'workflow-operation' : b6176f27f93041eda5e3ea2c20e27870 e350cdb78679c4e7 INTERNAL [tracer: manual-instrumentation-example:1.0.0] AttributesMap{data={environment=production, service.name=my-java-service}, capacity=128, totalAddedValues=2}
Feb 03, 2025 3:11:26 PM io.opentelemetry.sdk.internal.ThrottlingLogger doLog
SEVERE: Failed to export spans. The request could not be executed. Full error message: Canceled
[WARNING] thread Thread[#55,Okio Watchdog,5,com.example.ManualOpenTelemetryExample] was interrupted but is still alive after waiting at least 14980msecs
[WARNING] thread Thread[#55,Okio Watchdog,5,com.example.ManualOpenTelemetryExample] will linger despite being asked to die via interruption
[WARNING] NOTE: 1 thread(s) did not finish despite being asked to via interruption. This is not a problem with exec:java, it is a problem with the running code. Although not serious, it should be remedied.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 16.700 s
[INFO] Finished at: 2025-02-03T15:11:41+08:00
[INFO] ------------------------------------------------------------------------
What could be wrong here? Is there anything missing from my code?
The idea is to test my Dynatrace instance that opentelemetry is proven to be working using Java
Upvotes: 0
Views: 69
Reputation: 46
It seems like you are trying to use the OtlpGrpcSpanExporter
. gRPC is currently not supported. Could you try swapping out the OtlpGrpcSpanExporter
for an OtlpHttpSpanExporter
? This would mean data is exported via OTLP HTTP to the Dynatrace endpoint.
Upvotes: 2