Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public class LgtmStackContainer extends GenericContainer<LgtmStackContainer> {

private static final int OTLP_HTTP_PORT = 4318;

private static final int LOKI_PORT = 3100;

private static final int TEMPO_PORT = 3200;

private static final int PROMETHEUS_PORT = 9090;
Expand All @@ -42,7 +44,7 @@ public LgtmStackContainer(String image) {
public LgtmStackContainer(DockerImageName image) {
super(image);
image.assertCompatibleWith(DEFAULT_IMAGE_NAME);
withExposedPorts(GRAFANA_PORT, TEMPO_PORT, OTLP_GRPC_PORT, OTLP_HTTP_PORT, PROMETHEUS_PORT);
withExposedPorts(GRAFANA_PORT, TEMPO_PORT, LOKI_PORT, OTLP_GRPC_PORT, OTLP_HTTP_PORT, PROMETHEUS_PORT);
waitingFor(
Wait.forLogMessage(".*The OpenTelemetry collector and the Grafana LGTM stack are up and running.*\\s", 1)
);
Expand All @@ -61,6 +63,10 @@ public String getTempoUrl() {
return "http://" + getHost() + ":" + getMappedPort(TEMPO_PORT);
}

public String getLokiUrl() {
return "http://" + getHost() + ":" + getMappedPort(LOKI_PORT);
}

public String getOtlpHttpUrl() {
return "http://" + getHost() + ":" + getMappedPort(OTLP_HTTP_PORT);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@
import io.micrometer.registry.otlp.OtlpMeterRegistry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.logs.Logger;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter;
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.logs.SdkLoggerProvider;
import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
Expand All @@ -28,86 +32,107 @@
public class LgtmStackContainerTest {

@Test
public void shouldPublishMetricAndTrace() throws Exception {
public void shouldPublishMetricsTracesAndLogs() throws Exception {
try ( // container {
LgtmStackContainer lgtm = new LgtmStackContainer("grafana/otel-lgtm:0.11.0")
LgtmStackContainer lgtm = new LgtmStackContainer("grafana/otel-lgtm:0.11.1")
// }
) {
lgtm.start();

OtlpGrpcSpanExporter spanExporter = OtlpGrpcSpanExporter
.builder()
.setTimeout(Duration.ofSeconds(1))
.setEndpoint(lgtm.getOtlpGrpcUrl())
.build();

OtlpGrpcLogRecordExporter logExporter = OtlpGrpcLogRecordExporter
.builder()
.setTimeout(Duration.ofSeconds(1))
.setEndpoint(lgtm.getOtlpGrpcUrl())
.build();

BatchSpanProcessor spanProcessor = BatchSpanProcessor
.builder(spanExporter)
.setScheduleDelay(500, TimeUnit.MILLISECONDS)
.build();

SdkTracerProvider tracerProvider = SdkTracerProvider
.builder()
.addSpanProcessor(spanProcessor)
.setResource(Resource.create(Attributes.of(AttributeKey.stringKey("service.name"), "test-service")))
.build();

SdkLoggerProvider loggerProvider = SdkLoggerProvider
.builder()
.addLogRecordProcessor(SimpleLogRecordProcessor.create(logExporter))
.build();

OpenTelemetrySdk openTelemetry = OpenTelemetrySdk
.builder()
.setTracerProvider(tracerProvider)
.setLoggerProvider(loggerProvider)
.build();

String version = RestAssured
.get(String.format("http://%s:%s/api/health", lgtm.getHost(), lgtm.getMappedPort(3000)))
.jsonPath()
.get("version");
assertThat(version).isEqualTo("11.6.0");

generateTrace(lgtm);
assertThat(version).isEqualTo("12.0.0");

OtlpConfig otlpConfig = createOtlpConfig(lgtm);
MeterRegistry meterRegistry = SystemStubs
.withEnvironmentVariable("OTEL_SERVICE_NAME", "testcontainers")
.execute(() -> new OtlpMeterRegistry(otlpConfig, Clock.SYSTEM));
Counter.builder("test.counter").register(meterRegistry).increment(2);

Logger logger = openTelemetry.getSdkLoggerProvider().loggerBuilder("test").build();
logger
.logRecordBuilder()
.setBody("Test log!")
.setAttribute(AttributeKey.stringKey("job"), "test-job")
.emit();

Tracer tracer = openTelemetry.getTracer("test");
Span span = tracer.spanBuilder("test").startSpan();
span.end();

Awaitility
.given()
.pollInterval(Duration.ofSeconds(2))
.atMost(Duration.ofSeconds(5))
.ignoreExceptions()
.untilAsserted(() -> {
Response response = RestAssured
Response metricResponse = RestAssured
.given()
.queryParam("query", "test_counter_total{job=\"testcontainers\"}")
.get(String.format("%s/api/v1/query", lgtm.getPrometheusHttpUrl()))
.prettyPeek()
.thenReturn();
assertThat(response.getStatusCode()).isEqualTo(200);
assertThat(response.body().jsonPath().getList("data.result[0].value")).contains("2");
});
assertThat(metricResponse.getStatusCode()).isEqualTo(200);
assertThat(metricResponse.body().jsonPath().getList("data.result[0].value")).contains("2");

Awaitility
.given()
.pollInterval(Duration.ofSeconds(2))
.atMost(Duration.ofSeconds(5))
.ignoreExceptions()
.untilAsserted(() -> {
Response response = RestAssured
Response logResponse = RestAssured
.given()
.queryParam("query", "{service_name=\"unknown_service:java\"}")
.get(String.format("%s/loki/api/v1/query_range", lgtm.getLokiUrl()))
.prettyPeek()
.thenReturn();
assertThat(logResponse.getStatusCode()).isEqualTo(200);
assertThat(logResponse.body().jsonPath().getString("data.result[0].values[0][1]"))
.isEqualTo("Test log!");

Response traceResponse = RestAssured
.given()
.get(String.format("%s/api/search", lgtm.getTempoUrl()))
.prettyPeek()
.thenReturn();
assertThat(response.getStatusCode()).isEqualTo(200);
assertThat(response.body().jsonPath().getString("traces[0].rootServiceName"))
assertThat(traceResponse.getStatusCode()).isEqualTo(200);
assertThat(traceResponse.body().jsonPath().getString("traces[0].rootServiceName"))
.isEqualTo("test-service");
});
}
}

private void generateTrace(LgtmStackContainer lgtm) {
OtlpGrpcSpanExporter exporter = OtlpGrpcSpanExporter
.builder()
.setTimeout(Duration.ofSeconds(1))
.setEndpoint(lgtm.getOtlpGrpcUrl())
.build();

BatchSpanProcessor spanProcessor = BatchSpanProcessor
.builder(exporter)
.setScheduleDelay(500, TimeUnit.MILLISECONDS)
.build();

SdkTracerProvider tracerProvider = SdkTracerProvider
.builder()
.addSpanProcessor(spanProcessor)
.setResource(Resource.create(Attributes.of(AttributeKey.stringKey("service.name"), "test-service")))
.build();

OpenTelemetrySdk openTelemetry = OpenTelemetrySdk.builder().setTracerProvider(tracerProvider).build();

Tracer tracer = openTelemetry.getTracer("test");
Span span = tracer.spanBuilder("test").startSpan();
span.end();

openTelemetry.shutdown();
openTelemetry.close();
}
}

private static OtlpConfig createOtlpConfig(LgtmStackContainer lgtm) {
Expand Down
Loading