Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Mastering Spring Boot's Actuator | Spring IO 2018

Mastering Spring Boot's Actuator | Spring IO 2018

Spring Boot's Actuator provides a powerful set of production-ready features that have been recently updated for Spring Boot 2.0. In this talk we'll look in detail at the Actuator, focusing on the new features including the new endpoint infrastructure that introduces support for Jersey and Web Flux alongside the existing support for Spring MVC. You'll leave this talk with a detailed understanding of the Actuator and armed with the knowledge required to develop your own endpoints.

Andy Wilkinson

May 25, 2018
Tweet

More Decks by Andy Wilkinson

Other Decks in Programming

Transcript

  1. @ankinson actuator noun mechanical device for moving or controlling something

    Spring Boot Actuator noun module for controlling Spring Boot applications ACTUATOR?
  2. @ankinson SCHEDULED TASKS { "cron" : [ { "runnable" :

    { "target" : "com.example.Processor.processOrders" }, "expression" : "0 0 0/3 1/1 * ?" } ], "fixedDelay" : [ { "runnable" : { "target" : "com.example.Processor.purge" }, "initialDelay" : 5000, "interval" : 5000 } ], "fixedRate" : [ { "runnable" : { "target" : "com.example.Processor.retrieveIssues" }, "initialDelay" : 10000, "interval" : 3000 } ] } /actuator/scheduledtasks Inspired by a proposal from Huang YunKun Builds on top of improvements in Spring Framework 5.0 "cron" : [ { "runnable" : { "target" : "com.example.Processor.processOrders" }, "expression" : "0 0 0/3 1/1 * ?" } "fixedDelay" : [ { "runnable" : { "target" : "com.example.Processor.purge" }, "initialDelay" : 5000, "interval" : 5000 }
  3. @ankinson SESSIONS { "sessions" : [ { "id" : "d66667e1-bcf1-453a-89f2-1d777439c4de",

    "attributeNames" : [ ], "creationTime" : "2018-05-09T11:28:40.594Z", "lastAccessedTime" : "2018-05-09T13:28:28.594Z", "maxInactiveInterval" : 1800, "expired" : false }, { "id" : "85af4f77-319f-4912-8e81-f40c9de63735", "attributeNames" : [ ], "creationTime" : "2018-05-09T01:28:40.593Z", "lastAccessedTime" : "2018-05-09T13:27:55.593Z", "maxInactiveInterval" : 1800, "expired" : false }, { "id" : "4db5efcc-99cb-4d05-a52c-b49acfbb7ea9", "attributeNames" : [ ], "creationTime" : "2018-05-09T08:28:40.594Z", "lastAccessedTime" : "2018-05-09T13:28:03.594Z", "maxInactiveInterval" : 1800, "expired" : false } ] } /actuator/sessions Contributed by Vedran Pavic { "id" : "85af4f77-319f-4912-8e81-f40c9de63735", "attributeNames" : [ ], "creationTime" : "2018-05-09T01:28:40.593Z", "lastAccessedTime" : "2018-05-09T13:27:55.593Z", "maxInactiveInterval" : 1800, "expired" : false }
  4. @ankinson /** * {@link Endpoint} to expose a user's {@link

    Session}s. * * @author Vedran Pavic * @since 2.0.0 */ @Endpoint(id = "sessions") public class SessionsEndpoint { // … } @Endpoint(id = "sessions") http://example.com/actuator/ sessions
  5. @ankinson @ReadOperation public SessionsReport sessionsForUsername(String username) { Map<String, ? extends

    Session> sessions = this.sessionRepository .findByIndexNameAndIndexValue( FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, username); return new SessionsReport(sessions); } @ReadOperation (String username) SessionsReport GET http://example.com/actuator/sessions username ? =alice
  6. @ankinson @ReadOperation public SessionDescriptor getSession(@Selector String sessionId) { Session session

    = this.sessionRepository.findById(sessionId); if (session == null) { return null; } return new SessionDescriptor(session); } @ReadOperation (@Selector String sessionId) SessionDescriptor GET http://example.com/actuator/sessions /{ } sessionId
  7. @ankinson @DeleteOperation public void deleteSession(@Selector String sessionId) { this.sessionRepository.deleteById(sessionId); }

    @DeleteOperation @Selector String sessionId DELETE http://example.com/actuator/sessions /{ } sessionId void
  8. @ankinson @Endpoint(id = "loggers") public class LoggersEndpoint { @WriteOperation public

    void configureLogLevel(@Selector String name, @Nullable LogLevel configuredLevel) { Assert.notNull(name, "Name must not be empty"); this.loggingSystem.setLogLevel(name, configuredLevel); } } @Endpoint(id = “loggers") @WriteOperation void @Selector String name @Nullable LogLevel configuredLevel POST http://example.com/actuator/loggers /{ } name { " ": "DEBUG" } configuredLevel
  9. @ankinson @EndpointWebExtension(endpoint = HealthEndpoint.class) public class HealthEndpointWebExtension { @ReadOperation public

    WebEndpointResponse<Health> getHealth( SecurityContext securityContext) { return this.responseMapper.map( this.delegate.health(), securityContext); } } @EndpointWebExtension(endpoint = HealthEndpoint.class) WebEndpointResponse<Health> SecurityContext securityContext