Using micrometer in a Vaadin page / component

Hi,

Wanting statistics on how often pages are navigated to, we built a listener like this:

@Component
public class PageMetrics implements AfterNavigationListener {
  // transient because meter is not serializable
  private transient Meter.MeterProvider<Counter> pageViewCounter;

  public PageMetrics(MeterRegistry meterRegistry) {
    this.pageViewCounter =
        Counter.builder("pageviews").withRegistry(meterRegistry);
  }

  @Override
  public void afterNavigation(AfterNavigationEvent event) {
    String route = event.getLocation().getPath();
    if (route.isEmpty()) {
      route = "/";
    }
    pageViewCounter.withTag("page", sanitize(route)).increment();
  }
.....
}

And then in a VaadinServiceInitListener we do

@AllArgsConstructor
@Component
public class VaadinServiceInitializer implements VaadinServiceInitListener {

  private final PageMetrics pageMetrics;

  @Override
  public void serviceInit(ServiceInitEvent event) {
    event
        .getSource()
        .addUIInitListener(
            uiInitEvent -> uiInitEvent.getUI().addAfterNavigationListener(pageMetrics));

However, because the meter is transient, when a session is deserialized the pageViewCounter is null and we get NPE. I thought that Vaadin/Spring would take care of executing and reinjecting the constructor again but it does not. So i’m wondering how people are using micrometer classes in their components, if anyone does this ?

Constructors are never called during deserialization.
If using KubernetesKit, an idea could be to have MeterRegistry as transient field and lazy initialize pageViewCounter in afterNavigation; the MeterRegistry bean will be injected into the field bt the Kit when deserialization is completed.

Indeed, that seems it would work.

What if all of your views extend a parent that implements before enter. Then use that method to log the access.