Docs

Migrating to Version 5

How to move a Vaadin application from the version 4 OpenTelemetry agent to the Micrometer-based version 5 of Observability Kit.

Observability Kit 5 is a ground-up rewrite. Earlier versions shipped as a standalone OpenTelemetry Java agent that you attached to the JVM and configured through an agent.properties file. Version 5 is a plain Micrometer library: you add it as a dependency, and it records into your application’s MeterRegistry and emits tracing spans through the Micrometer Observation API.

The practical upshot is that, with Spring Boot, the kit becomes a true drop-in — add one dependency and you’re done. There’s no agent to download, no -javaagent flag, and no separate configuration file. In exchange, the telemetry now flows through Spring Boot Actuator and the Micrometer registry backends you already use, rather than through the kit’s own OpenTelemetry exporters.

This page describes what changed and how to move an existing version 4 setup to version 5.

Important
Breaking Change
Version 5 is not a drop-in replacement for version 4. Meter names, the configuration model, the tracing data, and the custom-instrumentation API have all changed. Plan to update your dashboards, alerts, and any custom instrumentation as part of the upgrade.

What Changed at a Glance

Version 4 (OpenTelemetry agent) Version 5 (Micrometer)

Packaging

A separate agent JAR, downloaded manually, plus a starter dependency.

A single Maven dependency. No agent, no manual download.

Startup

-javaagent:observability-kit-agent.jar on the JVM command line.

Nothing — the kit auto-configures on the classpath.

Telemetry pipeline

OpenTelemetry SDK, exported directly to a backend or collector over OTLP.

Micrometer MeterRegistry for metrics, Observation API for traces.

Export

Built into the agent and configured in agent.properties.

Spring Boot Actuator plus a Micrometer registry of your choice.

Configuration

agent.properties, OTEL_* environment variables, or otel.* system properties.

vaadin.observability.* Spring properties, or an ObservabilitySettings builder.

Frontend

@hilla/observability-kit-client npm package, initialized with init().

Built in and server-side. No npm package, no client code.

Custom instrumentation

OpenTelemetry API — @WithSpan, GlobalOpenTelemetry, Tracer.

Micrometer — @Observed/@Timed, MeterRegistry, Observation API.

Requirements

Java 21+.

Java 21+, Vaadin 25.3+, and Spring Boot 4 for the starter.

Step 1: Update Dependencies

Remove the agent and switch the dependency to the module that matches your deployment.

Spring Boot

For a Spring Boot application, keep the starter but update its version. Boot’s Micrometer auto-configuration does the rest.

Source code
pom.xml
<dependency>
    <groupId>com.vaadin</groupId>
    <artifactId>observability-kit-starter</artifactId>
</dependency>

To actually export the metrics, add Spring Boot Actuator and the registry backend you want. The kit only records into the registry; it no longer exports anything itself. For example, for Prometheus:

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>
Source code
application.properties
management.endpoints.web.exposure.include=prometheus

The metrics are then served at GET /actuator/prometheus.

Plain Spring

Use the observability-kit-spring module, import the configuration, and supply a MeterRegistry bean. See the Getting Started page for details.

Standalone (Without Spring)

Use the observability-kit-micrometer module and install the kit at servlet-context startup, before VaadinService initializes:

Source code
Java
ObservabilityKit.install(meterRegistry,
        ObservabilitySettings.builder().build());

Step 2: Remove the Agent

Delete everything related to the version 4 agent:

  • The downloaded observability-kit-agent-*.jar file.

  • The -javaagent:…​/observability-kit-agent.jar argument from every launch command, container image, and run configuration.

  • The agent.properties file (its settings are migrated in Step 4).

  • Any OTEL_* environment variables or -Dotel.* system properties used to configure the agent.

With the new version there is no longer anything to download or attach. The kit activates by being on the classpath.

Step 3: Remove the Frontend Package

Version 4 required a separate client package for frontend observability. In version 5, browser-side timing is built in and collected through a server-side channel, so the npm package and its initialization code are gone.

Remove the dependency and the init() call:

  • Uninstall @hilla/observability-kit-client.

  • Delete the import { init } from '@hilla/observability-kit-client' block and the init(…​) call from frontend/index.ts.

Client-side instrumentation is now enabled by default and toggled with a single property, vaadin.observability.client.

