Салют, хабровчане! Уже через неделю стартуют занятия в новой группе курса «Разработчик на Spring Framework». В связи с этим делимся с вами полезным материалом в котором рассказано о том, что такое Spring Actuator и чем он может быть полезен.



  1. Что такое Spring Actuator?
  2. Как добавить Spring Actuator в проект Maven или Gradle?
  3. Создание проекта Spring Boot с зависимостью Spring Actuator.
  4. Мониторинг приложений с Spring Actuator Endpoints.

Что такое Spring Actuator?

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

Традиционно, до Spring Actuator, нам нужно было писать код для проверки работоспособности приложения, но с Spring Actuator нам не нужно писать код. Spring Actuator предоставляет несколько готовых конечных точек (endpoint), которые могут быть полезны для мониторинга приложения.

Как добавить Spring Actuator в проект Maven или Gradle?

Maven

<dependencies>
  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
   </dependency>
</dependencies>

Gradle

dependencies {
  compile("org.springframework.boot:spring-boot-starter-actuator")
}

Создание проекта Spring Boot с Spring Actuator

Давайте продолжим и создадим с помощью Spring Initializer проект Spring Boot с зависимостями Spring Actuator, Web и DevTools.

Обратите внимание, что на момент написания этой статьи версия Spring Boot была 2.1.0.



Импортируйте проект в Eclipse или любую другую IDE и запустите SpringActuatorApplication.java.

В консоли вы увидите следующее:



Видно, что встроенный Tomcat запущен на порту 8080, а SpringActuatorApplication запущен в Tomcat. Также вы можете увидеть, что конечные точки actuator’а доступны по адресу /actuator.

018-11-09 20:00:29.346  INFO 8338 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''

2018-11-09 20:00:29.354  INFO 8338 --- [  restartedMain] n.b.j.s.SpringActuatorApplication        : Started SpringActuatorApplication in 9.273 seconds (JVM running for 11.823)

2018-11-09 20:00:29.190  INFO 8338 --- [  restartedMain] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 2 endpoint(s) beneath base path '/actuator'.

Мониторинг приложений с Spring Actuator Endpoints

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

ID Описание
auditevents
Предоставляет информацию о событиях
аудита для текущего приложения.
beans Отображает полный список всех
Spring-бинов в приложении.
caches Информация о кэше.
conditions Показывает условия (Condition), которые
были вычислены для классов конфигурации
и автоконфигурации, и причины, по
которым они соответствовали или не
соответствовали.
configprops Отображает список всех
@ConfigurationProperties
env Отображает свойства из
ConfigurableEnvironment.
flyway Показывает миграции баз данных
Flyway, которые были применены.
health Показывает сведения о работоспособности
приложения.
httptrace Отображает информацию трассировки
HTTP (по умолчанию последние 100 HTTP
запросов-ответов).
info Отображает дополнительную информацию
о приложении.
integrationgraph Граф Spring Integration.
loggers Отображает и позволяет
изменить конфигурацию логгеров в
приложении.
liquibase Показывает примененные миграции
базы данных Liquibase.
metrics Показывает информацию о метриках
для текущего приложения.
mappings Отображает список всех путей
@RequestMapping.
scheduledtasks Отображает запланированные задачи
(scheduled tasks).
sessions Позволяет извлекать и удалять
пользовательские сессии из хранилищ,
поддерживаемых Spring Session. Недоступно
при использовании Spring Session для реактивных
веб-приложений.
shutdown Позволяет приложению корректно
завершить работу.
threaddump Отображает информацию о потоках.

Включение конечных точек

По умолчанию включены все конечные точки, кроме shutdown. Чтобы включить конечную точку, используйте следующее свойство в файле application.properties.

management.endpoint.<code><</code>id<code>></code>.enabled

Примечание переводчика: по умолчанию доступ ко всем конечным точкам есть только через JMX, доступа через HTTP ко всем конечным точкам нет (см. ниже).

Пример:

Чтобы включить конечную точку shutdown, нам нужно сделать следующую запись в файле application.properties:

management.endpoint.shutdown.enabled=true

Мы можем отключить все конечные точки, а затем включать только те, которые нам нужны. При следующей конфигурации все конечные точки, кроме info, будут отключены.

management.endpoints.enabled-by-default=false
management.endpoint.info.enabled=true

Доступ к конечным точкам через HTTP

Давайте перейдем по URL-адресу localhost:8080/actuator и посмотрим на доступные конечные точки.

Примечание: я использую Postman для тестирования, поскольку он показывает JSON в хорошо структурированном формате. Вы можете использовать любой другой инструмент или просто браузер.



Как вы уже заметили, здесь показаны только конечные точки health и info. Потому что это единственные конечные точки, которые по умолчанию доступны через http. Доступ через http к другим конечным точкам закрыт по умолчанию из соображений безопасности, поскольку они могут содержать конфиденциальную информацию и, следовательно, могут быть скомпрометированы.

