From eeb5a2eb3b73c088be2e680437c1f3233a506839 Mon Sep 17 00:00:00 2001 From: Giovanni Lovato Date: Tue, 9 Jun 2026 14:26:19 +0200 Subject: [PATCH 1/3] docs: add README with kit overview, setup, configuration and metrics --- README.md | 226 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..05d5902 --- /dev/null +++ b/README.md @@ -0,0 +1,226 @@ +# Vaadin Observability Kit + +Production telemetry for [Vaadin Flow](https://vaadin.com) applications, built on +[Micrometer](https://micrometer.io). The kit instruments the Vaadin runtime — +sessions, UIs, navigation, requests, errors and real browser-side timing — and +records everything into your application's `MeterRegistry`, so it shows up in +whatever backend you already use (Prometheus, OTLP, Graphite, …). Tracing spans +are emitted through the Micrometer Observation API. + +It is a drop-in: with Spring Boot you **add one dependency and you're done** — no +code, no annotations, no configuration required. + +> Observability Kit is a commercial Vaadin product. See [License](#license). + +## Requirements + +- Java 21 or newer +- Vaadin 25.3 or newer (Flow 25.3+) +- A Micrometer `MeterRegistry` — the Spring Boot starter provides one out of the box +- Spring Boot 4 (only for the `observability-kit-starter`; plain-Spring and + standalone setups are also supported) + +## Getting started (Spring Boot) + +Add the starter: + +```xml + + com.vaadin + observability-kit-starter + 5.0-SNAPSHOT + +``` + +That's the whole setup. On startup the kit auto-configures a `MeterRegistry` +(through Spring Boot's Micrometer support) and wires the Vaadin instrumentation +onto it. Sessions, UIs, navigation, request handling, errors and client-side +timing all start recording automatically. + +### Exposing the metrics + +The kit *records* into a registry; to *export* the metrics, add Spring Boot +Actuator and the registry backend of your choice — for example Prometheus: + +```xml + + org.springframework.boot + spring-boot-starter-actuator + + + io.micrometer + micrometer-registry-prometheus + +``` + +```properties +management.endpoints.web.exposure.include=prometheus +``` + +The metrics are then available at `GET /actuator/prometheus`. + +## Working with the metrics in your application + +Everything the kit records lives in the application `MeterRegistry`. You can read +it from anywhere a bean is injectable — including a Vaadin view — and record your +own meters right alongside the built-in ones: + +```java +@Route("latency") +public class LatencyView extends VerticalLayout { + + private static final String SERVER_TIMER = "vaadin.request.duration"; + + private final transient MeterRegistry registry; + + public LatencyView(MeterRegistry registry) { + this.registry = registry; + + add(new Button("Do work", e -> timed("do-work", () -> doWork()))); + add(new Button("Show server timing", e -> { + Timer timer = registry.find(SERVER_TIMER).timer(); + if (timer != null) { + Notification.show("%d requests, max %.0f ms".formatted( + timer.count(), timer.max(TimeUnit.MILLISECONDS))); + } + })); + } + + /** Record a custom timer next to the kit's built-in meters. */ + private void timed(String action, Runnable work) { + Timer.Sample sample = Timer.start(registry); + try { + work.run(); + } finally { + sample.stop(registry.timer("app.interaction", "action", action)); + } + } +} +``` + +The built-in server-side request timer is `vaadin.request.duration`; the +browser-observed round trip (when client metrics are enabled) is +`vaadin.client.rpc.duration`. See [Metrics](#metrics) for the full list. + +## Other setups + +### Plain Spring (without Spring Boot) + +Add the Spring module, import the configuration, and provide a `MeterRegistry` +bean: + +```xml + + com.vaadin + observability-kit-spring + 5.0-SNAPSHOT + +``` + +```java +@Configuration +@Import(ObservabilityConfiguration.class) +class ObservabilityConfig { + + @Bean + MeterRegistry meterRegistry() { + return new SimpleMeterRegistry(); + } +} +``` + +### Standalone (without Spring) + +Add the core module and install the kit once at startup, before the +`VaadinService` initializes: + +```xml + + com.vaadin + observability-kit-micrometer + 5.0-SNAPSHOT + +``` + +```java +MeterRegistry registry = new SimpleMeterRegistry(); +ObservabilityKit.install(registry, ObservabilitySettings.builder().build()); +``` + +## Configuration + +Every feature is enabled by default. With the Spring Boot starter, configure the +kit through `vaadin.observability.*` properties: + +```properties +# Turn the whole kit off +vaadin.observability.enabled=false + +# Or toggle individual feature groups +vaadin.observability.client=false +vaadin.observability.traces=false +``` + +| Property | Default | Description | +| --- | --- | --- | +| `vaadin.observability.enabled` | `true` | Master switch for the auto-configuration. | +| `vaadin.observability.sessions` | `true` | Session count, lifetime and lock metrics. | +| `vaadin.observability.uis` | `true` | UI count metrics. | +| `vaadin.observability.navigation` | `true` | Navigation timing. | +| `vaadin.observability.requests` | `true` | Server-side request and RPC timing. | +| `vaadin.observability.errors` | `true` | Error counters. | +| `vaadin.observability.client` | `true` | Browser-side timing collected from the client. | +| `vaadin.observability.traces` | `true` | Emit tracing spans via the Observation API. | +| `vaadin.observability.traces-session-id` | `false` | Include the session id as a span attribute. | +| `vaadin.observability.route-cardinality-limit` | `200` | Maximum number of distinct `route` tag values before they collapse to `_other`. | +| `vaadin.observability.client-rate-per-session` | `100` | Maximum client-side samples accepted per session (throttling guard). | + +For plain Spring the same keys are read via `@Value`; for standalone use, build an +`ObservabilitySettings` with the matching builder methods: + +```java +ObservabilitySettings.builder() + .client(false) + .traces(false) + .routeCardinalityLimit(500) + .build(); +``` + +## Metrics + +| Meter | Type | Description | +| --- | --- | --- | +| `vaadin.sessions.active` | Gauge | Currently active sessions. | +| `vaadin.sessions.created` | Counter | Sessions created. | +| `vaadin.sessions.duration` | Timer | Session lifetime. | +| `vaadin.session.lock.wait` | Timer | Time spent waiting to acquire the session lock. | +| `vaadin.session.lock.hold` | Timer | Time the session lock is held. | +| `vaadin.ui.active` | Gauge | Currently active UIs. | +| `vaadin.ui.created` | Counter | UIs created. | +| `vaadin.navigation` | Timer | Navigation duration (tagged by `route`, `outcome`). | +| `vaadin.request.duration` | Timer | Server-side request handling time. | +| `vaadin.rpc.duration` | Timer | Server-side RPC invocation time (tagged by `type`). | +| `vaadin.errors` | Counter | Server-side errors (tagged by `exception`). | +| `vaadin.client.bootstrap.duration` | Timer | Browser application bootstrap time. | +| `vaadin.client.navigation.duration` | Timer | Browser-observed navigation time. | +| `vaadin.client.rpc.duration` | Timer | Browser-observed server round trip. | +| `vaadin.client.web_vitals.lcp` | Timer | Largest Contentful Paint. | +| `vaadin.client.web_vitals.fcp` | Timer | First Contentful Paint. | +| `vaadin.client.errors` | Counter | Errors reported by the browser. | +| `vaadin.client.dropped` | Counter | Client samples dropped before recording. | +| `vaadin.client.throttled` | Counter | Client samples rejected by the per-session rate limit. | + +## Tracing + +When tracing is enabled (the default) and an `ObservationRegistry` is available, +the kit emits spans through the Micrometer Observation API for the Vaadin request +lifecycle, navigation and RPC. Spring Boot Actuator supplies an +`ObservationRegistry` automatically; the standalone bootstrap creates one for you. +To export the spans, add a Micrometer tracing bridge (for example OpenTelemetry or +Zipkin) as you would for any Micrometer-instrumented application. Set +`vaadin.observability.traces=false` to disable span emission. + +## License + +Observability Kit is available under the Vaadin Commercial License and Service +Terms. See . From 299e97e66abbd14afa98a8163799dc1f65f25e53 Mon Sep 17 00:00:00 2001 From: Giovanni Lovato Date: Wed, 10 Jun 2026 11:04:47 +0200 Subject: [PATCH 2/3] Update README.md Co-authored-by: caalador --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 05d5902..2231916 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Vaadin Observability Kit -Production telemetry for [Vaadin Flow](https://vaadin.com) applications, built on +Production telemetry for [Vaadin Flow](https://vaadin.com) applications, using [Micrometer](https://micrometer.io). The kit instruments the Vaadin runtime — sessions, UIs, navigation, requests, errors and real browser-side timing — and records everything into your application's `MeterRegistry`, so it shows up in From 96a68c54dabc51885878689495e5f5e10971a63c Mon Sep 17 00:00:00 2001 From: Giovanni Lovato Date: Wed, 10 Jun 2026 11:06:55 +0200 Subject: [PATCH 3/3] docs: install standalone kit from a ServletContextListener MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The standalone example showed a bare ObservabilityKit.install(...) with no indication of where it must run. It has to complete before the VaadinService initializes, so show it in a @WebListener ServletContextListener — matching the kit's own standalone setup (caalador review). --- README.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2231916..73ce7af 100644 --- a/README.md +++ b/README.md @@ -131,7 +131,8 @@ class ObservabilityConfig { ### Standalone (without Spring) -Add the core module and install the kit once at startup, before the +Add the core module and install the kit at servlet-context startup — for example +from a `ServletContextListener` — so the registry is in place before the `VaadinService` initializes: ```xml @@ -143,8 +144,16 @@ Add the core module and install the kit once at startup, before the ``` ```java -MeterRegistry registry = new SimpleMeterRegistry(); -ObservabilityKit.install(registry, ObservabilitySettings.builder().build()); +@WebListener +public class ObservabilitySetup implements ServletContextListener { + + @Override + public void contextInitialized(ServletContextEvent event) { + MeterRegistry registry = new SimpleMeterRegistry(); + ObservabilityKit.install(registry, + ObservabilitySettings.builder().build()); + } +} ``` ## Configuration