Step 4: Migrate Configuration

Move settings out of agent.properties and into vaadin.observability.* Spring properties (or, for standalone, the ObservabilitySettings builder). The configuration model is much smaller: instead of OpenTelemetry’s fine-grained instrumentation switches, version 5 exposes a handful of feature toggles.

Version 4 Version 5

otel.instrumentation.vaadin.frontend.enabled

vaadin.observability.client

otel.instrumentation.vaadin.frontend.* (per-module toggles)

No equivalent — client instrumentation is a single on/off toggle.

Tracing on/off (agent-level)

vaadin.observability.traces

(no equivalent)

vaadin.observability.sessions, .uis, .ui-state, .navigation, .requests, .data, .errors, .resync, .database, .insights

otel.service.name, otel.resource.attributes

Configured through Spring/Micrometer (for example spring.application.name and your registry’s common tags or OTLP resource settings), not through the kit.

A typical version 5 configuration:

Source code
application.properties
# Turn the whole kit off
vaadin.observability.enabled=false

# Or toggle individual feature groups
vaadin.observability.client=false
vaadin.observability.traces=false

Everything that instruments ordinary request handling is enabled by default, so most applications need no configuration at all. The opt-in features are UI state size, database monitoring, and the two detail toggles that would add sensitive or high-cardinality data to what leaves the application. For the complete list of properties, see the Configuration page.

Note
Service Identity Moves to Micrometer
The service.name, service.namespace, and related OpenTelemetry resource attributes are no longer set on the kit. Service identity is now part of your Micrometer/Actuator setup — for example, common registry tags or the OTLP exporter’s resource configuration. Set them there so every meter and span is tagged consistently.

Step 5: Update Custom Instrumentation

If you wrote custom traces or metrics with the OpenTelemetry API, port them to Micrometer. The concepts map closely.

Version 4 (OpenTelemetry) Version 5 (Micrometer)

@WithSpan

@Observed (timer + span) or @Timed (timer only)

@SpanAttribute("key")

lowCardinalityKeyValues = { "key", "value" } on @Observed, or a tag on the meter

GlobalOpenTelemetry.getTracer(…​) + Span

Observation from an injected ObservationRegistry

Meter / LongCounter / gaugeBuilder

Counter / Gauge / Timer builders, or MeterRegistry shortcuts

For example, a manually traced method:

Source code
Version 4 — OpenTelemetry
Tracer tracer = GlobalOpenTelemetry.getTracer("app-instrumentation", "1.0");
Span span = tracer.spanBuilder("My Task").startSpan();
try {
    doWork();
} finally {
    span.end();
}
Source code
Version 5 — Micrometer Observation
Observation.createNotStarted("app.task", observationRegistry)
        .contextualName("my-task")
        .observe(() -> doWork());

Because the kit records into the same registry and Observation API, your custom meters and spans sit alongside the built-in ones and export through the same backend. For the full set of options — annotations, fluent builders, and raw registry beans — see the Customization page.

Note
AOP Required for Annotations
The @Observed, @Timed, and @Counted annotations are backed by Spring AOP aspects. Add spring-boot-starter-aop (or register the aspects yourself in plain Spring) for them to take effect. The version 4 @WithSpan annotation worked through the agent and needed no AOP.

Step 6: Update Dashboards and Alerts

Meter names changed, so any saved queries, dashboards, and alerts must be updated. The most common renames:

Version 4 Version 5 Notes

vaadin.session.count (Gauge)

vaadin.sessions.active (Gauge)

vaadin.session.duration (Histogram)

vaadin.sessions.duration (Timer)

vaadin.ui.count (Gauge)

vaadin.ui.active (Gauge)

(none)

vaadin.sessions.created, vaadin.ui.created

New counters.

(none)

vaadin.navigation, vaadin.request.duration, vaadin.rpc.duration, vaadin.errors

New server-side timers and error counter.

(none)

vaadin.session.lock.wait, vaadin.session.lock.hold

New session-lock timers.

(none)

vaadin.data.count.duration, vaadin.data.fetch.duration, vaadin.data.fetch.requested, vaadin.data.fetch.rows

New data provider query timers and page sizes for lazy-loading components.

(none)

vaadin.ui.state.*, vaadin.session.state.nodes.max, vaadin.session.uis.max

