Save 37% off PRO during our Black Friday Sale! »

Better monitoring with Spring boot Actuator

Better monitoring with Spring boot Actuator

An overview of the features Spring boot actuator has to offer.

804116bef2aa0a22789514d3b7a8f520?s=128

Dimitri

July 27, 2020
Tweet

Transcript

  1. Better monitoring with Spring boot Actuator

  2. What is Spring boot Actuator? • Spring boot library •

    Adds production-ready features • Provides useful endpoints • Both over HTTP and JMX
  3. Which endpoints are there? • Auditevents • Beans • Caches

    • Conditions • Configprops • Env • Flyway • Health • Heapdump • Httptrace • Info • Integrationgraph • Jolokia • Logfile • Loggers • Liquibase • Metrics • Mappings • Prometheus • Scheduledtasks • Sessions • Shutdown • Threaddump
  4. How do I get started?

  5. Add a dependency... <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>

  6. … and configure what you need management: endpoints: web: exposure:

    include: env, info, health, metrics
  7. And… what now?

  8. Visit /actuator { "_links": { "self": { "href": "http://192.168.0.220:8080/actuator", "templated":

    false }, "health": { "href": "http://192.168.0.220:8080/actuator/health", "templated": false } }
  9. Exploring the conditions endpoint

  10. What does it do? • Which autoconfigurations are in use

    • Why are they (not) applied? • What can I do to make it work?
  11. Visit /actuator/conditions { "positiveMatches": {/* ... */}, "negativeMatches": { "RabbitHealthContributorAutoConfiguration":

    { "notMatched": [ { "condition": "OnClassCondition", "message": "@ConditionalOnClass did not find required class 'org.springframework.amqp.rabbit.core.RabbitTemplate'" } ]
  12. Exploring the env endpoint

  13. What does it do? • Which application properties are loaded?

    • Where do these properties come from?
  14. Visit /actuator/env { "activeProfiles": [ "dev" ], "propertySources": [ {

    "name": "applicationConfig: [classpath:/application-dev.yml]", "properties": { "server.port": { "value": 8080, "origin": "class path resource [application-dev.yml]:2:9"
  15. Exploring the health endpoint

  16. What does it do? • Is the database available? •

    Is there enough disk space? • Is Eureka available? • Is Solr available? • Useful for monitoring software • ...
  17. Visit /actuator/health { "status": "UP" }

  18. Showing detailed health info management: endpoint: health: show-details: always

  19. Showing detailed health info { "status": "UP", "components": { "db":

    { "status": "UP", "details": { "database": "DB2 UDB for AS/400", "validationQuery": "SELECT 1 FROM SYSIBM.SYSDUMMY1", "result": 1 } }
  20. Creating a custom health indicator @Component @RequiredArgsConstructor public class GitHubAPIHealthIndicator

    implements HealthIndicator { private final RestTemplate restTemplate; @Override public Health health() { // TODO: implement } }
  21. Creating a custom health indicator try { var result =

    restTemplate.getForEntity("https://api.github.com/", ObjectNode.class); if (result.getStatusCode().is2xxSuccessful() && result.getBody() != null) { return Health.up().build(); } else { return Health.down().withDetail("status", result.getStatusCode()).build(); } } catch (RestClientException ex) { return Health.down().withException(ex).build(); }
  22. Creating a custom health indicator { "status": "UP", "components": {

    "gitHubAPI": { "status": "UP" } } }
  23. Useful for monitoring

  24. Useful for Eureka

  25. Exploring the heapdump endpoint

  26. What does it do? • Returns *.HPROF file • Can

    be imported in JVisualVM, … • Find memory leaks and other peformance issues
  27. Open the *.HPROF file

  28. Exploring the info endpoint

  29. What does it do? • Returns additional information • By

    default empty • Useful in combination with Maven resource filtering
  30. Configuring info info: contributors: Dimitri Mestdagh project-version: @project-version@ build-timestamp: @maven.build.timestamp@

  31. Visit /actuator/info { "contributors": "Dimitri Mestdagh", "project-version": "0.0.1-SNAPSHOT", "build-timestamp": "2020-06-27

    11:52:30" }
  32. Exploring the loggers endpoint

  33. What does it do? • What logging levels are in

    use? • Change runtime logging levels • Useful for debugging
  34. Visit /actuator/loggers { "loggers": { "ROOT": { "configuredLevel": "INFO", "effectiveLevel":

    "INFO" }, "be.g00glen00b": { "configuredLevel": null, "effectiveLevel": "INFO" } } }
  35. Changing the runtime logger levels curl \ --header "Content-Type: application/json"

    \ --request POST \ --data '{"configuredLevel": "DEBUG"}' \ http://localhost:8080/actuator/loggers/be.g00glen00b
  36. Exploring the metrics endpoint

  37. What does it do? • Application metrics • Uses micrometer

    • Counters • Gauges • Distribution summaries • Percentiles • Timers
  38. Visit /actuator/metrics { "names": [ "cache.evictions", "http.server.requests", "jvm.threads.states", "hystrix.execution", "spring.batch.chunk.write",

    "spring.batch.item.process", "hystrix.latency.total", "jvm.memory.used" ] }
  39. Visit /actuator/metrics/{metric} { "name": "jvm.memory.used", "description": "The amount of used

    memory", "baseUnit": "bytes", "measurements": [{ "statistic": "VALUE", "value": 196616376 }], "availableTags": [{ "tag": "area", "values": ["heap", "nonheap"] }]
  40. Visit /actuator/metrics/{metric}?tag=area:heap { "name": "jvm.memory.used", "description": "The amount of used

    memory", "baseUnit": "bytes", "measurements": [{ "statistic": "VALUE", "value": 196616376 }], "availableTags": [] }
  41. Creating custom counter metrics @Bean public Counter invoicesCounter(MeterRegistry registry) {

    return Counter .builder("invoices.created") .description("Amount of invoices created") .register(registry); }
  42. Creating custom counter metrics @PostMapping public CreatedInvoiceDTO create(@RequestBody InvoiceParametersDTO parameters)

    { counter.increment(); // Add this return facade.create(parameters); }
  43. Creating custom gauge metrics @Bean public Gauge countOrdersGauge(MeterRegistry registry, OrderRepository

    repository) { return Gauge .builder("order.count", repository::count) .description("Amount of registered orders”) .register(registry); }
  44. Cool stuff… but why?

  45. Cool stuff… but why? • Production-readiness • Better monitoring •

    Better logging • Better debugging = More happy people
  46. Resources • https://docs.spring.io/spring-boot/docs/current/reference/html/p roduction-ready-features.html • https://dimitr.im/mastering-spring-boot-actuator Shameless self-promotion

  47. Thank you for listening!