Spring: Monitoring

Spring: Monitoring


Мониториг любого приложения включает в себя:

  • мониторинг приложения логов;
  • мониторинг ошибок приложения;
  • мониторинг основных метрик: CPU, RAM и т.д.;
  • мониторинг состояния сети;
  • мониторинг запросов/ответов входящих и исходящих к каждому уникальному ресурсу;
  • мониторинг использования внешних ресурсов (БД, кэша, веб сервисов, стриминговых сервисов и т.д.);
  • детализация по транзакциям;
  • профилирование приложения;
  • мониторинг доступных для исползуемых инструментов метрик (в случае с Java - JavaHeap, JMX и т.д.);
  • мониторинг клитических метрик, определенных командой разработки или бизнесом.

Нагрузка

Лучше всего проверять качество и стабильность работы приложения под нагрузкой. Существует большой набор инструментов, с помощью которых можно отслеживать нагрузку на сервер и вести мониторинг (как на уровне Java, так и на уровне OS). Самыми распространенными являются JMeter, DynaTrace, NewRelic. Все они являются внешними для приложения.

Для примитивной нагрузки средствами Spring, можно воспользоваться средством повторного тестирования, входящего в стандартный пакет JUnit5. Аннотация @RepeatedTest, которая является (в свою очередь) аннотированной от @TestTemplate - которая определяет метод не как тестировочный, но как некий шаблон для тестов.

1
2
3
4
@RepeatedTest(100)
void listUsers() {
httpClient.get("clients");
}

В примере выше - Spring выполнит 100 тестов, определенных как: HTTP клиент выполняет запрос к удаленому узлу и проверяет результат.

Профилирование

Стандартным приложением, позволяющим выполнять профилирование является JConsole. Существует так же ряд других приложений, которые имеют более расширенный функционал, например, JProfiler, YourKit и др.

Мониторинг Spring Boot приложения

Для мониторинга Spring приложения в стандартном пакете Spring предусмотрен модуль SpringBoot Actuator (spring-boot-starter-actuator). Он сразу включает в себя следующие инструменты:

  • health check: проверка состояния приложения. Сервис доступен по /health
  • auditing: набор утилит для аудирования (критичных) событий на сервере. Сервис доступен по /auditevents
  • metrics: получение (критичных) метрик приложения. По умолчанию исползует библиотеку Micrometer для их учета. Сервис доступен по /metrics
  • HTTP trace: трассировка запросов/ответов. Сервис доступен по /httptrace

Базовая настройка

По умолчанию модуль предоставляет информацию для мониторинга по контекстному пути ${server}/actuator/${tool}. Например, /actuator/health, /actuator/auditevent. Путь можно изменить. Выполняется это путем изменения параметра приложения mangement.endpoints.web.base-path на нужное значение, например:

1
mangement.endpoints.web.base-path=/custom-monitoring-path

Тогда health check будет расположен /custom-monitoring-path/health. Так же можно изменить путь до каждой отдельной утилиты:

1
mangement.endpoints.web.path-path.${tool}=new-custom-pathx

Если необходимо ограничить доступ к мониторингу каким-то удаленным узлом (например, только тем сервером, на котором и запускается приложение), то необходимо указать его в настройках:

1
2
management.server.port=9090
management.server.address=192.168.0.100

Утилиты для мониторинга

Spring предоставляет большое количество утилит для мониторинга в составе стандартного пакета. Некоторые из них представлены в сжатом виде, некоторые более подробно ниже. Подробно они описаны тут.

Почти все утилиты по умолчанию включены и собирают данные, но не все доступны из сервиса для проверки статуса или получения дополнительной информации по ним. Для начала предоставления информации по всем утилитам через сервис, достаточно добавить параметр в настройках Spring:

1
management.endpoints.web.explosure.include=*

Чтобы спрятать все:

1
management.endpoints.web.explosure.exclude=*

Выборочно:

1
2
management.endpoints.web.explosure.include=env,info,beans
management.endpoints.web.explosure.exclude=heapdump,threadump

/info

Утилита предоставляет справочную информацию по приложению. По умолчанию данная утилита выдает пустой результат, но чтобы она заполнена данными следует предоставить параметры в Spring: info.app.name, info.app.description, info.app.version. Так же справочную информацию по приложению Spring ищет в META-INF/build-info.properties.

/health

По умолчанию просто возвращает статус работы Spring - либо работает (UP), либо нет (DOWN).
Если требуется детальная информация, ее можно подключить, передав приложению свойство management.endpoint.health.show-details со значением always. В Spring существует возможность модифицировать результат проверки статуса и добавить собственную детализацию. Для этого необходимо создать бин, который будет реализовывать интерфейс HealthIndicator:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Component
public class MyHealth implements HealthIndicator, ApplicationContextAware {
@Autowire
@Lazy
private MyObjectsService service;

ApplicationContext ctx;

@Override
public void setApplicationContext(ApplicationContext ctx) {
this.ctx = ctx;
}

public Health health() {
Map<String, String> details = new HashMap();
details.put("myService", "WORKING");
details.put("data", Status.UNKNOWN);
return Health.up().withDetails(details).build();
}
}

