1. Overview
This tutorial will show how to register a jakarta.servlet.http.HttpSessionListener and track the number of active sessions in the web application using metrics.
2. Defining the Listener
We can register the HTTP Session listener in the web.xml:
<web-app ...>
<listener>
<listener-class>com.baeldung.web.SessionListenerWithMetrics</listener-class>
</listener>
</web-app>
Alternatively, in a Servlet 3 environment, we can use the @WebListener to register the listener as well. In this case, we need to annotate the main SpringBootApplication class with @ServletComponentScan.
Finally, we can also register the listener using Java configuration by declaring a ServletListenerRegistrationBean bean:
@Bean
public ServletListenerRegistrationBean<SessionListenerWithMetrics> sessionListenerWithMetrics() {
ServletListenerRegistrationBean<SessionListenerWithMetrics> listenerRegBean =
new ServletListenerRegistrationBean<>();
listenerRegBean.setListener(new SessionListenerWithMetrics());
return listenerRegBean;
}
3. The Basic Listener
The simple listener will keep track of the number of active sessions at all times:
public class SessionListenerWithMetrics implements HttpSessionListener {
private final AtomicInteger activeSessions;
public SessionListenerWithMetrics() {
super();
activeSessions = new AtomicInteger();
}
public int getTotalActiveSession() {
return activeSessions.get();
}
public void sessionCreated(final HttpSessionEvent event) {
activeSessions.incrementAndGet();
}
public void sessionDestroyed(final HttpSessionEvent event) {
activeSessions.decrementAndGet();
}
}
The session listener will be triggered when the session is created – sessionCreated:
HttpSession session = request.getSession();
And destroyed – sessionDestroyed:
session.invalidate();
This mechanism allows the current session count to be retrieved from the listener, but in order to have real-time monitoring and transparency, we need additional logic to actually retrieve the value and publish it.
This is where the metrics library comes in – it comes with several out of the box reporters that allow this metric to be published with very little effort.
4. The Listener With Metrics
So, instead of rolling out our own custom monitoring solution, we’ll leverage the metrics library; we’ll need to add it to our pom:
<dependency>
<groupId>com.codahale.metrics</groupId>
<artifactId>metrics-core</artifactId>
<version>4.2.21</version>
</dependency>
With metrics core is available on the classpath, we can write the same HttpSessionListener using a Counter object:
public class SessionListenerWithMetrics implements HttpSessionListener {
private final Counter counterOfActiveSessions;
public SessionListenerWithMetrics() {
super();
counterOfActiveSessions = MetricRegistrySingleton.metrics.counter("web.sessions.active.count");
}
public void sessionCreated(final HttpSessionEvent event) {
counterOfActiveSessions.inc();
}
public void sessionDestroyed(final HttpSessionEvent event) {
counterOfActiveSessions.dec();
}
}
The MetricRegistry – the central registry of all application metrics – is simply referenced in an application wide static field:
public final class MetricRegistrySingleton {
public static final MetricRegistry metrics = new MetricRegistry();
}
Publishing this metric and making it readily available to be monitored – for example to the standard logging system of the application – is straightforward:
Logger logger = LoggerFactory.getLogger("com.baeldung.monitoring");
Slf4jReporter reporter = Slf4jReporter.forRegistry(metrics).outputTo(logger).
convertRatesTo(TimeUnit.SECONDS).convertDurationsTo(TimeUnit.MILLISECONDS).build();
reporter.start(5, TimeUnit.MINUTES);
5. Conclusion
This tutorial illustrated how to register a HttpSessionListener in the deployment descriptor of the web application and how to monitor the active number of sessions using two mechanisms. The first mechanism is a hand-rolled counter and the second is based on the mature metrics library.
The implementation can be found in the example GitHub project.