Slide 1

Slide 1 text

Better monitoring with Spring boot Actuator

Slide 2

Slide 2 text

What is Spring boot Actuator? ● Spring boot library ● Adds production-ready features ● Provides useful endpoints ● Both over HTTP and JMX

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

How do I get started?

Slide 5

Slide 5 text

Add a dependency... org.springframework.boot spring-boot-starter-actuator

Slide 6

Slide 6 text

… and configure what you need management: endpoints: web: exposure: include: env, info, health, metrics

Slide 7

Slide 7 text

And… what now?

Slide 8

Slide 8 text

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 } }

Slide 9

Slide 9 text

Exploring the conditions endpoint

Slide 10

Slide 10 text

What does it do? ● Which autoconfigurations are in use ● Why are they (not) applied? ● What can I do to make it work?

Slide 11

Slide 11 text

Visit /actuator/conditions { "positiveMatches": {/* ... */}, "negativeMatches": { "RabbitHealthContributorAutoConfiguration": { "notMatched": [ { "condition": "OnClassCondition", "message": "@ConditionalOnClass did not find required class 'org.springframework.amqp.rabbit.core.RabbitTemplate'" } ]

Slide 12

Slide 12 text

Exploring the env endpoint

Slide 13

Slide 13 text

What does it do? ● Which application properties are loaded? ● Where do these properties come from?

Slide 14

Slide 14 text

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"

Slide 15

Slide 15 text

Exploring the health endpoint

Slide 16

Slide 16 text

What does it do? ● Is the database available? ● Is there enough disk space? ● Is Eureka available? ● Is Solr available? ● Useful for monitoring software ● ...

Slide 17

Slide 17 text

Visit /actuator/health { "status": "UP" }

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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 } }

Slide 20

Slide 20 text

Creating a custom health indicator @Component @RequiredArgsConstructor public class GitHubAPIHealthIndicator implements HealthIndicator { private final RestTemplate restTemplate; @Override public Health health() { // TODO: implement } }

Slide 21

Slide 21 text

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(); }

Slide 22

Slide 22 text

Creating a custom health indicator { "status": "UP", "components": { "gitHubAPI": { "status": "UP" } } }

Slide 23

Slide 23 text

Useful for monitoring

Slide 24

Slide 24 text

Useful for Eureka

Slide 25

Slide 25 text

Exploring the heapdump endpoint

Slide 26

Slide 26 text

What does it do? ● Returns *.HPROF file ● Can be imported in JVisualVM, … ● Find memory leaks and other peformance issues

Slide 27

Slide 27 text

Open the *.HPROF file

Slide 28

Slide 28 text

Exploring the info endpoint

Slide 29

Slide 29 text

What does it do? ● Returns additional information ● By default empty ● Useful in combination with Maven resource filtering

Slide 30

Slide 30 text

Configuring info info: contributors: Dimitri Mestdagh project-version: @project-version@ build-timestamp: @maven.build.timestamp@

Slide 31

Slide 31 text

Visit /actuator/info { "contributors": "Dimitri Mestdagh", "project-version": "0.0.1-SNAPSHOT", "build-timestamp": "2020-06-27 11:52:30" }

Slide 32

Slide 32 text

Exploring the loggers endpoint

Slide 33

Slide 33 text

What does it do? ● What logging levels are in use? ● Change runtime logging levels ● Useful for debugging

Slide 34

Slide 34 text

Visit /actuator/loggers { "loggers": { "ROOT": { "configuredLevel": "INFO", "effectiveLevel": "INFO" }, "be.g00glen00b": { "configuredLevel": null, "effectiveLevel": "INFO" } } }

Slide 35

Slide 35 text

Changing the runtime logger levels curl \ --header "Content-Type: application/json" \ --request POST \ --data '{"configuredLevel": "DEBUG"}' \ http://localhost:8080/actuator/loggers/be.g00glen00b

Slide 36

Slide 36 text

Exploring the metrics endpoint

Slide 37

Slide 37 text

What does it do? ● Application metrics ● Uses micrometer ● Counters ● Gauges ● Distribution summaries ● Percentiles ● Timers

Slide 38

Slide 38 text

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" ] }

Slide 39

Slide 39 text

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"] }]

Slide 40

Slide 40 text

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": [] }

Slide 41

Slide 41 text

Creating custom counter metrics @Bean public Counter invoicesCounter(MeterRegistry registry) { return Counter .builder("invoices.created") .description("Amount of invoices created") .register(registry); }

Slide 42

Slide 42 text

Creating custom counter metrics @PostMapping public CreatedInvoiceDTO create(@RequestBody InvoiceParametersDTO parameters) { counter.increment(); // Add this return facade.create(parameters); }

Slide 43

Slide 43 text

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); }

Slide 44

Slide 44 text

Cool stuff… but why?

Slide 45

Slide 45 text

Cool stuff… but why? ● Production-readiness ● Better monitoring ● Better logging ● Better debugging = More happy people

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

Thank you for listening!