Четких правил относительно указания статусов нет, но есть рекомендации:

  • статус UP должен быть присвоен приложению если все компоненты имеют допустимый статус (возможно, каким-то компонентам не обязательно быть доступными чтобы вся система считалась доступной!)
  • Стандартные статусы: UP (HTTP 200) - все работает штатно; DOWN (HTTP 503) - все плохо, все компоненты или критическая часть не работает корректно; OUT_OF_SERVICE (HTTP 503) - компонент или его часть не доступны; UNKNOWN (HTTP 501) - статус компонента неизвестен

Статусы HTTP указываются как универсально средство для идентификации состояния приложения. Статусы можно добавить и указать им соответствие статусам HTTP (либо изменить стандартные:

1
2
3
management.health.status.http-mapping.FATAL=501
management.health.status.http-mapping.OUT_OF_SERVICE=503
management.health.status.order=FATAL,DOWN,OUT_OF_SERVICE,UNKNOWN, UP

/beans

Данная утилита предоставляет информацию по всем(!) бинам, связанным с контекстом - там отображаются alias, scope и dependencies. Иногда полезно заглядывать в информацию данной утилиты чтобы убирать ненужные бины.

/auditevents

Предоставляет аудированную информацию, заполненную критичными событиями. По умолчанию отображает только события связанные с безопасность (Spring Security), но может быть расширено.

/caches

Предоставляет общую и детальную (/caches/${cache_name}) информацию по кэшу.

/conditions

Предоставляет общую информацию по текущему состоянию и автонастройкам.

/configprops

Все текущие параметры приложения с их текущими значениями.

/env

Информация по окружению приложения (системная информация).

/loggers

Активные логгеры на текущий момент со всеми их настройками. При выполнении GET запроса к данной утилите, будет выведен список. Но с помощью POST конфигурациями каждого конкретного логгера можно управлять:

1
2
3
4
POST http://localhost:8080/actuator/loggers/my.company.services
{
"configuredLevel":”DEBUG
}

Заставит логгер перейти на логирование на уровне DEBUG.

/heapdump

Выполняет HeapDump.

/threadump

Выполняет ThreadDump.

/mappings

Предоставляет информацию по путям доступных @RequestMapping.

/metrics

Текущие метрики. Для получения текущего значения по конкретной метрике - /metrics/${metric_name}.

/shutdown

Эта утилита по умолчанию не видна и не доступна. При попытке запросить ее будет выдан статус 404. Чтобы ее включить достаточно указать в параметрах Spring:

1
management.endpoint.shutdown.enabled=true

Впрочем, так включается и отключается любая утилита. Чтобы отключить все, которые по умолчанию включены присутствует отдельный параметр (можно отключить все, а затем точечно включать нужные):

1
management.endpoints.enabled-by-default=false

Собственные утилиты

Для этого достаточно создать бин с одной из аннотаций из группы @Endpoint. В случае если утилиту следует раскрыть только для JMX, аннотация должна быть @JmxEndpoint. Если утилита должна быть доступна через веб - @WebEndpoint. Какая бы реализация ни была выбрана, в каждой следует указать идентификатор - поле id. Есть возможность отключения параметра по умолчанию - для этого есть параметр enableByDefault.

В бине можно определить методы, которые будут выполнять действия, согдасно видам запросов: @ReadOperation (GET запросы), @WriteOperation (POST запросы) и @DeleteOperation (DELETE запросы).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@Component
@WebEndpoint("mytool")
public class MyToolWebEndpoint implements ApplicationContextAware {
@Autowire
MyService svc;

@Override
public void setApplicationContext(ApplicationContext ctx) {
this.ctx = ctx;
}

@ReadOperation
public MyEndpointJson get() {
return new MyEndpointJson(...);
}

@ReadOperation
public MyChildEndpointJson getChild(@Selector String child) {
return new MyChildEndpointJson(...);
}

@WriteOperation
public void write(@Selector String child, MyChildEndpointJson childCfg) {
...
}

@DeleteOperation
public void delete(@Selector String child) {
...
}
}

Просмотр метрик

Метрики, которые входят в состав базовой утилиты /metrics по умолчанию активны и снимают ряд метрик, которые потом можно будет отправить в ситстему учета и отображения метрик (например, Prometheus).

Метрик, которые снимаются по умолчанию довольно много и все их можно разбить на категории:

  • JVM, GC, учет RAM, использование потоков, количество видимых классов и т.д.;
  • Использование CPU;
  • Spring-специфические компоненты;
  • Кэш;
  • Источники данных и пул соединений;
  • Время работы;
  • Данные от Tomcat (или другого используемого сервера);
  • Информация по запросам к Spring MVC и WebFlux;
  • Прочая специфическая информация (типа данные от стриминговых серверов, показания событий и т.д.).
 Comments
Comment plugin failed to load
Loading comment plugin