diff --git a/examples/java/testcontainer/README.md b/examples/java/testcontainer/README.md index bf5882e9..a5256e7f 100644 --- a/examples/java/testcontainer/README.md +++ b/examples/java/testcontainer/README.md @@ -1,33 +1,41 @@ # Using Testcontainers -The provided code demonstrates how to use **Testcontainers** with **Grafana's LGTM stack** to test OpenTelemetry metrics in a Java application. Here's a step-by-step explanation: +The provided code demonstrates how to use **Testcontainers** with **Grafana's LGTM stack** to test OpenTelemetry metrics +in a Java application. Here's a step-by-step explanation: 1. **Set Up the Testcontainers Environment**: - - The `@Testcontainers` annotation enables the Testcontainers extension for JUnit 5. - - The `@Container` annotation is used to define a `LgtmStackContainer` that runs the Grafana LGTM stack in a Docker container. +- The `@Testcontainers` annotation enables the Testcontainers extension for JUnit 5. +- The `@Container` annotation is used to define a `LgtmStackContainer` that runs the Grafana LGTM stack in a Docker + container. 2. **Configure OpenTelemetry**: - - In the `@BeforeEach` method, system properties are set to configure the OpenTelemetry exporter to send metrics to the LGTM stack running in the container. +- In the `@BeforeEach` method, system properties are set to configure the OpenTelemetry exporter to send metrics to + the LGTM stack running in the container. 3. **Run the Application**: - - The `OtelApp` class initializes OpenTelemetry and generates a custom metric (`sold_items`) with attributes (e.g., `tenant`). +- The `OtelApp` class initializes OpenTelemetry and generates a custom metric (`sold_items`) with attributes (e.g., + `tenant`) as well as a span representing the block the code. -4. **Test the Metrics Export**: +4. **Test Exporting Metrics and Traces**: - - The test method `testExportMetric` runs the application and queries the Prometheus endpoint in the LGTM stack to verify that the metric (`sold_items`) has been exported successfully. - - The `Awaitility` library is used to poll the Prometheus endpoint until the metric is found or a timeout occurs. +- The test method `testExportMetricsAndTraces` runs the application and queries the Prometheus and Tempo endpoints + in the LGTM stack to verify that the metric (`sold_items`) and span have been exported successfully. +- The `Awaitility` library is used to poll the endpoints until the telemetry is found or a timeout occurs. 5. **Debugging with Grafana**: - - The test outputs the Grafana URL (`lgtm.getGrafanaHttpUrl()`) to the console, allowing you to manually inspect the metrics in the Grafana UI. + +- The test outputs the Grafana URL (`lgtm.getGrafanaHttpUrl()`) to the console, allowing you to manually inspect the + telemetry in the Grafana UI if needed. ## Example Usage 1. Start the test using `mvn test`. 2. Check the console output for the Grafana URL. -3. Open the Grafana UI, navigate to the Explore tab, and query the metrics. -4. The test will pass if the metric is successfully exported and found in Prometheus. +3. Open the Grafana UI, navigate to the Explore tab, and query the metrics or traces. +4. The test will pass if the metric and span are successfully exported and found in Prometheus and Tempo. -This setup is useful for validating OpenTelemetry instrumentation and ensuring metrics are correctly exported to a monitoring system. +This setup is useful for validating OpenTelemetry instrumentation and ensuring metrics are correctly exported to a +monitoring system. \ No newline at end of file diff --git a/examples/java/testcontainer/pom.xml b/examples/java/testcontainer/pom.xml index 0ddc68a2..f9427624 100644 --- a/examples/java/testcontainer/pom.xml +++ b/examples/java/testcontainer/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.grafana.example - testcontaier + testcontainer 1.0.0-SNAPSHOT Java Testcontainer Demo diff --git a/examples/java/testcontainer/src/test/java/com/grafana/example/TestcontainerTest.java b/examples/java/testcontainer/src/test/java/com/grafana/example/TestcontainerTest.java index 27758baf..a84b3c5d 100644 --- a/examples/java/testcontainer/src/test/java/com/grafana/example/TestcontainerTest.java +++ b/examples/java/testcontainer/src/test/java/com/grafana/example/TestcontainerTest.java @@ -9,6 +9,7 @@ import java.net.http.HttpResponse; import java.nio.charset.StandardCharsets; import java.time.Duration; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.testcontainers.grafana.LgtmStackContainer; @@ -18,7 +19,8 @@ @Testcontainers public class TestcontainerTest { - @Container private final LgtmStackContainer lgtm = new LgtmStackContainer("grafana/otel-lgtm"); + @Container + private final LgtmStackContainer lgtm = new LgtmStackContainer("grafana/otel-lgtm"); @BeforeEach void setUp() { @@ -26,12 +28,13 @@ void setUp() { System.setProperty("otel.exporter.otlp.protocol", "http/protobuf"); System.setProperty("otel.resource.attributes", "service.name=otel-java-test"); System.setProperty("otel.metric.export.interval", "1s"); + System.setProperty("otel.bsp.schedule.delay", "500ms"); } @Test - void testExportMetric() { - // Howto: - // 1. The test with a really long timeout + void testExportMetricsAndTraces() throws InterruptedException { + // How to debug: + // 1. Run the test with a really long timeout (update the awaitility argument) // 2. Go to the Grafana UI // 3. Open the Explore tab // 4. Select the Prometheus data source @@ -39,21 +42,18 @@ void testExportMetric() { // 6. Click on the metric to see the details // 7. Copy the query and paste it into the test System.out.println("Grafana URL to debug telemetry: " + lgtm.getGrafanaHttpUrl()); - var app = new OtelApp(); app.run(); + HttpClient client = HttpClient.newHttpClient(); String query = URLEncoder.encode( "sold_items_total{job=\"otel-java-test\",service_name=\"otel-java-test\",tenant=\"tenant1\"}", StandardCharsets.UTF_8); - String prometheusHttpUrl = lgtm.getPromehteusHttpUrl() + "/api/v1/query?query=" + query; + String prometheusHttpUrl = lgtm.getPrometheusHttpUrl() + "/api/v1/query?query=" + query; - HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder().uri(URI.create(prometheusHttpUrl)).build(); - // Total time: 18.448 s (for the whole test, will take longer when the image needs to be - // downloaded) await() .atMost(Duration.ofSeconds(10)) .until( @@ -63,5 +63,18 @@ void testExportMetric() { String body = response.body(); return response.statusCode() == 200 && body.contains("sold_items"); }); + + HttpRequest traceRequest = HttpRequest.newBuilder() + .uri(URI.create(String.format("%s/api/search", lgtm.getTempoUrl()))) + .build(); + + await() + .atMost(Duration.ofSeconds(10)) + .until( + () -> { + HttpResponse response = client.send(traceRequest, HttpResponse.BodyHandlers.ofString()); + String body = response.body(); + return response.statusCode() == 200 && body.contains("otel-java-test"); + }); } }