Docs

Grafana Integration

Learn how to export Observability Kit metrics, traces, and logs to a Grafana stack.

Grafana is an observability stack with support for metrics, traces, and logs, viewed together in a single tool. A typical stack pairs Grafana with Prometheus for metrics, Tempo for traces, and Loki for logs. It can be self-hosted or used as the managed Grafana Cloud service.

This page covers the application-side configuration — getting the kit’s telemetry into those backing stores. For standing up the stores themselves, follow the Grafana documentation; Grafana Cloud also exposes a single OTLP gateway that accepts both metrics and traces.

Configure the Application

Add Actuator and the Prometheus registry for metrics, and the OpenTelemetry starter for OTLP trace export:

Source code
pom.xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-opentelemetry</artifactId>
</dependency>
Source code
application.properties
spring.application.name=vaadin

# Metrics: scraped by Prometheus from Actuator
management.endpoints.web.exposure.include=prometheus
# The OpenTelemetry starter also brings in the OTLP metrics registry; disable it so metrics go through Prometheus only
management.otlp.metrics.export.enabled=false

# Traces: pushed to Tempo over OTLP
management.opentelemetry.tracing.export.otlp.endpoint=http://localhost:4318/v1/traces
management.tracing.sampling.probability=1.0

Point management.opentelemetry.tracing.export.otlp.endpoint at your Tempo (or collector) OTLP endpoint, and configure Prometheus to scrape the application at /actuator/prometheus — see the Prometheus page.

Logs reach Loki through your logging pipeline rather than the kit; see the Loki documentation for the available options.

Viewing Data

Data is explored through Grafana’s Explore view, selecting the data source for each signal. See the Grafana documentation for details.

Viewing Traces

Open the Explore view and select Tempo as the data source. Change the Query type to Search, select your service name from the Service name menu, then click the refresh button in the top-right to search for traces.

Use the Tags option to filter for specific span attributes. For example, to find traces that contain errors, filter on outcome=error.

Clicking a trace ID brings up a side panel with detailed information about the trace, such as its nested spans and their attributes.

Viewing Metrics

Open the Explore view and select Prometheus as the data source. Select a metric from the Metric drop-down — for example vaadin_sessions_active — then click the refresh button in the top-right to display it.

Viewing Logs

Open the Explore view and select Loki as the data source. Under Labels, configure a label for service_name with your application’s service name, then click the refresh button in the top-right to search for logs.

Example Dashboard Queries

The following PromQL expressions cover the most useful panels for a Vaadin dashboard. Remember that Prometheus renders the dotted meter names in its own convention — vaadin.request.duration becomes vaadin_request_duration_seconds, and the .created counters become vaadin_sessions_total and vaadin_ui_total.

Panel Query

Active sessions

sum(vaadin_sessions_active)

Active UIs (browser tabs)

sum(vaadin_ui_active)

Request rate

sum(rate(vaadin_request_duration_seconds_count[$__rate_interval]))

Server errors

sum(rate(vaadin_errors_total[$__rate_interval]))

Request latency, p95

histogram_quantile(0.95, sum by (le) (rate(vaadin_request_duration_seconds_bucket[$__rate_interval])))

RPC latency by type, p95

histogram_quantile(0.95, sum by (le, type) (rate(vaadin_rpc_duration_seconds_bucket[$__rate_interval])))

Navigation rate by route

sum by (route) (rate(vaadin_navigation_seconds_count[$__rate_interval]))

Session lock wait, p95

histogram_quantile(0.95, sum by (le) (rate(vaadin_session_lock_wait_seconds_bucket[$__rate_interval])))

Retained UI state against the heap

sum(vaadin_ui_state_size_bytes) charted next to sum(jvm_memory_used_bytes{area="heap"}) and sum(jvm_memory_max_bytes{area="heap"})

The percentile queries read _bucket series, which the kit’s timers don’t publish by default — enable them per meter first; see Percentiles and Histogram Buckets. The UI state panel needs the opt-in vaadin.observability.ui-state feature, and a byte figure appears only when vaadin.observability.ui-state-bytes-per-node is set; see UI State Size.

A complete dashboard built from these queries ships with the Vaadin observability use-case application: a provisioned Grafana dashboard (grafana/dashboards/vaadin.json) together with a Docker Compose stack that runs Prometheus and Grafana against the application. Import the JSON into your own Grafana as a starting point, or run the stack to see the panels over live data.

Updated