Доступ к конкретным конечным точкам

Если мы хотим предоставить доступ через web (http) к другим конечным точкам то, нам нужно сделать следующие записи в файле application.properties.

management.endpoints.web.exposure.include=<список конечных точек через запятую><a href="http://localhost:8080/actuator"></a>

Пример:

management.endpoints.web.exposure.include= health,info,env

Теперь, после добавления в application.properties указанной выше записи, давайте снова перейдем по http://localhost:8080/actuator

Как мы видим на скриншоте ниже, конечная точка env также включена.



Доступ ко всем конечным точкам

Если мы хотим включить все конечные точки, мы можем использовать знак *, как показано ниже.

management.endpoints.web.exposure.include=*



Доступ ко всем конечным точкам, кроме некоторых

Две записи ниже активируют все конечные точки, но отключают конечную точку env.

management.endpoints.web.exposure.include=*
management.endpoints.web.exposure.exclude=env





Отключение всех конечных точек HTTP

Если вы не хотите предоставлять конечные точки через HTTP, это можно сделать, настроив в файле application.properties следующее:

management.server.port=-1

или так:

management.endpoints.web.exposure.exclude=*

Настройка URL для доступа к конечным точкам

По умолчанию все конечные точки доступны по URL /actuator по адресам вида /actuator/{id}. Однако можно изменить базовый путь /actuator, используя следующее свойство в application.properties.

management.endpoints.web.base-path

Например, если вы хотите сделать базовый URL-адрес как /monitor вместо /actuator это можно сделать следующим образом:

management.endpoints.web.base-path=/monitor



При этом все конечные точки будут доступны как /monitor/{id} вместо /actuator/{id}



Конечные точки Spring Boot Actuator

Давайте обсудим некоторые из наиболее важных конечных точек.

/health

Конечная точка health даёт общий статус приложения: запущено и работает или нет. Это очень важно для мониторинга состояния приложения, когда оно находится в продакшене. Эта конечная точка может быть интегрирована с приложениями мониторинга и будет очень полезна для определения работоспособности приложений в реальном времени.

Объем информации, предоставляемой конечной точкой health, зависит от свойства management.endpoint.health.show-details в файле application.properties.

Если management.endpoint.health.show-details=never, то никакая дополнительная информация не отображается. В этом случае вы увидите только следующее (это поведение по умолчанию).



Если management.endpoint.health.show-details=always, то дополнительная информация показывается всем пользователям. Как мы видим в ответе ниже, у нас появилась информация о дисковом пространстве (diskSpace). Если ваше приложение подключено к базе данных, то у вас также будет отображаться информация о состоянии базы данных.



Если management.endpoint.health.show-details=when-authorized, то дополнительная информация будет показана только авторизованным пользователям. Авторизацию можно настроить с помощью свойства management.endpoint.health.roles.

Преднастроенные индикаторы

Spring Boot Actuator имеет множество автоматически настроенных “индикаторов здоровья” (HeathIndicators)для проверки работоспособности различных частей приложения. Например, DiskspaceHealthIndicator предоставляет информацию о дисковом пространстве. Если вы используете MongoDB, то MongoHealthIndicator проверит работоспособность БД Mongo (запущен сервер или нет) и отобразит соответствующую информацию. По умолчанию окончательный статус приложения определяет HealthAggregator, который просто сортирует список статусов, предоставленных каждым HealthIndicator. Первый статус в отсортированном списке используется как окончательный статус приложения.

Отключение всех преднастроенных индикаторов

Описанные выше “индикаторы здоровья” включены по умолчанию, однако, их можно отключить с помощью следующего свойства:

management.health.defaults.enabled=false

Отключение отдельного индикатора

В качестве альтернативы можно отключить отдельный HealthIndicator, как показано ниже, например, для отключения проверки дискового пространства:

management.health.diskspace.enabled=false

Примечание: идентификатором любого HealthIndicator будет имя бина без суффикса HealthIndicator.

Например:

DiskSpaceHealthIndicator	diskspace
MongoHealthIndicator		mongo
CassandraHealthIndicator	cassandra
DataSourceHealthIndicator	datasource

и так далее…

Написание своих индикаторов (HealthIndicator)

Наряду со встроенными HealthIndicator, предоставляемыми Spring Boot Actuator, мы можем создавать собственные индикаторы состояния. Для этого вам нужно создать класс, который реализует интерфейс HealthIndicator, реализовать его метод health() и вернуть Health в качестве ответа с соответствующей информацией, как показано ниже:

import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;

@Component
public class CustomHealthIndicator implements HealthIndicator {

 @Override
 public Health health() {
  int errorCode = 0; 
  // In the above line,I am simple assigning zero,but you can call Health check related code like below commented line and that method can return the appropriate code.
  // int errorCode = performHealthCheck();
  if (errorCode != 0) {
   return Health.down().withDetail("Error Code", errorCode).build();
  }
  return Health.up().build();
 }

}

