Skip to content

Commit

Permalink
Document support for Prometheus Client 1.x
Browse files Browse the repository at this point in the history
  • Loading branch information
jonatan-ivanov committed Apr 17, 2024
1 parent e615674 commit 730d965
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 8 deletions.
4 changes: 2 additions & 2 deletions docs/modules/ROOT/pages/implementations/_install.adoc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[[implementations-installing]]
== Installing
[id=installing-micrometer-registry-{system}]
== Installing micrometer-registry-{system}

For Gradle, add the following implementation:

Expand Down
93 changes: 87 additions & 6 deletions docs/modules/ROOT/pages/implementations/prometheus.adoc
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
= Micrometer Prometheus
:toc:
:sectnums:
:system: prometheus

Prometheus is a dimensional time series database with a built-in UI, a custom query language, and math operations.
Prometheus is designed to operate on a pull model, periodically scraping metrics from application instances, based on service discovery.

Micrometer uses the Prometheus Java Client under the hood; there are two versions of it and Micrometer supports both. If you want to use the "new" client (`1.x`), use `micrometer-registry-prometheus` but if you want to use the "legacy" client (`0.x`), use `micrometer-registry-prometheus-simpleclient`.

:system: prometheus
include::_install.adoc[]

:system: prometheus-simpleclient
include::_install.adoc[]

== Configuring
Expand All @@ -32,13 +37,25 @@ try {
});
new Thread(server::start).start();
} catch (IOException e) {
}
catch (IOException e) {
throw new RuntimeException(e);
}
----
<1> The `PrometheusMeterRegistry` has a `scrape()` function that knows how to supply the String data necessary for the scrape. All you have to do is wire it to an endpoint.

You can alternatively use `io.prometheus.client.exporter.HTTPServer`, which you can find in `io.prometheus:simpleclient_httpserver`:
If you use the "new" client (`micrometer-registry-prometheus`), you can alternatively use `io.prometheus.metrics.exporter.httpserver.HTTPServer`, which you can find in `io.prometheus:prometheus-metrics-exporter-httpserver`:

[source,java]
----
PrometheusMeterRegistry prometheusRegistry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
HTTPServer.builder()
.port(8080)
.registry(prometheusRegistry.getPrometheusRegistry())
.buildAndStart();
----

If you use the "legacy" client (`micrometer-registry-prometheus-simpleclient`), you can alternatively use `io.prometheus.client.exporter.HTTPServer`, which you can find in `io.prometheus:simpleclient_httpserver`:

[source,java]
----
Expand All @@ -47,12 +64,20 @@ PrometheusMeterRegistry prometheusRegistry = new PrometheusMeterRegistry(Prometh
new HTTPServer(new InetSocketAddress(8080), prometheusRegistry.getPrometheusRegistry(), true);
----

Another alternative can be `io.prometheus.client.exporter.MetricsServlet`, which you can find in `io.prometheus:simpleclient_servlet` in case your app is running in a servlet container (such as Tomcat):
If you use the "new" client (`micrometer-registry-prometheus`), another alternative can be `io.prometheus.metrics.exporter.servlet.jakarta.PrometheusMetricsServlet`, which you can find in `io.prometheus:prometheus-metrics-exporter-servlet-jakarta` in case your app is running in a servlet container (such as Tomcat):

[source,java]
----
PrometheusMeterRegistry prometheusRegistry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
HttpServlet servlet = new PrometheusMetricsServlet(prometheusRegistry.getPrometheusRegistry());
----

If you use the "legacy" client (`micrometer-registry-prometheus-simpleclient`), another alternative can be `io.prometheus.client.exporter.MetricsServlet`, which you can find in `io.prometheus:simpleclient_servlet` in case your app is running in a servlet container (such as Tomcat):

[source,java]
----
PrometheusMeterRegistry prometheusRegistry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
HttpServlet metricsServlet = new MetricsServlet(prometheusRegistry.getPrometheusRegistry());
HttpServlet servlet = new MetricsServlet(prometheusRegistry.getPrometheusRegistry());
----

=== Scrape Format
Expand All @@ -61,7 +86,14 @@ By default, the `PrometheusMeterRegistry` `scrape()` method returns the https://

The https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md[OpenMetrics] format can also be produced.
To specify the format to be returned, you can pass a content type to the `scrape` method.
For example, to get the OpenMetrics 1.0.0 format scrape, you could use the Prometheus Java client constant for it, as follows:
For example, to get the OpenMetrics 1.0.0 format scrape, you could use the Prometheus Java client constant for it, as follows in case of the "new" client (`micrometer-registry-prometheus`):

[source,java]
----
String openMetricsScrape = registry.scrape("application/openmetrics-text");
----

if you use the "legacy" client (`micrometer-registry-prometheus-simpleclient`):

[source,java]
----
Expand Down Expand Up @@ -175,3 +207,52 @@ Actually, the `PrometheusMeterRegistry` has a shortcut for this, so you can do t
----
registry.throwExceptionOnRegistrationFailure();
----

== Exemplars

Exemplars are metadata that you can attach to the value of your time series. They can reference reference data outside of your metrics. A common use case is storing tracing information (`traceId`, `spanId`). Exemplars are not tags/dimensions (labels in Prometheus terminology), they will not increase cardinality since they belong to the values of the time series.

In order to setup Exemplars for `PrometheusMeterRegistry`, you will need a component that provides you the tracing information. If you use the "new" client (`micrometer-registry-prometheus`), this component is the `io.prometheus.metrics.tracer.common.SpanContext` while if you use the "legacy" client (`micrometer-registry-prometheus-simpleclient`), it is the `SpanContextSupplier`.

Setting them up are somewhat similar, if you use the "new" client (`micrometer-registry-prometheus`):
[source,java]
----
PrometheusMeterRegistry registry = new PrometheusMeterRegistry(
PrometheusConfig.DEFAULT,
new PrometheusRegistry(),
Clock.SYSTEM,
new MySpanContext() <1>
);
registry.counter("test").increment();
System.out.println(registry.scrape("application/openmetrics-text"));
----
<1> You need to implement `MySpanContext` (`class MySpanContext implements SpanContext { ... }`) or use an implementation that already exists.

But if you use the "legacy" client (`micrometer-registry-prometheus-simpleclient`):
[source,java]
----
PrometheusMeterRegistry registry = new PrometheusMeterRegistry(
PrometheusConfig.DEFAULT,
new CollectorRegistry(),
Clock.SYSTEM,
new DefaultExemplarSampler(new MySpanContextSupplier()) <1>
);
registry.counter("test").increment();
System.out.println(registry.scrape(TextFormat.CONTENT_TYPE_OPENMETRICS_100));
----
<1> You need to implement `MySpanContextSupplier` (`class MySpanContextSupplier implements SpanContextSupplier { ... }`) or use an implementation that already exists.

If your configuration is correct, you should get something like this, the `# {span_id="321",trace_id="123"} ...` section is the Exempar right after the value:
[source]
----
# TYPE test counter
# HELP test
test_total 1.0 # {span_id="321",trace_id="123"} 1.0 1713310767.908
# EOF
----

Exemplars are only supported in the OpenMetrics format (they will not show up in the Prometheus text format). You might need to explicitly ask for the OpenMetrics format, for example:
[source,shell]
----
curl --silent -H 'Accept: application/openmetrics-text; version=1.0.0' localhost:8080/prometheus
----

0 comments on commit 730d965

Please sign in to comment.