In Prometheus, labels are key-value pairs attached to metrics to add more context
For example
app_total_count_total{endpoint="/health",app_name="my_app",} 3.0 app_total_count_total{endpoint="/user-profile",app_name="my_app",} 7.0
In the above example, we have a single metric name app_total_count_total with two dimensions:
· endpoint
· app_name
These two dimensions endpoint, app_name are the labels for this metric.
How to Add Labels in Java?
You can do this when building your Metirc (Ex: Counter):
Counter appRequestCounter = Counter.build() .name("app_total_count") .help("Total requests by endpoint and app name") .labelNames("endpoint", "app_name") .register();
Then increment with labels:
· appRequestCounter.labels("/health", "my_app").inc();
Here the label endpoint is set to /health and the app_name is set to my_app
· appRequestCounter.labels("/user-profile", "my_app").inc();
Here the label endpoint is set to /user-profile and the app_name is
set to my_app
Let’s build an application and understand the labels use cases better.
PrometheusLabelMetricsApp.java
package com.sample.app; import io.prometheus.client.Counter; import io.prometheus.client.exporter.common.TextFormat; import io.prometheus.client.hotspot.DefaultExports; import io.prometheus.client.CollectorRegistry; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.StringWriter; import java.net.InetSocketAddress; import java.util.Arrays; import java.util.List; public class PrometheusLabelMetricsApp { // Define counter with both 'endpoint' and 'app_name' labels static final Counter appRequestCounter = Counter.build().name("app_total_count") .help("Total requests by endpoint and app name").labelNames("endpoint", "app_name").register(); static final String APP_NAME = "my_app"; // Supported endpoints static final List<String> validEndpoints = Arrays.asList("/health", "/login", "/logout", "/user-profile"); public static void main(String[] args) throws IOException { // Optional: Export default JVM metrics // DefaultExports.initialize(); // Start HTTP server HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0); // Handle /metrics endpoint server.createContext("/metrics", new MetricsHandler()); // Handle your 4 sample endpoints for (String endpoint : validEndpoints) { server.createContext(endpoint, new AppEndpointHandler(endpoint)); } server.setExecutor(null); server.start(); System.out.println("Server started on http://localhost:8080"); System.out.println("Metrics available at: http://localhost:8080/metrics"); } // Handler for metrics endpoint static class MetricsHandler implements HttpHandler { @Override public void handle(HttpExchange exchange) throws IOException { StringWriter writer = new StringWriter(); TextFormat.write004(writer, CollectorRegistry.defaultRegistry.metricFamilySamples()); String response = writer.toString(); exchange.getResponseHeaders().set("Content-Type", TextFormat.CONTENT_TYPE_004); exchange.sendResponseHeaders(200, response.length()); try (OutputStreamWriter os = new OutputStreamWriter(exchange.getResponseBody())) { os.write(response); } } } // Handler for simulated API endpoints static class AppEndpointHandler implements HttpHandler { private final String endpoint; AppEndpointHandler(String endpoint) { this.endpoint = endpoint; } @Override public void handle(HttpExchange exchange) throws IOException { // Increment counter with both labels appRequestCounter.labels(endpoint, APP_NAME).inc(); String response = "Hello from " + endpoint; exchange.sendResponseHeaders(200, response.length()); try (OutputStreamWriter os = new OutputStreamWriter(exchange.getResponseBody())) { os.write(response); } } } }
Run the application.
You will see following messages in console.
Server started on http://localhost:8080
Metrics available at: http://localhost:8080/metrics
Open the url ‘http://localhost:8080/metrics’ in browser.
Right now no metrics are captured. Let’s hit the http://localhost:8080/health endpoint couple of times. I hit this endpoint for 5 times, and the metrics response is like below.
# HELP app_total_count_total Total requests by endpoint and app name # TYPE app_total_count_total counter app_total_count_total{endpoint="/health",app_name="my_app",} 5.0 # HELP app_total_count_created Total requests by endpoint and app name # TYPE app_total_count_created gauge app_total_count_created{endpoint="/health",app_name="my_app",} 1.744526450145E9
From the response, you can confirm that the /health endpoint is visited 5 times.
Let’s hit /login 3 times, /logout 2 times and /user-profile 1 time.
Metrics endpoint response looks like below.
# HELP app_total_count_total Total requests by endpoint and app name # TYPE app_total_count_total counter app_total_count_total{endpoint="/logout",app_name="my_app",} 2.0 app_total_count_total{endpoint="/login",app_name="my_app",} 3.0 app_total_count_total{endpoint="/health",app_name="my_app",} 5.0 app_total_count_total{endpoint="/user-profile",app_name="my_app",} 1.0 # HELP app_total_count_created Total requests by endpoint and app name # TYPE app_total_count_created gauge app_total_count_created{endpoint="/logout",app_name="my_app",} 1.744526536605E9 app_total_count_created{endpoint="/login",app_name="my_app",} 1.744526531462E9 app_total_count_created{endpoint="/health",app_name="my_app",} 1.744526450145E9 app_total_count_created{endpoint="/user-profile",app_name="my_app",} 1.744526539912E9
How to see this metrics in prometheus UI?
Let’s attach this target to Prometheus instance by updating prometheus.yml file
prometheus.yml
global: scrape_interval: 15s scrape_configs: - job_name: 'prometheus' static_configs: - targets: ['localhost:9090'] - job_name: 'node_exporter' static_configs: - targets: ['localhost:9100'] - job_name: 'java_app' static_configs: - targets: ['localhost:8080']
Start Prometheus application by executing following command.
prometheus --config.file=./prometheus.yml
Upon successful starting of Prometheus server, execute following metric.
app_total_count_total
You can get total requests by the metric using the aggregate function sum.
sum(app_total_count_total)
Percentage of Total metrics went to user-profile
( sum(app_total_count_total{endpoint="/user-profile"}) / sum(app_total_count_total) ) * 100
Filter the metrics by endpoint label
app_total_count_total{endpoint="/logout"}
Previous Next Home
No comments:
Post a Comment