Skip to content

Commit 4bb0c08

Browse files
feat(ad): expose Prometheus /metrics endpoint and scrape it from the OTel Collector
Add a Prometheus client library (io.prometheus:prometheus-metrics 1.3.6) to the ad service, expose `/metrics` on `AD_PROMETHEUS_PORT` (default 9465), and register a custom counter `demo_ad_served_total{category}` incremented as ads are returned. Wire a `prometheus/ad` receiver in the OTel Collector to scrape the endpoint, demonstrating Prometheus metric ingestion via the collector.
1 parent e513c9c commit 4bb0c08

8 files changed

Lines changed: 44 additions & 2 deletions

File tree

.env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ ACCOUNTING_DOCKERFILE=./src/accounting/Dockerfile
5353
# Ad Service
5454
AD_PORT=9555
5555
AD_ADDR=ad:${AD_PORT}
56+
AD_PROMETHEUS_PORT=9465
5657
AD_DOCKERFILE=./src/ad/Dockerfile
5758

5859
# Cart Service

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ the release.
77

88
## Unreleased
99

10+
* [ad] Expose a Prometheus `/metrics` endpoint (default port `9465`) using the
11+
Prometheus Java client library, with a custom counter
12+
`demo_ad_served_total{category}`, and scrape it from the OTel Collector via a
13+
new `prometheus/ad` receiver to demo Prometheus metric ingestion.
1014
* [telemetry-docs] Add a new service to provide telemetry documentation based
1115
on Weaver
1216
([#2794](https://github.com/open-telemetry/opentelemetry-demo/pull/2794))

docker-compose.minimal.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@ services:
3535
restart: unless-stopped
3636
ports:
3737
- "${AD_PORT}"
38+
- "${AD_PROMETHEUS_PORT}"
3839
environment:
3940
- AD_PORT
41+
- AD_PROMETHEUS_PORT
4042
- FLAGD_HOST
4143
- FLAGD_PORT
4244
- OTEL_EXPORTER_OTLP_ENDPOINT=http://${OTEL_COLLECTOR_HOST}:${OTEL_COLLECTOR_PORT_HTTP}
@@ -738,6 +740,7 @@ services:
738740
condition: service_healthy
739741
logging: *logging
740742
environment:
743+
- AD_PROMETHEUS_PORT
741744
- FRONTEND_PROXY_ADDR
742745
- HOST_FILESYSTEM
743746
- IMAGE_PROVIDER_HOST

docker-compose.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,10 @@ services:
6363
restart: unless-stopped
6464
ports:
6565
- "${AD_PORT}"
66+
- "${AD_PROMETHEUS_PORT}"
6667
environment:
6768
- AD_PORT
69+
- AD_PROMETHEUS_PORT
6870
- FLAGD_HOST
6971
- FLAGD_PORT
7072
- OTEL_EXPORTER_OTLP_ENDPOINT=http://${OTEL_COLLECTOR_HOST}:${OTEL_COLLECTOR_PORT_HTTP}
@@ -889,6 +891,7 @@ services:
889891
condition: service_healthy
890892
logging: *logging
891893
environment:
894+
- AD_PROMETHEUS_PORT
892895
- FRONTEND_PROXY_ADDR
893896
- HOST_FILESYSTEM
894897
- IMAGE_PROVIDER_HOST

src/ad/Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,5 @@ ADD --chmod=644 https://github.com/open-telemetry/opentelemetry-java-instrumenta
2929
ENV JAVA_TOOL_OPTIONS="-javaagent:/usr/src/app/opentelemetry-javaagent.jar -Xmx200m"
3030

3131
EXPOSE ${AD_PORT}
32+
EXPOSE ${AD_PROMETHEUS_PORT}
3233
ENTRYPOINT [ "./build/install/opentelemetry-demo-ad/bin/Ad" ]

src/ad/build.gradle

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ def opentelemetryInstrumentationVersion = "2.27.0"
2424
def grpcVersion = "1.81.0"
2525
def jacksonVersion = "2.21.3"
2626
def protocVersion = "4.34.1"
27+
def prometheusMetricsVersion = "1.3.6"
2728

2829
tasks.withType(JavaCompile).configureEach {
2930
sourceCompatibility = JavaVersion.VERSION_21
@@ -55,7 +56,9 @@ dependencies {
5556
"io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations",
5657
"org.apache.logging.log4j:log4j-core:2.25.4",
5758
"dev.openfeature.contrib.providers:flagd:0.13.1",
58-
'dev.openfeature:sdk:1.20.2'
59+
'dev.openfeature:sdk:1.20.2',
60+
"io.prometheus:prometheus-metrics-core:${prometheusMetricsVersion}",
61+
"io.prometheus:prometheus-metrics-exporter-httpserver:${prometheusMetricsVersion}"
5962

6063
runtimeOnly "com.fasterxml.jackson.core:jackson-core:${jacksonVersion}",
6164
"com.fasterxml.jackson.core:jackson-databind:${jacksonVersion}",

src/ad/src/main/java/oteldemo/AdService.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import io.opentelemetry.context.Scope;
2626
import io.opentelemetry.instrumentation.annotations.SpanAttribute;
2727
import io.opentelemetry.instrumentation.annotations.WithSpan;
28+
import io.prometheus.metrics.core.metrics.Counter;
29+
import io.prometheus.metrics.exporter.httpserver.HTTPServer;
2830
import java.io.IOException;
2931
import java.util.ArrayList;
3032
import java.util.Collection;
@@ -57,6 +59,14 @@ public final class AdService {
5759

5860
private Server server;
5961
private HealthStatusManager healthMgr;
62+
private HTTPServer prometheusServer;
63+
64+
private static final Counter adsServedCounter =
65+
Counter.builder()
66+
.name("demo_ad_served_total")
67+
.help("Total number of ads served, labeled by category")
68+
.labelNames("category")
69+
.register();
6070

6171
private static final AdService service = new AdService();
6272
private static final Tracer tracer = GlobalOpenTelemetry.getTracer("ad");
@@ -81,6 +91,11 @@ private void start() throws IOException {
8191
() ->
8292
new IllegalStateException(
8393
"environment vars: AD_PORT must not be null")));
94+
int prometheusPort =
95+
Integer.parseInt(Optional.ofNullable(System.getenv("AD_PROMETHEUS_PORT")).orElse("9465"));
96+
prometheusServer = HTTPServer.builder().port(prometheusPort).buildAndStart();
97+
logger.info(
98+
"Prometheus metrics endpoint started, listening on " + prometheusServer.getPort() + "/metrics");
8499
healthMgr = new HealthStatusManager();
85100

86101
// Create a flagd instance with OpenTelemetry
@@ -118,6 +133,9 @@ private void stop() {
118133
healthMgr.clearStatus("");
119134
server.shutdown();
120135
}
136+
if (prometheusServer != null) {
137+
prometheusServer.stop();
138+
}
121139
}
122140

123141
private enum AdRequestType {
@@ -231,6 +249,7 @@ public void getAds(AdRequest req, StreamObserver<AdResponse> responseObserver) {
231249
private Collection<Ad> getAdsByCategory(@SpanAttribute("demo.ad.category") String category) {
232250
Collection<Ad> ads = adsMap.get(category);
233251
Span.current().setAttribute("demo.ad.count", ads.size());
252+
adsServedCounter.labelValues(category).inc(ads.size());
234253
return ads;
235254
}
236255

@@ -251,6 +270,7 @@ private List<Ad> getRandomAds() {
251270
ads.add(Iterables.get(allAds, random.nextInt(allAds.size())));
252271
}
253272
span.setAttribute("demo.ad.count", ads.size());
273+
adsServedCounter.labelValues("random").inc(ads.size());
254274

255275
} finally {
256276
span.end();

src/otel-collector/otelcol-config.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@ receivers:
5757
endpoint: "valkey-cart:6379"
5858
username: "valkey"
5959
collection_interval: 10s
60+
prometheus/ad:
61+
config:
62+
scrape_configs:
63+
- job_name: ad
64+
scrape_interval: 10s
65+
static_configs:
66+
- targets: ["ad:${env:AD_PROMETHEUS_PORT}"]
6067
# Host metrics
6168
host_metrics:
6269
root_path: /hostfs
@@ -232,7 +239,7 @@ service:
232239
processors: [resourcedetection, memory_limiter, transform/sanitize_spans]
233240
exporters: [otlp_grpc/jaeger, debug, span_metrics]
234241
metrics:
235-
receivers: [docker_stats, http_check/frontend-proxy, host_metrics, nginx, otlp, postgresql, redis, span_metrics, kafkametrics]
242+
receivers: [docker_stats, http_check/frontend-proxy, host_metrics, nginx, otlp, postgresql, prometheus/ad, redis, span_metrics, kafkametrics]
236243
processors: [resourcedetection, memory_limiter]
237244
exporters: [otlp_http/prometheus, debug]
238245
logs:

0 commit comments

Comments
 (0)