Skip to content

Commit bb3b183

Browse files
committed
Add loki port to lgtm test container
1 parent a2197e1 commit bb3b183

File tree

3 files changed

+121
-63
lines changed

3 files changed

+121
-63
lines changed

modules/grafana/build.gradle

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,13 @@ dependencies {
1212
testImplementation 'io.opentelemetry:opentelemetry-api'
1313
testImplementation 'io.opentelemetry:opentelemetry-sdk'
1414
testImplementation 'io.opentelemetry:opentelemetry-exporter-otlp'
15+
16+
testImplementation project(':junit-jupiter')
17+
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.11.0'
18+
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.10.3'
19+
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.11.0'
20+
}
21+
22+
test {
23+
useJUnitPlatform()
1524
}

modules/grafana/src/main/java/org/testcontainers/grafana/LgtmStackContainer.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ public class LgtmStackContainer extends GenericContainer<LgtmStackContainer> {
3131

3232
private static final int OTLP_HTTP_PORT = 4318;
3333

34+
private static final int LOKI_PORT = 3100;
35+
3436
private static final int TEMPO_PORT = 3200;
3537

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

66+
public String getLokiUrl() {
67+
return "http://" + getHost() + ":" + getMappedPort(LOKI_PORT);
68+
}
69+
6470
public String getOtlpHttpUrl() {
6571
return "http://" + getHost() + ":" + getMappedPort(OTLP_HTTP_PORT);
6672
}

modules/grafana/src/test/java/org/testcontainers/grafana/LgtmStackContainerTest.java

Lines changed: 105 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,23 @@
77
import io.micrometer.registry.otlp.OtlpMeterRegistry;
88
import io.opentelemetry.api.common.AttributeKey;
99
import io.opentelemetry.api.common.Attributes;
10+
import io.opentelemetry.api.logs.Logger;
1011
import io.opentelemetry.api.trace.Span;
1112
import io.opentelemetry.api.trace.Tracer;
13+
import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter;
1214
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
1315
import io.opentelemetry.sdk.OpenTelemetrySdk;
16+
import io.opentelemetry.sdk.logs.SdkLoggerProvider;
17+
import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor;
1418
import io.opentelemetry.sdk.resources.Resource;
1519
import io.opentelemetry.sdk.trace.SdkTracerProvider;
1620
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
1721
import io.restassured.RestAssured;
1822
import io.restassured.response.Response;
1923
import org.awaitility.Awaitility;
20-
import org.junit.Test;
24+
import org.junit.jupiter.api.AfterAll;
25+
import org.junit.jupiter.api.BeforeAll;
26+
import org.junit.jupiter.api.Test;
2127
import uk.org.webcompere.systemstubs.SystemStubs;
2228

2329
import java.time.Duration;
@@ -27,71 +33,27 @@
2733

2834
public class LgtmStackContainerTest {
2935

30-
@Test
31-
public void shouldPublishMetricAndTrace() throws Exception {
32-
try ( // container {
33-
LgtmStackContainer lgtm = new LgtmStackContainer("grafana/otel-lgtm:0.11.0")
34-
// }
35-
) {
36-
lgtm.start();
37-
38-
String version = RestAssured
39-
.get(String.format("http://%s:%s/api/health", lgtm.getHost(), lgtm.getMappedPort(3000)))
40-
.jsonPath()
41-
.get("version");
42-
assertThat(version).isEqualTo("11.6.0");
43-
44-
generateTrace(lgtm);
45-
46-
OtlpConfig otlpConfig = createOtlpConfig(lgtm);
47-
MeterRegistry meterRegistry = SystemStubs
48-
.withEnvironmentVariable("OTEL_SERVICE_NAME", "testcontainers")
49-
.execute(() -> new OtlpMeterRegistry(otlpConfig, Clock.SYSTEM));
50-
Counter.builder("test.counter").register(meterRegistry).increment(2);
51-
52-
Awaitility
53-
.given()
54-
.pollInterval(Duration.ofSeconds(2))
55-
.atMost(Duration.ofSeconds(5))
56-
.ignoreExceptions()
57-
.untilAsserted(() -> {
58-
Response response = RestAssured
59-
.given()
60-
.queryParam("query", "test_counter_total{job=\"testcontainers\"}")
61-
.get(String.format("%s/api/v1/query", lgtm.getPrometheusHttpUrl()))
62-
.prettyPeek()
63-
.thenReturn();
64-
assertThat(response.getStatusCode()).isEqualTo(200);
65-
assertThat(response.body().jsonPath().getList("data.result[0].value")).contains("2");
66-
});
67-
68-
Awaitility
69-
.given()
70-
.pollInterval(Duration.ofSeconds(2))
71-
.atMost(Duration.ofSeconds(5))
72-
.ignoreExceptions()
73-
.untilAsserted(() -> {
74-
Response response = RestAssured
75-
.given()
76-
.get(String.format("%s/api/search", lgtm.getTempoUrl()))
77-
.prettyPeek()
78-
.thenReturn();
79-
assertThat(response.getStatusCode()).isEqualTo(200);
80-
assertThat(response.body().jsonPath().getString("traces[0].rootServiceName"))
81-
.isEqualTo("test-service");
82-
});
83-
}
84-
}
36+
private static final LgtmStackContainer lgtm = new LgtmStackContainer("grafana/otel-lgtm:0.11.1");
37+
38+
private static OpenTelemetrySdk openTelemetry;
8539

86-
private void generateTrace(LgtmStackContainer lgtm) {
87-
OtlpGrpcSpanExporter exporter = OtlpGrpcSpanExporter
40+
@BeforeAll
41+
static void setup() {
42+
lgtm.start();
43+
OtlpGrpcSpanExporter spanExporter = OtlpGrpcSpanExporter
8844
.builder()
8945
.setTimeout(Duration.ofSeconds(1))
90-
.setEndpoint(lgtm.getOtlpGrpcUrl())
46+
.setEndpoint(LgtmStackContainerTest.lgtm.getOtlpGrpcUrl())
47+
.build();
48+
49+
OtlpGrpcLogRecordExporter logExporter = OtlpGrpcLogRecordExporter
50+
.builder()
51+
.setTimeout(Duration.ofSeconds(1))
52+
.setEndpoint(LgtmStackContainerTest.lgtm.getOtlpGrpcUrl())
9153
.build();
9254

9355
BatchSpanProcessor spanProcessor = BatchSpanProcessor
94-
.builder(exporter)
56+
.builder(spanExporter)
9557
.setScheduleDelay(500, TimeUnit.MILLISECONDS)
9658
.build();
9759

@@ -101,13 +63,94 @@ private void generateTrace(LgtmStackContainer lgtm) {
10163
.setResource(Resource.create(Attributes.of(AttributeKey.stringKey("service.name"), "test-service")))
10264
.build();
10365

104-
OpenTelemetrySdk openTelemetry = OpenTelemetrySdk.builder().setTracerProvider(tracerProvider).build();
66+
SdkLoggerProvider loggerProvider = SdkLoggerProvider
67+
.builder()
68+
.addLogRecordProcessor(SimpleLogRecordProcessor.create(logExporter))
69+
.build();
70+
71+
openTelemetry =
72+
OpenTelemetrySdk.builder().setTracerProvider(tracerProvider).setLoggerProvider(loggerProvider).build();
73+
}
74+
75+
@AfterAll
76+
static void cleanup() {
77+
openTelemetry.shutdown();
78+
lgtm.stop();
79+
}
80+
81+
@Test
82+
void shouldPublishMetric() throws Exception {
83+
String version = RestAssured
84+
.get(String.format("http://%s:%s/api/health", lgtm.getHost(), lgtm.getMappedPort(3000)))
85+
.jsonPath()
86+
.get("version");
87+
assertThat(version).isEqualTo("12.0.0");
88+
89+
OtlpConfig otlpConfig = createOtlpConfig(lgtm);
90+
MeterRegistry meterRegistry = SystemStubs
91+
.withEnvironmentVariable("OTEL_SERVICE_NAME", "testcontainers")
92+
.execute(() -> new OtlpMeterRegistry(otlpConfig, Clock.SYSTEM));
93+
Counter.builder("test.counter").register(meterRegistry).increment(2);
94+
95+
Awaitility
96+
.given()
97+
.pollInterval(Duration.ofSeconds(2))
98+
.atMost(Duration.ofSeconds(5))
99+
.ignoreExceptions()
100+
.untilAsserted(() -> {
101+
Response response = RestAssured
102+
.given()
103+
.queryParam("query", "test_counter_total{job=\"testcontainers\"}")
104+
.get(String.format("%s/api/v1/query", lgtm.getPrometheusHttpUrl()))
105+
.prettyPeek()
106+
.thenReturn();
107+
assertThat(response.getStatusCode()).isEqualTo(200);
108+
assertThat(response.body().jsonPath().getList("data.result[0].value")).contains("2");
109+
});
110+
}
105111

112+
@Test
113+
void shouldPublishLog() {
114+
Logger logger = openTelemetry.getSdkLoggerProvider().loggerBuilder("test").build();
115+
logger.logRecordBuilder().setBody("Test log!").setAttribute(AttributeKey.stringKey("job"), "test-job").emit();
116+
117+
Awaitility
118+
.given()
119+
.pollInterval(Duration.ofSeconds(2))
120+
.atMost(Duration.ofSeconds(5))
121+
.ignoreExceptions()
122+
.untilAsserted(() -> {
123+
Response response = RestAssured
124+
.given()
125+
.queryParam("query", "{service_name=\"unknown_service:java\"}")
126+
.get(String.format("%s/loki/api/v1/query_range", lgtm.getLokiUrl()))
127+
.prettyPeek()
128+
.thenReturn();
129+
assertThat(response.getStatusCode()).isEqualTo(200);
130+
assertThat(response.body().jsonPath().getString("data.result[0].values[0][1]")).isEqualTo("Test log!");
131+
});
132+
}
133+
134+
@Test
135+
void shouldPublishTrace() {
106136
Tracer tracer = openTelemetry.getTracer("test");
107137
Span span = tracer.spanBuilder("test").startSpan();
108138
span.end();
109139

110-
openTelemetry.shutdown();
140+
Awaitility
141+
.given()
142+
.pollInterval(Duration.ofSeconds(2))
143+
.atMost(Duration.ofSeconds(5))
144+
.ignoreExceptions()
145+
.untilAsserted(() -> {
146+
Response response = RestAssured
147+
.given()
148+
.get(String.format("%s/api/search", lgtm.getTempoUrl()))
149+
.prettyPeek()
150+
.thenReturn();
151+
assertThat(response.getStatusCode()).isEqualTo(200);
152+
assertThat(response.body().jsonPath().getString("traces[0].rootServiceName")).isEqualTo("test-service");
153+
});
111154
}
112155

113156
private static OtlpConfig createOtlpConfig(LgtmStackContainer lgtm) {

0 commit comments

Comments
 (0)