Spring Boot Actuator – SpringBoot执行器

最后修改: 2018年 1月 23日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this article, we introduce the Spring Boot Actuator. We’ll cover the basics first, then discuss in detail what’s available in Spring Boot 2.x vs 1.x.

在这篇文章中,我们将介绍Spring Boot Actuator。我们将首先介绍基础知识,然后详细讨论Spring Boot 2.x与1.x中的可用功能

We’ll learn how to use, configure, and extend this monitoring tool in Spring Boot 2.x and WebFlux, taking advantage of the reactive programming model. Then we’ll discuss how to do the same using Boot 1.x.

我们将学习如何利用反应式编程模型,在Spring Boot 2.x和WebFlux中使用、配置和扩展这个监控工具。然后我们将讨论如何使用Boot 1.x做同样的事情。

Spring Boot Actuator is available since April 2014, together with the first Spring Boot release.

自2014年4月起,Spring Boot Actuator与第一个Spring Boot版本一起提供。

With the release of Spring Boot 2, Actuator has been redesigned, and new exciting endpoints were added.

随着Spring Boot 2的发布,Actuator已被重新设计,并增加了新的令人兴奋的端点。

We split this guide into three main sections:

我们将本指南分为三个主要部分。

2. What Is an Actuator?

2.什么是执行器?

In essence, Actuator brings production-ready features to our application.

从本质上讲,Actuator为我们的应用带来了可用于生产的功能。

Monitoring our app, gathering metrics, understanding traffic, or the state of our database become trivial with this dependency.

通过这一依赖关系,监测我们的应用程序、收集指标、了解流量或我们的数据库状态变得微不足道。

The main benefit of this library is that we can get production-grade tools without having to actually implement these features ourselves.

这个库的主要好处是,我们可以获得生产级的工具,而不需要自己实际实现这些功能。

Actuator is mainly used to expose operational information about the running application — health, metrics, info, dump, env, etc. It uses HTTP endpoints or JMX beans to enable us to interact with it.

Actuator主要用于暴露运行中的应用程序的操作信息–健康、指标、信息、转储、环境等。它使用HTTP端点或JMXBean,使我们能够与它互动。

Once this dependency is on the classpath, several endpoints are available for us out of the box. As with most Spring modules, we can easily configure or extend it in many ways.

一旦这个依赖关系出现在classpath上,就有几个端点可供我们开箱即用。与大多数Spring模块一样,我们可以很容易地以多种方式配置或扩展它。

2.1. Getting Started

2.1.起步

To enable Spring Boot Actuator, we just need to add the spring-boot-actuator dependency to our package manager.

要启用Spring Boot Actuator,我们只需要将spring-boot-actuator依赖性添加到我们的软件包管理器中。

In Maven:

在Maven中。

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

Note that this remains valid regardless of the Boot version, as versions are specified in the Spring Boot Bill of Materials (BOM).

请注意,无论Boot版本如何,这都是有效的,因为版本是在Spring Boot材料清单(BOM)中指定的。

3. Spring Boot 2.x Actuator

3.Spring Boot 2.x Actuator

In 2.x, Actuator keeps its fundamental intent but simplifies its model, extends its capabilities, and incorporates better defaults.

在2.x中,Actuator保持了它的基本意图,但简化了它的模型,扩展了它的能力,并纳入了更好的默认值。

First, this version becomes technology-agnostic. It also simplifies its security model by merging it with the application one.

首先,这个版本变得与技术无关。它还简化了安全模型,将其与应用模型合并。

Among the various changes, it’s important to keep in mind that some of them are breaking. This includes HTTP requests and responses as well as Java APIs.

在各种变化中,重要的是要记住,其中一些是破坏性的。这包括HTTP请求和响应,以及Java APIs。

Lastly, the latest version now supports the CRUD model as opposed to the old read/write model.

最后,最新版本现在支持CRUD模型,而不是以前的读/写模型。

3.1. Technology Support

3.1.技术支持

With its second major version, Actuator is now technology-agnostic whereas in 1.x it was tied to MVC, therefore to the Servlet API.

在其第二个主要版本中,Actuator现在是与技术无关的,而在1.x版本中,它是与MVC相联系的,因此与Servlet API相联系。

In 2.x, Actuator defines its model as pluggable and extensible without relying on MVC for this.

在2.x版本中,Actuator将其模型定义为可插拔和可扩展的,而不依赖MVC来实现。

Hence, with this new model, we’re able to take advantage of MVC as well as WebFlux as an underlying web technology.