New, opt-in gauges of retained UI state, for capacity planning.

(none)

vaadin.client.*

Browser-observed timing (bootstrap, navigation, Web Vitals, errors).

(none)

vaadin.resync

New counter of UIDL message resends and client-requested resynchronizations.

(none)

vaadin.db.fetch.rows, vaadin.db.query

New, opt-in per-route database metrics. Spring Boot starter only.

db.client.connections.*

Use Micrometer’s own pool metrics

No longer emitted by the kit. Spring Boot/Micrometer instrument the connection pool directly.

process.runtime.jvm.*

Use Micrometer’s JVM binders

No longer emitted by the kit. Actuator registers JVM and process metrics out of the box.

For the complete, current list of meters, see the Reference page.

Important
Queries Break Structurally, Not Only by Name

Three export-level changes affect existing queries and alerts beyond the renames above:

  • The version 4 agent exported OpenTelemetry histograms with buckets. Version 5 timers publish count, sum, and max only, so a histogram_quantile() query or a latency alert finds no _bucket series until you enable them per meter — and it fails silently, returning no data rather than an error. See Percentiles and Histogram Buckets.

  • Prometheus strips the reserved _created suffix, so vaadin.sessions.created and vaadin.ui.created appear as vaadin_sessions_total and vaadin_ui_total.

  • With tracing on, each observed timer also publishes a parallel long-task timer (_active series in Prometheus), which roughly doubles the series count for those meters. Account for it when estimating metric volume.

Note
Tracing Data Is Shaped Differently
Version 4 produced a rich span tree with many Vaadin-specific attributes, some of them per element synchronization. Version 5 emits spans for the request lifecycle, navigation, RPC, service-executor tasks, data provider count and fetch queries, and — when database monitoring is on — JDBC queries, through the Observation API. Spans that would have been unbounded as timer tags, such as the invoked component and event, are attached as span-only attributes. Add your own spans with @Observed or the Observation API where you need finer-grained tracing; see Customization.
Note
New in Version 5: Interaction Insights
Version 5 also retains the interactions that failed or ran over the UX budget — and the data provider queries behind a slow component — and serves them, grouped and ready to act on, from an Actuator endpoint. This has no version 4 equivalent, and it’s the fastest way from a user report to a line of code. See the Interaction Insights page.

Step 7: Update Backend Integrations

Because the kit no longer exports telemetry itself, integration with backends now goes through standard Micrometer mechanisms rather than the OpenTelemetry agent’s exporters:

  • Metrics are exported by adding the corresponding micrometer-registry-* dependency (Prometheus, OTLP, Graphite, and others) and exposing it through Actuator.

  • Traces are exported by adding a Micrometer tracing bridge — for example OpenTelemetry (micrometer-tracing-bridge-otel) or Zipkin (micrometer-tracing-bridge-brave) — as you would for any Micrometer-instrumented application.

  • Logs are no longer exported by the kit at all. The version 4 agent could ship them over OTLP; in version 5, route them through your logging pipeline instead — see the vendor pages under Integrations for the options.

Vendors such as Prometheus, Grafana, Datadog, and New Relic are all reachable this way, either through a native Micrometer registry or through an OTLP bridge to an OpenTelemetry collector. See the Integrations page for vendor-specific setup.

Migration Checklist

  • ❏ Remove the observability-kit-agent JAR and the -javaagent flag.

  • ❏ Update or switch the kit dependency to the version 5 module for your deployment.

  • ❏ Add Spring Boot Actuator and a micrometer-registry-* backend to export metrics.

  • ❏ Add a Micrometer tracing bridge if you export traces.

  • ❏ Delete agent.properties and any OTEL_* / otel.* settings.

  • ❏ Re-create any needed settings as vaadin.observability.* properties.

  • ❏ Remove the @hilla/observability-kit-client package and its init() call.

  • ❏ Port custom OpenTelemetry instrumentation to the Micrometer API (add spring-boot-starter-aop if you use the annotations).

  • ❏ Update dashboards, queries, and alerts to the new meter names.

  • ❏ Expose and secure the vaadin Actuator endpoint if you want interaction insights.

  • ❏ Re-verify backend integrations end to end.

A82D8720-A226-41EF-9CC5-3391AE5EF262

Updated