Давайте снова перейдем на конечную точку health и посмотрим, отражается ли наш индикатор или нет.



Мы видим наш индикатор.

Статус отдельного компонента

Можно также проверить состояние отдельного компонента. В приведенном выше примере мы видели написанный нами индикатор и diskSpace.

Если мы хотим видеть только состояние диска, мы можем использовать следующее URL:

http://localhost:8080/actuator/health/diskSpace



/info

Конечная точка info предоставляет общую информацию о приложении, которую она получает из файлов, таких как build-info.properties или git.properties, или из свойств, указанных в application.properties.

Так как в нашем проекте такого файла нет, то ответ будет пустой, как показано ниже:



Spring Boot Actuator отображает информацию о сборке, если присутствует файл META-INF/build-info.properties. Этот файл с информацией о проекте создается время сборки целью build-info. Здесь также можно добавить произвольное количество дополнительных свойств.

Давайте добавим в pom.xml цель build-info для плагина spring-boot-maven-plugin.

<plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <version>2.1.0.RELEASE</version>
        <executions>
          <execution>
            <goals>
              <goal>build-info</goal>
            </goals>
            <configuration>
              <additionalProperties>
                <encoding.source>UTF-8</encoding.source>
                <encoding.reporting>UTF-8</encoding.reporting>
                <java.source>${maven.compiler.source}</java.source>
                <java.target>${maven.compiler.target}</java.target>
              </additionalProperties>
            </configuration>
          </execution>
        </executions>
 </plugin>

Теперь давайте снова посмотрим на конечную точку info и увидим информацию о сборке, как показано ниже:



Кроме того, мы можем добавить информацию о приложении с ключом info в application.properties, как показано ниже, и она будет отображаться в конечной точке /info.

info.application.name=spring-actuator
info.application.description=spring boot actuator application
info.application.version=0.0.1-SNAPSHOT



/beans

Конечная точка beans показывает все бины, определенные в Spring-контейнере со следующей информацией о каждом бине:

aliases  : названия всех псевдонимов
scope   : область видимости
type      : полное имя бина
resource : ресурс (класс), в котором определён бин
dependencies : имена зависимых бинов

Например, я создал RestController с именем TestController и заинжектил компонент с именем TestService

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {
 
 @Autowired
 private TestService testService;
 
 @GetMapping("/messages")
 public String getMessage() {
  return "Hello";
 }
}
import org.springframework.context.annotation.Configuration;

@Configuration
public class TestService {

}

Вы можете увидеть, как это показывается для testController, на скриншоте ниже.



/configprops
Конечная точка configProps показывает все бины, аннотированные @ConfigurationProperties.



На приведенном выше скриншоте мы видим два бина, которые определены в самом Spring Framework и снабжены аннотацией @ConfigurationProperties и, следовательно, отображаются в этой конечной точке.

На скриншоте ниже показан исходный код HttpTraceProperties, аннотированный @ConfigurationProperties.



/env

Конечная точка env предоставляет всю информацию, относящуюся к окружению, в следующем порядке:

Свойства системы
зависит от JVM (не зависит от платформы)
Системное окружение или переменные
окружения
зависит от операционной
системы (зависит от платформы)
Настройки уровня приложения
определены в
application.properties



/heapdump

Конечная точка heapdump делает дамп кучи приложения. Эта конечная точка возвращает двоичные данные в формате HPROF. Поскольку обычно возвращается много данных, вы должны их сохранить и проанализировать.

/loggers

Конечная точка loggers предоставляет логгеры приложения с информацией об их настроенном уровне логирования (configuredLevel) и эффективном уровне (effectiveLevel). Если для логера и его родителя настроенный уровень не указан (null), то эффективным уровнем будет уровень корневого логера.

Свойство level указывает, какие уровни логирования поддерживаются фреймворком логирования.



Чтобы получить информацию для конкретного логера, передайте имя (ид) логера в URL-адресе после конечной точки /loggers, как показано ниже:

http://localhost:8080/actuator/loggers/nl.blogpsot.javasolutionsguide.springactuator.SpringActuatorApplication



/metrics

Конечная точка metrics показывает все метрики, которые вы можете отслеживать для вашего приложения.



Проверка индивидуальной метрики

Вы можете смотреть отдельную метрику, передав её в URL-адресе после /metrics, как показано ниже:

http://localhost:8080/actuator/metrics/jvm.memory.used



Ссылки

docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html
docs.spring.io/spring-boot/docs/current/actuator-api/html

По устоявшейся традиции ждем ваши комментарии и приглашаем всех на день открытых дверей, который пройдет 23 мая.

Комментарии (1)


  1. yashanet
    20.05.2019 16:39

    крутая админка для этого всего github.com/codecentric/spring-boot-admin