因此,通过这个新模型,我们能够利用MVC以及WebFlux作为底层Web技术的优势。

Moreover, forthcoming technologies could be added by implementing the right adapters.

此外,通过实施正确的适配器,可以增加即将到来的技术。

Finally, JMX remains supported to expose endpoints without any additional code.

最后,JMX仍然支持暴露端点,不需要任何额外的代码。

3.2. Important Changes

3.2.重要变化

Unlike in previous versions, Actuator comes with most endpoints disabled.

与以前的版本不同,Actuator的大多数端点都是禁用的。

Thus, the only two available by default are /health and /info.

因此,默认情况下只有两个可用的是/health/info

If we want to enable all of them, we could set management.endpoints.web.exposure.include=*. Alternatively, we can list endpoints that should be enabled.

如果我们想启用所有的端点,我们可以设置management.endpoints.web.exposure.include=*。另外,我们也可以列出应该启用的端点。

Actuator now shares the security config with the regular App security rules, so the security model is dramatically simplified.

Actuator现在与常规App的安全规则共享安全配置,因此安全模型被大大简化。

Therefore, to tweak Actuator security rules, we could just add an entry for /actuator/**:

因此,为了调整执行器的安全规则,我们可以只添加一个/actuator/**的条目。

@Bean
public SecurityWebFilterChain securityWebFilterChain(
  ServerHttpSecurity http) {
    return http.authorizeExchange()
      .pathMatchers("/actuator/**").permitAll()
      .anyExchange().authenticated()
      .and().build();
}

We can find further details on the brand new Actuator official docs.

我们可以在全新的执行器官方文档上找到进一步的细节。

Also, by default, all Actuator endpoints are now placed under the /actuator path.

另外,默认情况下,所有的执行器端点现在都放在/actuator路径下

Same as in the previous version, we can tweak this path using the new property management.endpoints.web.base-path.

与之前的版本相同,我们可以使用新的属性management.endpoints.web.base-path.调整这个路径。

3.3. Predefined Endpoints

3.3.预定义端点

Let’s have a look at some available endpoints, most of which were available in 1.x already.

让我们看看一些可用的端点,其中大部分在1.x中已经可用。

Also, some endpoints have been added, some removed and some have been restructured:

此外,一些端点被添加,一些被删除,一些被重组

  • /auditevents lists security audit-related events such as user login/logout. Also, we can filter by principal or type among other fields.
  • /beans returns all available beans in our BeanFactory. Unlike /auditevents, it doesn’t support filtering.
  • /conditions, formerly known as /autoconfig, builds a report of conditions around autoconfiguration.
  • /configprops allows us to fetch all @ConfigurationProperties beans.
  • /env returns the current environment properties. Additionally, we can retrieve single properties.
  • /flyway provides details about our Flyway database migrations.
  • /health summarizes the health status of our application.
  • /heapdump builds and returns a heap dump from the JVM used by our application.
  • /info returns general information. It might be custom data, build information or details about the latest commit.
  • /liquibase behaves like /flyway but for Liquibase.
  • /logfile returns ordinary application logs.
  • /loggers enables us to query and modify the logging level of our application.
  • /metrics details metrics of our application. This might include generic metrics as well as custom ones.
  • /prometheus returns metrics like the previous one, but formatted to work with a Prometheus server.
  • /scheduledtasks provides details about every scheduled task within our application.
  • /sessions lists HTTP sessions given we are using Spring Session.
  • /shutdown performs a graceful shutdown of the application.
  • /threaddump dumps the thread information of the underlying JVM.

3.4. Hypermedia for Actuator Endpoints

3.4.执行器端点的超媒体

Spring Boot adds a discovery endpoint that returns links to all available actuator endpoints. This will facilitate discovering actuator endpoints and their corresponding URLs.

Spring Boot增加了一个发现端点,可以返回所有可用的执行器端点的链接。这将有助于发现执行器端点和它们相应的URL。

By default, this discovery endpoint is accessible through the /actuator endpoint.

默认情况下,该发现端点可通过/actuator端点访问。

Therefore, if we send a GET request to this URL, it’ll return the actuator links for the various endpoints:

因此,如果我们向这个URL发送一个GET 请求,它将返回各个端点的执行器链接。

{
  "_links": {
    "self": {
      "href": "http://localhost:8080/actuator",
      "templated": false
    },
    "features-arg0": {
      "href": "http://localhost:8080/actuator/features/{arg0}",
      "templated": true
    },
    "features": {
      "href": "http://localhost:8080/actuator/features",
      "templated": false
    },
    "beans": {
      "href": "http://localhost:8080/actuator/beans",
      "templated": false
    },
    "caches-cache": {
      "href": "http://localhost:8080/actuator/caches/{cache}",
      "templated": true
    },
    // truncated
}

As shown above, the /actuator endpoint reports all available actuator endpoints under the _links field.

如上所示,/actuator端点在_links字段下报告所有可用的执行器端点。

Moreover, if we configure a custom management base path, then we should use that base path as the discovery URL.

此外,如果我们配置了一个自定义的管理基础路径,那么我们应该使用该基础路径作为发现URL。

For instance, if we set the management.endpoints.web.base-path to /mgmt, then we should send a request to the /mgmt endpoint to see the list of links.

例如,如果我们将management.endpoints.web.base-path设置为/mgmt,那么我们应该向/mgmtendpoint发送一个请求,以查看链接列表。

Quite interestingly, when the management base path is set to /, the discovery endpoint is disabled to prevent the possibility of a clash with other mappings.

颇为有趣的是,当管理基础路径被设置为/时,发现端点被禁用,以防止与其他映射发生冲突的可能性。

3.5. Health Indicators

3.5.健康指标

Just like in the previous version, we can add custom indicators easily. Opposite to other APIs, the abstractions for creating custom health endpoints remain unchanged. However, a new interface, ReactiveHealthIndicator, has been added to implement reactive health checks.

就像以前的版本一样,我们可以轻松地添加自定义指标。与其他API相反,用于创建自定义健康端点的抽象仍然没有改变。然而,增加了一个新的接口,ReactiveHealthIndicator,以实现反应性健康检查。

Let’s have a look at a simple custom reactive health check:

让我们来看看一个简单的自定义反应式健康检查。

@Component
public class DownstreamServiceHealthIndicator implements ReactiveHealthIndicator {

    @Override
    public Mono<Health> health() {
        return checkDownstreamServiceHealth().onErrorResume(
          ex -> Mono.just(new Health.Builder().down(ex).build())
        );
    }

    private Mono<Health> checkDownstreamServiceHealth() {
        // we could use WebClient to check health reactively
        return Mono.just(new Health.Builder().up().build());
    }
}

A handy feature of health indicators is that we can aggregate them as part of a hierarchy.

健康指标的一个方便的特点是,我们可以将它们作为层次结构的一部分进行汇总。

So, following the previous example, we could group all downstream services under a downstream-services category. This category would be healthy as long as every nested service was reachable.

因此,按照前面的例子,我们可以将所有下游服务归入一个downstream-services类别。只要每个嵌套的service都是可到达的,这个类别就会是健康的。

Check out our article on health indicators for a more in-depth look.

请查看我们关于健康指标的文章,了解更深入的情况。

3.6. Health Groups

3.6.健康组

As of Spring Boot 2.2, we can organize health indicators into groups and apply the same configuration to all the group members.

从Spring Boot 2.2开始,我们可以将健康指标组织到中,并对所有组成员应用相同的配置。

For example, we can create a health group named custom by adding this to our application.properties:

例如,我们可以创建一个名为custom的健康组,将其添加到我们的application.properties

management.endpoint.health.group.custom.include=diskSpace,ping

This way, the custom group contains the diskSpace and ping health indicators.

这样,custom 组包含diskSpace ping 健康指标。

Now if we call the /actuator/health endpoint, it would tell us about the new health group in the JSON response:

现在,如果我们调用/actuator/health 端点,它将在JSON响应中告诉我们新的健康组。

{"status":"UP","groups":["custom"]}

With health groups, we can see the aggregated results of a few health indicators.

通过健康组,我们可以看到一些健康指标的汇总结果。

In this case, if we send a request to /actuator/health/custom, then:

在这种情况下,如果我们向/actuator/health/custom发送一个请求,那么。

{"status":"UP"}

We can configure the group to show more details via application.properties:

我们可以通过application.properties配置该组以显示更多细节。

management.endpoint.health.group.custom.show-components=always
management.endpoint.health.group.custom.show-details=always

Now if we send the same request to /actuator/health/custom, we’ll see more details:

现在,如果我们向/actuator/health/custom>发送同样的请求,我们会看到更多的细节。

{
  "status": "UP",
  "components": {
    "diskSpace": {
      "status": "UP",
      "details": {
        "total": 499963170816,
        "free": 91300069376,
        "threshold": 10485760
      }
    },
    "ping": {
      "status": "UP"
    }
  }
}

It’s also possible to show these details only for authorized users:

也可以只为授权用户显示这些细节。

management.endpoint.health.group.custom.show-components=when_authorized
management.endpoint.health.group.custom.show-details=when_authorized

We can also have a custom status mapping.

我们也可以有一个自定义的状态映射。

For instance, instead of an HTTP 200 OK response, it can return a 207 status code:

例如,它可以返回一个207状态代码,而不是HTTP 200 OK响应。

management.endpoint.health.group.custom.status.http-mapping.up=207

Here, we’re telling Spring Boot to return a 207 HTTP status code if the custom group status is UP.

在这里,我们告诉Spring Boot,如果custom group的状态是UP.,则返回207 HTTP状态代码。

3.7. Metrics in Spring Boot 2

3.7.Spring Boot 2中的衡量标准

In Spring Boot 2.0, the in-house metrics were replaced with Micrometer support, so we can expect breaking changes. If our application was using metric services such as GaugeService or CounterService, they will no longer be available.

在Spring Boot 2.0中,内部度量衡被Micrometer支持所取代,因此我们可以预期会有一些变化。如果我们的应用程序正在使用诸如GaugeServiceCounterService等度量衡服务,它们将不再可用。

Instead, we’re expected to interact with Micrometer directly. In Spring Boot 2.0, we’ll get a bean of type MeterRegistry autoconfigured for us.

相反,我们应该与Micrometer直接互动。在Spring Boot 2.0中,我们将得到一个为我们自动配置的MeterRegistry类型的bean。

Furthermore, Micrometer is now part of Actuator’s dependencies, so we should be good to go as long as the Actuator dependency is in the classpath.

此外,Micrometer现在是Actuator依赖的一部分,所以只要Actuator的依赖在classpath中,我们就应该可以正常使用。

Moreover, we’ll get a completely new response from the /metrics endpoint:

此外,我们将从/metrics端点得到一个全新的响应。

{
  "names": [
    "jvm.gc.pause",
    "jvm.buffer.memory.used",
    "jvm.memory.used",
    "jvm.buffer.count",
    // ...
  ]
}

As we can see, there are no actual metrics as we got in 1.x.

我们可以看到,没有像我们在1.x中得到的实际衡量标准。

To get the actual value of a specific metric, we can now navigate to the desired metric, e.g., /actuator/metrics/jvm.gc.pause, and get a detailed response:

为了得到一个特定指标的实际值,我们现在可以导航到所需的指标,例如,/actuator/metrics/jvm.gc.pause,并得到一个详细的回应。

{
  "name": "jvm.gc.pause",
  "measurements": [
    {
      "statistic": "Count",
      "value": 3.0
    },
    {
      "statistic": "TotalTime",
      "value": 7.9E7
    },
    {
      "statistic": "Max",
      "value": 7.9E7
    }
  ],
  "availableTags": [
    {
      "tag": "cause",
      "values": [
        "Metadata GC Threshold",
        "Allocation Failure"
      ]
    },
    {
      "tag": "action",
      "values": [
        "end of minor GC",
        "end of major GC"
      ]
    }
  ]
}

Now metrics are much more thorough, including not only different values but also some associated metadata.

现在的衡量标准要彻底得多,不仅包括不同的数值,还包括一些相关的元数据。

3.8. Customizing the /info Endpoint

3.8.定制/info端点

The /info endpoint remains unchanged. As before, we can add git details using the respective Maven or Gradle dependency:

/info 端点保持不变。和以前一样,我们可以使用相应的Maven或Gradle依赖性来添加git细节

<dependency>
    <groupId>pl.project13.maven</groupId>
    <artifactId>git-commit-id-plugin</artifactId>
</dependency>

Likewise, we could also include build information including name, group, and version using the Maven or Gradle plugin:

同样,我们也可以使用Maven或Gradle插件包括构建信息,包括名称、组和版本

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <executions>
        <execution>
            <goals>
                <goal>build-info</goal>
            </goals>
        </execution>
    </executions>
</plugin>

3.9. Creating a Custom Endpoint

3.9.创建一个自定义端点

As we pointed out previously, we can create custom endpoints. However, Spring Boot 2 has redesigned the way to achieve this to support the new technology-agnostic paradigm.

正如我们之前指出的,我们可以创建自定义端点。然而,Spring Boot 2重新设计了实现这一目的的方式,以支持新的技术无关的范式。

Let’s create an Actuator endpoint to query, enable, and disable feature flags in our application:

让我们创建一个执行器端点,在我们的应用程序中查询、启用和禁用功能标志

@Component
@Endpoint(id = "features")
public class FeaturesEndpoint {

    private Map<String, Feature> features = new ConcurrentHashMap<>();

    @ReadOperation
    public Map<String, Feature> features() {
        return features;
    }

    @ReadOperation
    public Feature feature(@Selector String name) {
        return features.get(name);
    }

    @WriteOperation
    public void configureFeature(@Selector String name, Feature feature) {
        features.put(name, feature);
    }

    @DeleteOperation
    public void deleteFeature(@Selector String name) {
        features.remove(name);
    }

    public static class Feature {
        private Boolean enabled;

        // [...] getters and setters 
    }

}

To get the endpoint, we need a bean. In our example, we’re using @Component for this. Also, we need to decorate this bean with @Endpoint.

为了获得端点,我们需要一个Bean。在我们的例子中,我们使用@Component来实现。另外,我们需要用@Endpoint来装饰这个Bean。

The path of our endpoint is determined by the id parameter of @Endpoint. In our case, it’ll route requests to /actuator/features.

我们的端点的路径是由@Endpoint.id参数决定的。在我们的例子中,它将把请求导向/actuator/features

Once ready, we can start defining operations using:

一旦准备好,我们就可以开始使用定义操作了。

  • @ReadOperation: It’ll map to HTTP GET.
  • @WriteOperation: It’ll map to HTTP POST.
  • @DeleteOperation: It’ll map to HTTP DELETE.

When we run the application with the previous endpoint in our application, Spring Boot will register it.

当我们在应用程序中使用前一个端点运行应用程序时,Spring Boot将注册它。

A quick way to verify this is to check the logs:

验证这一点的一个快速方法是检查日志。

[...].WebFluxEndpointHandlerMapping: Mapped "{[/actuator/features/{name}],
  methods=[GET],
  produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}"
[...].WebFluxEndpointHandlerMapping : Mapped "{[/actuator/features],
  methods=[GET],
  produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}"
[...].WebFluxEndpointHandlerMapping : Mapped "{[/actuator/features/{name}],
  methods=[POST],
  consumes=[application/vnd.spring-boot.actuator.v2+json || application/json]}"
[...].WebFluxEndpointHandlerMapping : Mapped "{[/actuator/features/{name}],
  methods=[DELETE]}"[...]

In the previous logs, we can see how WebFlux is exposing our new endpoint. If we switch to MVC, it’ll simply delegate on that technology without having to change any code.

在前面的日志中,我们可以看到WebFlux是如何暴露我们的新端点的。如果我们切换到MVC,它就会简单地在该技术上进行委托,而不需要改变任何代码。

Also, we have a few important considerations to keep in mind with this new approach:

此外,我们还有一些重要的考虑因素要在这个新方法中牢记。

  • There are no dependencies with MVC.
  • All the metadata present as methods before (sensitive, enabled…) no longer exist. We can, however, enable or disable the endpoint using @Endpoint(id = “features”, enableByDefault = false).
  • Unlike in 1.x, there is no need to extend a given interface anymore.
  • In contrast with the old read/write model, we can now define DELETE operations using @DeleteOperation.

3.10. Extending Existing Endpoints

3.10.扩展现有的端点

Let’s imagine we want to make sure the production instance of our application is never a SNAPSHOT version.

让我们设想一下,我们想确保我们应用程序的生产实例永远不是SNAPSHOT版本。

We decide to do this by changing the HTTP status code of the Actuator endpoint that returns this information, i.e., /info. If our app happened to be a SNAPSHOT, we would get a different HTTP status code.

我们决定通过改变返回该信息的Actuator端点的HTTP状态代码来实现,即/info。如果我们的应用程序碰巧是一个SNAPSHOT,我们将得到一个不同的HTTP状态代码。

We can easily extend the behavior of a predefined endpoint using the @EndpointExtension annotations, or its more concrete specializations @EndpointWebExtension or @EndpointJmxExtension:

我们可以使用@EndpointExtension注解或其更具体的特化@EndpointWebExtension@EndpointJmxExtension轻松扩展预定义端点的行为。

@Component
@EndpointWebExtension(endpoint = InfoEndpoint.class)
public class InfoWebEndpointExtension {

    private InfoEndpoint delegate;

    // standard constructor

    @ReadOperation
    public WebEndpointResponse<Map> info() {
        Map<String, Object> info = this.delegate.info();
        Integer status = getStatus(info);
        return new WebEndpointResponse<>(info, status);
    }

    private Integer getStatus(Map<String, Object> info) {
        // return 5xx if this is a snapshot
        return 200;
    }
}

3.11. Enable All Endpoints

3.11.启用所有端点

In order to access the actuator endpoints using HTTP, we need to both enable and expose them.

为了使用HTTP访问执行器端点,我们需要同时启用和公开它们。

By default, all endpoints but /shutdown are enabled. Only the /health and /info endpoints are exposed by default.

默认情况下,除了/shutdown之外,所有的端点都被启用。默认情况下,只有/health/info端点被暴露。

We need to add the following configuration to expose all endpoints:

我们需要添加以下配置来暴露所有的端点。

management.endpoints.web.exposure.include=*

To explicitly enable a specific endpoint (e.g., /shutdown), we use:

要明确地启用一个特定的端点(例如,/shutdown),我们使用。

management.endpoint.shutdown.enabled=true

To expose all enabled endpoints except one (e.g., /loggers), we use:

为了暴露所有启用的端点,除了一个(例如,/loggers),我们使用。

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

4. Spring Boot 1.x Actuator

4.Spring Boot 1.x执行器

In 1.x, Actuator follows a read/write model, which means we can either read from it or write to it.

在1.x版本中,Actuator遵循读/写模式,这意味着我们可以从它那里读取或写入它。

For example, we can retrieve metrics or the health of our application. Alternatively, we could gracefully terminate our app or change our logging configuration.

例如,我们可以检索指标或我们应用程序的健康状况。另外,我们可以优雅地终止我们的应用程序或改变我们的日志配置。

In order to get it working, Actuator requires Spring MVC to expose its endpoints through HTTP. No other technology is supported.

为了让它工作,Actuator需要Spring MVC通过HTTP暴露其端点。不支持其他技术。

4.1. Endpoints

4.1.端点

In 1.x, Actuator brings its own security model. It takes advantage of Spring Security constructs but needs to be configured independently from the rest of the application.

在1.x中,Actuator带来了自己的安全模型。它利用了Spring安全结构的优势,但需要独立于应用程序的其他部分进行配置。

Also, most endpoints are sensitive — meaning they’re not fully public, or most information will be omitted — while a handful are not, e.g., /info.

另外,大多数端点是敏感的–意味着它们不完全公开,或者大部分信息将被省略–而少数端点则不是,例如/info

Here are some of the most common endpoints Boot provides out of the box:

以下是Boot提供的一些最常见的端点,开箱即用。

  • /health shows application health information (a simple status when accessed over an unauthenticated connection or full message details when authenticated); it’s not sensitive by default.
  • /info displays arbitrary application info; it’s not sensitive by default.
  • /metrics shows metrics information for the current application; it’s sensitive by default.
  • /trace displays trace information (by default the last few HTTP requests).

We can find the full list of existing endpoints over on the official docs.

我们可以在官方文档上找到现有端点的完整列表

4.2. Configuring Existing Endpoints

4.2.配置现有的端点

We can customize each endpoint with properties using the format endpoints.[endpoint name].[property to customize].

我们可以使用格式endpoints. [endpoint name]. [property to customize],用属性来定制每个端点。

Three properties are available:

有三处房产可供选择。

  • id: by which this endpoint will be accessed over HTTP
  • enabled: if true, then it can be accessed; otherwise not
  • sensitive: if true, then need the authorization to show crucial information over HTTP

For example, adding the following properties will customize the /beans endpoint:

例如,添加以下属性将定制/beans端点

endpoints.beans.id=springbeans
endpoints.beans.sensitive=false
endpoints.beans.enabled=true

4.3. /health Endpoint

4.3./health 端点

The /health endpoint is used to check the health or state of the running application.

/health端点用于检查运行中的应用程序的健康或状态。

It’s usually exercised by monitoring software to alert us if the running instance goes down or gets unhealthy for other reasons, e.g., connectivity issues with our DB, lack of disk space, etc.

它通常由监控软件行使,以提醒我们,如果正在运行的实例发生故障或由于其他原因变得不健康,例如,与我们的数据库的连接问题,缺乏磁盘空间,等等。

By default, unauthorized users can only see status information when they access over HTTP:

默认情况下,未经授权的用户只有在通过HTTP访问时才能看到状态信息。

{
    "status" : "UP"
}

This health information is collected from all the beans implementing the HealthIndicator interface configured in our application context.

这些健康信息是从我们的应用程序上下文中配置的所有实现HealthIndicator接口的bean中收集的。

Some information returned by HealthIndicator is sensitive in nature, but we can configure endpoints.health.sensitive=false to expose more detailed information like disk space, messaging broker connectivity, custom checks, and more.

HealthIndicator返回的一些信息在本质上是敏感的,但我们可以配置endpoints.health.sensitive=false以暴露更详细的信息,如磁盘空间、消息代理连接、自定义检查等等。

Note that this only works for Spring Boot versions below 1.5.0. For 1.5.0 and later versions, we should also disable security by setting management.security.enabled=false for unauthorized access.

注意,这只适用于1.5.0以下的Spring Boot版本。对于1.5.0及以后的版本,我们还应该通过设置management.security.enabled=false来禁用未经授权的访问。

We could also implement our own custom health indicator, which can collect any type of custom health data specific to the application and automatically expose it through the /health endpoint:

我们还可以实现我们自己的自定义健康指标,它可以收集特定于应用程序的任何类型的自定义健康数据,并通过/health端点自动将其公开。

@Component("myHealthCheck")
public class HealthCheck implements HealthIndicator {
 
    @Override
    public Health health() {
        int errorCode = check(); // perform some specific health check
        if (errorCode != 0) {
            return Health.down()
              .withDetail("Error Code", errorCode).build();
        }
        return Health.up().build();
    }
    
    public int check() {
    	// Our logic to check health
    	return 0;
    }
}

Here’s how the output would look:

下面是输出的情况。

{
    "status" : "DOWN",
    "myHealthCheck" : {
        "status" : "DOWN",
        "Error Code" : 1
     },
     "diskSpace" : {
         "status" : "UP",
         "free" : 209047318528,
         "threshold" : 10485760
     }
}

4.4. /info Endpoint

4.4./info 端点

We can also customize the data shown by the /info endpoint:

我们还可以自定义/info端点所显示的数据。

info.app.name=Spring Sample Application
info.app.description=This is my first spring boot application
info.app.version=1.0.0

And the sample output:

以及输出的样本。

{
    "app" : {
        "version" : "1.0.0",
        "description" : "This is my first spring boot application",
        "name" : "Spring Sample Application"
    }
}

4.5. /metrics Endpoint

4.5./metrics 端点

The metrics endpoint publishes information about OS and JVM as well as application-level metrics. Once enabled, we get information such as memory, heap, processors, threads, classes loaded, classes unloaded, and thread pools along with some HTTP metrics as well.

指标端点发布了关于操作系统和JVM以及应用程序级别的指标信息。一旦启用,我们就会得到诸如内存、堆、处理器、线程、加载的类、卸载的类、线程池以及一些HTTP指标等信息。

Here’s what the output of this endpoint looks like out of the box:

下面是这个端点的输出结果,是开箱后的样子。

{
    "mem" : 193024,
    "mem.free" : 87693,
    "processors" : 4,
    "instance.uptime" : 305027,
    "uptime" : 307077,
    "systemload.average" : 0.11,
    "heap.committed" : 193024,
    "heap.init" : 124928,
    "heap.used" : 105330,
    "heap" : 1764352,
    "threads.peak" : 22,
    "threads.daemon" : 19,
    "threads" : 22,
    "classes" : 5819,
    "classes.loaded" : 5819,
    "classes.unloaded" : 0,
    "gc.ps_scavenge.count" : 7,
    "gc.ps_scavenge.time" : 54,
    "gc.ps_marksweep.count" : 1,
    "gc.ps_marksweep.time" : 44,
    "httpsessions.max" : -1,
    "httpsessions.active" : 0,
    "counter.status.200.root" : 1,
    "gauge.response.root" : 37.0
}

In order to gather custom metrics, we have support for gauges (single-value snapshots of data) and counters, i.e., incrementing/decrementing metrics.

为了收集自定义指标,我们支持仪表(数据的单值快照)和计数器,即递增/递减的指标。

Let’s implement our own custom metrics into the /metrics endpoint.

让我们在/metrics端点中实现我们自己的自定义指标。

We’ll customize the login flow to record a successful and failed login attempt:

我们将定制登录流程以记录成功和失败的登录尝试。

@Service
public class LoginServiceImpl {

    private final CounterService counterService;
    
    public LoginServiceImpl(CounterService counterService) {
        this.counterService = counterService;
    }
	
    public boolean login(String userName, char[] password) {
        boolean success;
        if (userName.equals("admin") && "secret".toCharArray().equals(password)) {
            counterService.increment("counter.login.success");
            success = true;
        }
        else {
            counterService.increment("counter.login.failure");
            success = false;
        }
        return success;
    }
}

Here’s what the output might look like:

下面是输出结果可能是什么样子。

{
    ...
    "counter.login.success" : 105,
    "counter.login.failure" : 12,
    ...
}

Note that login attempts and other security-related events are available out of the box in Actuator as audit events.

请注意,登录尝试和其他与安全有关的事件在Actuator中是作为审计事件开箱即用的。

4.6. Creating a New Endpoint

4.6.创建一个新的端点

In addition to using the existing endpoints provided by Spring Boot, we can also create an entirely new one.

除了使用Spring Boot提供的现有端点外,我们还可以创建一个全新的端点。

First, we need to have the new endpoint implement the Endpoint<T> interface:

首先,我们需要让新的端点实现Endpoint<T>接口。

@Component
public class CustomEndpoint implements Endpoint<List<String>> {
    
    @Override
    public String getId() {
        return "customEndpoint";
    }

    @Override
    public boolean isEnabled() {
        return true;
    }

    @Override
    public boolean isSensitive() {
        return true;
    }

    @Override
    public List<String> invoke() {
        // Custom logic to build the output
        List<String> messages = new ArrayList<String>();
        messages.add("This is message 1");
        messages.add("This is message 2");
        return messages;
    }
}

In order to access this new endpoint, its id is used to map it. In other words we could exercise it hitting /customEndpoint.

为了访问这个新的端点,它的id被用来映射它。换句话说,我们可以行使它打/customEndpoint

Output:

输出。

[ "This is message 1", "This is message 2" ]

4.7. Further Customization

4.7.进一步定制

For security purposes, we might choose to expose the actuator endpoints over a non-standard port — the management.port property can easily be used to configure that.

为了安全起见,我们可能会选择通过一个非标准的端口暴露执行器端点–management.port属性可以很容易地用于配置。

Also, as we already mentioned, in 1.x. Actuator configures its own security model based on Spring Security but independent from the rest of the application.

另外,正如我们已经提到的,在1.x.中,Actuator基于Spring Security配置了自己的安全模型,但独立于应用程序的其他部分。

Hence, we can change the management.address property to restrict where the endpoints can be accessed from over the network:

因此,我们可以改变management.address属性,以限制端点在网络上可以被访问的地方。

#port used to expose actuator
management.port=8081 

#CIDR allowed to hit actuator
management.address=127.0.0.1 

#Whether security should be enabled or disabled altogether
management.security.enabled=false

Besides, all the built-in endpoints except /info are sensitive by default.

此外,除了/info,所有内置的端点默认都是敏感的。

If the application is using Spring Security, we can secure these endpoints by defining the default security properties (username, password, and role) in the application.properties file:

如果应用程序使用Spring Security,我们可以通过在application.properties文件中定义默认安全属性(用户名、密码和角色)来保护这些端点。

security.user.name=admin
security.user.password=secret
management.security.role=SUPERUSER

5. Conclusion

5.结论

In this article, we talked about Spring Boot Actuator. We began by defining what Actuator means and what it does for us.

在这篇文章中,我们谈到了Spring Boot Actuator。我们首先定义了Actuator的含义,以及它为我们做了什么。

Next, we focused on Actuator for the current Spring Boot version 2.x, discussing how to use it, tweak it, and extend it. We also talked about the important security changes that we can find in this new iteration. We discussed some popular endpoints and how they have changed as well.

接下来,我们重点讨论了当前Spring Boot 2.x版本的Actuator,讨论了如何使用它、调整它和扩展它。我们还谈到了在这个新的迭代中可以发现的重要安全变化。我们讨论了一些流行的端点,以及它们是如何变化的。

Then we discussed Actuator in the earlier Spring Boot 1 version.

然后我们讨论了早期Spring Boot 1版本中的Actuator。

Lastly, we demonstrated how to customize and extend Actuator.

最后,我们演示了如何定制和扩展Actuator。

As always, the code used in this article can be found over on GitHub for both Spring Boot 2.x and Spring Boot 1.x.

一如既往,本文中使用的代码可以在GitHub上找到,包括Spring Boot 2.xSpring Boot 1.x