Collect Logs & Metrics
Spring Boot writes the application log to the console, and Spring Boot Actuator, which you added in Add Health Checks, collects metrics with Micrometer. This guide shows how to make both useful in production, and what to watch in a Vaadin application.
Write Logs for Machines
In a container, write the log to the console, which is the default. The container platform collects it from there. To make it easier for a log management system to parse, switch to a structured JSON format:
Source code
application-prod.properties
application-prod.propertieslogging.structured.format.console=ecsEach log event is then written as one line of JSON. Besides ecs for the Elastic Common Schema, Spring Boot supports logstash and gelf. See Structured Logging for details.
To change a log level without rebuilding the application, set an environment variable. For example, LOGGING_LEVEL_COM_EXAMPLE=DEBUG sets the level of the com.example package to DEBUG.
What to Look for in a Vaadin Application
-
Unexpected errors. By default, when a listener throws an exception, Vaadin logs it, but the user sees nothing. The Handle Errors guide logs each error with a short ID, and shows the same ID to the user. When a user reports a problem, you can find the matching log entry.
-
Resynchronization warnings. Vaadin logs a warning when it has to resynchronize the UI of a browser tab. If the warnings are frequent, check the network, the proxies, and the load balancers between the browsers and the server. See When the Copies Drift Apart.
-
Missing context. If a servlet filter adds information to every log message, such as a request ID or the user name, the information is missing from messages logged in background threads. With the
WEBSOCKETpush transport, it’s also missing from messages logged in listeners, because the events from the browser don’t pass through servlet filters. See What Happens When a User Clicks a Button.
Expose Metrics
To let a monitoring system collect the metrics, add the Micrometer registry for it. For Prometheus, add the following dependency:
Source code
pom.xml
pom.xml<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<scope>runtime</scope>
</dependency>Then expose the prometheus endpoint, together with health, on a separate port:
Source code
application-prod.properties
application-prod.propertiesmanagement.server.port=8081
management.endpoints.web.exposure.include=health,prometheusPrometheus can then collect the metrics from /actuator/prometheus on port 8081. Don’t make that port reachable from the internet: don’t forward it in the reverse proxy, or publish it from the container. Metrics reveal details of your application that users have no reason to see.
The health endpoints move to port 8081 too, so update the health checks from Add Health Checks.
Give Actuator Its Own Security Configuration
If the application uses Spring Security, the requests to the management port pass through the security configuration as well. The Vaadin security configuration can’t handle them, and they fail with status 500. Add a separate security filter chain for the Actuator endpoints:
Source code
SecurityConfig.java
SecurityConfig.java@Bean
@Order(1) 1
SecurityFilterChain managementSecurityFilterChain(HttpSecurity http)
throws Exception {
http.securityMatcher(EndpointRequest.toAnyEndpoint())
.authorizeHttpRequests(auth -> auth.anyRequest().permitAll()); 2
return http.build();
}-
Makes this filter chain handle the Actuator requests before the Vaadin filter chain.
-
Allows all requests to the Actuator endpoints.
|
Warning
|
This filter chain allows everyone to use every exposed Actuator endpoint. It’s safe only when the endpoints are on a separate port that users can’t reach. Without management.server.port, the endpoints are on the same port as the application, and this filter chain makes them public.
|
Keep the Probes on the Application Port
A check against the management port can succeed even when the application port no longer accepts requests. For this reason, Spring Boot recommends serving the liveness and readiness checks on the application port as well:
Source code
application-prod.properties
application-prod.propertiesmanagement.endpoint.health.probes.add-additional-paths=trueThis adds /livez and /readyz to the application port. Allow them in the Vaadin security configuration, as in Allow the Health Checks Through Security, but with the following request matcher:
Source code
Java
.requestMatchers(EndpointRequest.toAdditionalPaths(
WebServerNamespace.SERVER, "health")).permitAll()Know Which Metrics to Watch
Spring Boot and Micrometer record metrics for the JVM, the web server, the database connection pool, and more. In a Vaadin application, start with the following ones. The names are as they appear in Prometheus:
tomcat_sessions_active_current_sessions-
The number of sessions in memory. Each session holds the UI state of one user. The number is usually higher than the number of people using the application, as explained in Count Sessions, Not Users. To change how long sessions stay, see Decide How Long Sessions Live.
jvm_memory_used_bytes{area="heap"}andjvm_gc_pause_seconds-
The memory used by the heap, where the UI state lives, and the time spent in garbage collection. If the heap stays close to its maximum, the application is running out of memory.
http_server_requests_seconds-
The number and duration of HTTP requests. All requests that Vaadin handles, such as page loads and round trips from the UI, have the
uri="/**"tag. The metric therefore shows how fast the application responds overall, but not which view is slow. logback_events_total{level="error"}-
The number of errors logged. Alert when it starts to grow.
For metrics about Vaadin itself, such as the number of active UIs, how long requests wait for the session lock, and how long Vaadin takes to handle each request, see Observability Kit. It records them in the same Micrometer registry.
To find out how much memory your application needs per session, and how fast it responds under load, before you go to production, see Measure Capacity and Test Failover.
Next Steps
Each guide so far has added a step to building and deploying the application. Build on CI runs these steps automatically on every change.