Observability Kit Reference
Observability Kit instruments the Vaadin runtime and records everything into your application’s Micrometer MeterRegistry.
Metrics are plain Micrometer meters; tracing spans are emitted through the Micrometer Observation API.
Both flow to whatever backend you’ve configured — see the Integrations page.
Each group of meters and spans is controlled by a feature toggle (for example vaadin.observability.sessions).
See the Configuration page for how to turn features on or off.
|
Note
|
Naming Conventions
Meter names follow Micrometer’s dotted, lowercase convention (for example vaadin.request.duration).
How a name appears in your backend depends on that its conventions — Prometheus, for instance, renders vaadin.request.duration as vaadin_request_duration_seconds with a _count, _sum, and bucket suffixes.
|
Metrics
A meter is a measurement recorded at runtime. Observability Kit records the meter types Micrometer provides:
- Counter
-
A value that only increases, such as the number of sessions created.
- Gauge
-
A value sampled at a point in time, such as the number of active sessions.
- Timer
-
Records both a count of events and the distribution of their durations.
- Distribution summary
-
Records both a count of events and the distribution of a non-time measurement, such as the number of rows read from a query.
Session Metrics
Controlled by vaadin.observability.sessions.
| Meter | Type | Description |
|---|---|---|
| Gauge | Currently active sessions. |
| Counter | Sessions created since startup. |
| Timer | Session lifetime, recorded when a session ends. |
| Timer | Time spent waiting to acquire the session lock.
Tagged by |
| Timer | Time the session lock is held.
Tagged by |
The context tag is request when the lock is taken during request handling, or access when it’s taken through UI.access().
UI Metrics
Controlled by vaadin.observability.uis.
| Meter | Type | Description |
|---|---|---|
| Gauge | Currently active UIs. |
| Counter | UIs created since startup. |
Navigation Metrics
Controlled by vaadin.observability.navigation.
| Meter | Type | Description |
|---|---|---|
| Timer | Navigation duration, from |
A navigation is recorded when it completes, so outcome is currently always success.
When a beforeEnter() listener reroutes or forwards, the navigation is recorded once, against the route it ended up on.
Request Metrics
Controlled by vaadin.observability.requests.
| Meter | Type | Description |
|---|---|---|
| Timer | Server-side request handling time.
Tagged by |
| Timer | Server-side RPC invocation time.
Tagged by |
|
Note
|
Extra Request Tags When Tracing Is Enabled
With tracing on — the default — |
Resync Metrics
Controlled by vaadin.observability.resync.
These track UIDL message-recovery events, which indicate a flaky client-server connection.
| Meter | Type | Description |
|---|---|---|
| Counter | Client-server message-recovery events.
Tagged by |
Error Metrics
Controlled by vaadin.observability.errors.
| Meter | Type | Description |
|---|---|---|
| Counter | Exceptions that propagate out of Vaadin request handling.
Tagged by |
|
Important
|
What This Counter Does and Doesn’t Count
This counter tracks exceptions that escape request handling — for example one thrown by a custom |
Client Metrics
Controlled by vaadin.observability.client.
These are observed in the browser and reported back to the server, subject to the per-session rate limit (see vaadin.observability.client-rate-per-session).
| Meter | Type | Description |
|---|---|---|
| Timer | Browser application bootstrap time. |
| Timer | Browser-observed navigation time. |
| Timer | Largest Contentful Paint. |
| Timer | First Contentful Paint. |
| Counter | Errors reported by the browser. |
| Counter | Client samples dropped before recording. |
| Counter | Client samples rejected by the per-session rate limit. |
Server round-trip timing isn’t collected in the browser.
Use the server-side vaadin.request.duration and vaadin.rpc.duration timers for that.
Database Metrics
Controlled by vaadin.observability.database (off by default, Spring Boot starter only).
When enabled, every DataSource bean is wrapped so that JDBC access — Spring Data, JdbcTemplate, or raw JDBC — is measured, attributed to the Vaadin route that triggered it.
See Database Monitoring for how this works and when to use it.
| Meter | Type | Description |
|---|---|---|
| Distribution summary | Rows read from a JDBC result set.
Tagged by |
| Timer | JDBC query duration.
Tagged by |
Common Tag Values
| Tag | Values |
|---|---|
|
|
| The target route template.
Distinct values are capped by |
|
|
| On RPC meters and spans, the RPC invocation type as reported by Flow.
On |
| The simple class name of the handled exception. |
|
Note
|
JVM, Process, and Connection-Pool Metrics
Observability Kit doesn’t record JVM, process, or database connection-pool metrics itself.
Those come from Micrometer’s standard binders — Spring Boot Actuator registers them out of the box, and you can add others as needed.
The kit’s own database metrics above measure query behavior per route, not the connection pool.
|
Tracing
When tracing is enabled (vaadin.observability.traces, the default) and an ObservationRegistry is available, the kit drives the core request lifecycle through the Observation API.
Each observation produces a tracing span and, through Micrometer’s DefaultMeterObservationHandler, the matching timer above — one measurement, recorded two ways.
To export spans, add a Micrometer tracing bridge (for example OpenTelemetry or Zipkin); see the Integrations page.
The kit produces the following spans:
| Span | Description |
|---|---|
| The root span for each Vaadin request. Carries the request-level attributes below. |
| A navigation, nested under the request that triggered it. |
| A server-side RPC invocation (DOM event, |
| A single JDBC query, nested under the request or RPC span that ran it. Emitted only when database monitoring is enabled (see Database Monitoring). |
Spans cover work done on the request-handling thread.
Work handed to another thread — for example a background task that later calls UI.access() — isn’t linked to the request that started it, and the UI.access() command itself is recorded under whichever request thread runs it.
Span Attributes
The root vaadin.request span carries these attributes:
| Attribute | Description |
|---|---|
| The protocol-level request type: |
| What the request actually did: |
| The HTTP method of the request. |
|
|
| The ID of the UI associated with the request, or |
| The browser location the request was sent from, or |
The nested spans carry the tags of their corresponding meters: vaadin.navigation <route> carries route and outcome; vaadin.rpc.<type> carries type.
The RPC span additionally carries two span-only, high-cardinality attributes when they can be resolved: vaadin.rpc.event (the invocation name, such as a DOM event name, invoked method name, or navigation location) and vaadin.rpc.component (the class name of the targeted Component).
These are attached to the span only, never as timer tags, because of their cardinality.
Together they let you trace a failure back to the interaction that caused it — which component, and which event.
Flow doesn’t report an invocation name for property syncs, which is how a field’s value change arrives at the server.
Those spans carry type and vaadin.rpc.component, but no vaadin.rpc.event.
The vaadin.db.query span carries route, a db.rows attribute with the number of rows read, and — when vaadin.observability.database-statement is enabled — the parameterized SQL as db.statement.
Errors
When a request or a nested operation fails, its observation is marked as error, so the span records the exception and the outcome tag becomes error.
For an exception thrown inside a component listener, this happens on the vaadin.rpc.<type> span — the one that also carries the component and event — rather than on the enclosing vaadin.request span, which still ends as success.
Flow hands such an exception to the session’s ErrorHandler instead of letting it escape request handling, which is also why it doesn’t increment the vaadin.errors counter.
See Error Metrics for what that counter measures.
Database Monitoring
With the Spring Boot starter, the kit can watch how many rows your queries return and how long they take, without touching application code. Enable it with:
Source code
application.properties
application.propertiesvaadin.observability.database=trueEvery DataSource bean is then wrapped so that each JDBC ResultSet reports its row count into the vaadin.db.fetch.rows distribution summary, tagged by the Vaadin route that triggered the fetch.
This lets you see which view issues the large reads.
Watch the p95/p99 of that summary and alert on it in your backend — for example a Prometheus rule on vaadin_db_fetch_rows — to catch runaway result sets in production.
This is off by default: it reaches outside the Vaadin runtime into the persistence layer and adds a small per-row cost.
It covers all JDBC access — Spring Data, JdbcTemplate, and raw JDBC — that flows through a managed DataSource.
Row counting is best-effort and attributes to _unknown when no view is active, such as for background tasks.
Locating Slow or Large Queries in a Trace
When tracing is also enabled (vaadin.observability.traces=true, the default), each query additionally opens a vaadin.db.query span.
Because it starts on the request-handling thread inside the Vaadin request span, it nests under that request or RPC span automatically.
In Jaeger — or any backend fed by your Micrometer tracing bridge — you can open a slow interaction and see the individual queries it ran, each carrying the route and a db.rows attribute.
The same observation also yields a vaadin.db.query duration timer: database time per view.
The span doesn’t include the SQL text by default.
Set vaadin.observability.database-statement=true to attach the parameterized statement as db.statement.
This is useful for pinpointing the offending query, but it’s opt-in because SQL is higher cardinality and can be sensitive.
Extending Built-In Instrumentation
To record your own metrics and spans alongside these, see the Custom Instrumentation page. Custom meters and spans share the same registry and backend, so keep your names and tag cardinality consistent with the conventions above.
4E9CED65-0EA1-4590-956A-6198F0F90482