Для отслеживания параметров работы приложения удобно использовать Spring Boot Actuator. Он предоставляет такие возможности, как:
- создание своих (кастомных) метрик, индикаторов и счётчиков;
- экспорт метрик в различные агрегаторы и визуализаторы, включая InfluxDB и Graphite.
На одном из проектов мне необходимо было добавить возможность просмотра в заданном формате определённых метрик микросервиса по HTTP-запросу установленного формата и выключение (полную остановку) сервиса по HTTP-запросу.
Задача интересная. И вот, как мы можем её решить:
1. Добавляем в pom.xml зависимости.
2. Добавляем в application.properties:
3. Расширяем возможности Health-индикатора актуатора.
В данном случае я добавил отображение в деталях Health-метрик следующих сведений:
- имя сервера, на котором запущено приложение;
- время работы сервиса с момента запуска.
Состав сведений, которые мы можем добавить для отображения в Health-метриках, окраничивается только нашей фантазией.
Запустим сервис и понаправляем на него запросы.
Посмотрим Health-статус:
Посмотрим API метрик:
Остановим сервис:
Весь код на GitHub
- создание своих (кастомных) метрик, индикаторов и счётчиков;
- экспорт метрик в различные агрегаторы и визуализаторы, включая InfluxDB и Graphite.
На одном из проектов мне необходимо было добавить возможность просмотра в заданном формате определённых метрик микросервиса по HTTP-запросу установленного формата и выключение (полную остановку) сервиса по HTTP-запросу.
Задача интересная. И вот, как мы можем её решить:
1. Добавляем в pom.xml зависимости.
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
2. Добавляем в application.properties:
# включаем отображение в Web всех метрик management.endpoints.web.exposure.include=* # активируем возможность выключения сервиса по HTTP-запросу management.endpoint.shutdown.enabled=true # активируем показ в Health-метриках дополнительных деталей (состяние баз данных, очередей и прочего) management.endpoint.health.show-details=always # изменяем стандартный путь к метрикам актуатора management.endpoints.web.base-path=/api # изменяем стандартный путь к Health-метрикам актуатора management.endpoints.web.path-mapping.health=status
# задаём имя сервера
server.name=defaultName-123
3. Расширяем возможности Health-индикатора актуатора.
@Service public class StatusEndpointService implements HealthIndicator { private MetricsEndpoint metricsEndpoint; @Value("${server.name}") private String serverName; @Autowired public void setMetricsEndpoint(MetricsEndpoint metricsEndpoint) { this.metricsEndpoint = metricsEndpoint; } @Override public Health health() { Map<String, Object> statusMap = new HashMap<>(); MetricResponse response = metricsEndpoint.metric("process.uptime", null); long uptimeMiliseconds = (long) (response.getMeasurements().get(0).getValue() * 1000); long millis = uptimeMiliseconds % 1000; long second = (uptimeMiliseconds / 1000) % 60; long minute = (uptimeMiliseconds / (1000 * 60)) % 60; long hour = (uptimeMiliseconds / (1000 * 60 * 60)) % 24; long days = uptimeMiliseconds / (1000 * 60 * 60 * 24); String formatedUptime = String.format("%d.%02d:%02d:%02d.%03d", days, hour, minute, second, millis); statusMap.put("serverName", serverName); statusMap.put("uptime", formatedUptime); return Health.up().withDetails(statusMap).build(); } }
В данном случае я добавил отображение в деталях Health-метрик следующих сведений:
- имя сервера, на котором запущено приложение;
- время работы сервиса с момента запуска.
Состав сведений, которые мы можем добавить для отображения в Health-метриках, окраничивается только нашей фантазией.
Запустим сервис и понаправляем на него запросы.
Посмотрим Health-статус:
$ curl http://localhost:8080/api/status | jq % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 231 0 231 0 0 46200 0 --:--:-- --:--:-- --:--:-- 46200 { "status": "UP", "details": { "statusEndpointService": { "status": "UP", "details": { "serverName": "localhost", "uptime": "0.00:07:29.735" } }, "diskSpace": { "status": "UP", "details": { "total": 354868289536, "free": 12128550912, "threshold": 10485760 } } } }
Посмотрим API метрик:
$ curl http://localhost:8080/api | jq % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 1838 0 1838 0 0 358k 0 --:--:-- --:--:-- --:--:-- 358k { "_links": { "self": { "href": "http://localhost:8080/api", "templated": false }, "auditevents": { "href": "http://localhost:8080/api/auditevents", "templated": false }, "beans": { "href": "http://localhost:8080/api/beans", "templated": false }, "caches": { "href": "http://localhost:8080/api/caches", "templated": false }, "caches-cache": { "href": "http://localhost:8080/api/caches/{cache}", "templated": true }, "health": { "href": "http://localhost:8080/api/status", "templated": false }, "health-component-instance": { "href": "http://localhost:8080/api/status/{component}/{instance}", "templated": true }, "health-component": { "href": "http://localhost:8080/api/status/{component}", "templated": true }, "conditions": { "href": "http://localhost:8080/api/conditions", "templated": false }, "shutdown": { "href": "http://localhost:8080/api/shutdown", "templated": false }, "configprops": { "href": "http://localhost:8080/api/configprops", "templated": false }, "env-toMatch": { "href": "http://localhost:8080/api/env/{toMatch}", "templated": true }, "env": { "href": "http://localhost:8080/api/env", "templated": false }, "info": { "href": "http://localhost:8080/api/info", "templated": false }, "loggers": { "href": "http://localhost:8080/api/loggers", "templated": false }, "loggers-name": { "href": "http://localhost:8080/api/loggers/{name}", "templated": true }, "heapdump": { "href": "http://localhost:8080/api/heapdump", "templated": false }, "threaddump": { "href": "http://localhost:8080/api/threaddump", "templated": false }, "metrics-requiredMetricName": { "href": "http://localhost:8080/api/metrics/{requiredMetricName}", "templated": true }, "metrics": { "href": "http://localhost:8080/api/metrics", "templated": false }, "scheduledtasks": { "href": "http://localhost:8080/api/scheduledtasks", "templated": false }, "httptrace": { "href": "http://localhost:8080/api/httptrace", "templated": false }, "mappings": { "href": "http://localhost:8080/api/mappings", "templated": false } } }
Остановим сервис:
$ curl -X POST localhost:8080/api/shutdown | jq % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 35 0 35 0 0 324 0 --:--:-- --:--:-- --:--:-- 324 { "message": "Shutting down, bye..." }
Весь код на GitHub