7. Actuator
To enable Actuator, you just add in build.gradle:
compile 'org.springframework.boot:spring-boot-starter-actuator'
Spring Boot Actuator provides a series of RESTful interfaces:
HTTP method | Route | describe |
---|---|---|
GET | /beans | All bean s in Spring application context and their dependencies |
GET | /autoconfig | Automatic configuration report, which automatic configuration is valid or invalid |
GET | /env | Various environmental attributes |
GET | /env/{name} | Retrieving environment attributes by name |
GET | /configprops | Various configuration attributes |
GET | /mappings | Mapping URI Path to Controller |
GET | /metrics | Various indicators |
GET | /metrics/{name} | Name-based index retrieval |
GET | /trace | Recent 100 HTTP request tracking (data in memory) |
GET | /dump | Snapshot of thread activity |
GET | /health | Application of health indicators, provided by the implementation of the Health Indicator interface |
POST | /shutdown | Close application |
GET | /info | Provide custom information about applications |
These information can be divided into three categories: configuration, metrics and miscellaneous. For security, any name or last part of a name is shown as an attribute of "password", "secret" or "key".
7.1 Configuration Information
Including / beans, / autoconfig, / env, / env/{name}, / configprops, / mappings
7.2 Indicator Information
The / metrics interface returns various metrics, categorized by prefix:
classification | prefix | describe |
---|---|---|
garbage collector | gc.* | mark-sweep and scavenge garbage collectors garbage collection count and duration (from java.lang.management.Garbage Collector MXBean) |
Memory | mem.* | Memory allocated to applications and free memory (from java.lang.Runtime) |
heap | heap.* | Current memory usage (from java.lang.management.MemoryUsage) |
classloader | classes.* | Number of classes loaded and unloaded by the JVM class loader (from java.lang.management.ClassLoading MXBean) |
system | processors,uptime,instance.uptime,systemload.average | Number of processors (from java.lang.Runtime), run time (from java. lang. management. Runtime MXBean), average system load (from java. lang. management. Operating System MXBean) |
Thread pool | threads.* | Threads, number of daemon threads, and peak threads (from java.lang.management.ThreadMXBean) since JVM startup |
data source | datasource.* | Number of data source connections (from the data source's metadata, only if there is a data source bean) |
HTTP session | httpsessions.* | Active and maximum number of sessions (from the embedded Tomcat bean, only if there is a built-in server) |
HTTP | counter.status.,gauge.response. | Various measures and statistics of HTTP requests |
The/health interface returns various health indicators:
Health indicator | Key | Reports |
---|---|---|
ApplicationHealthIndicator | none | Always "UP" |
DataSourceHealthIndicator | db | "UP" and database type if the database can be contacted; "DOWN" status otherwise |
DiskSpaceHealthIndicator | diskSpace | "UP" and available disk space, and "UP" if available space is above a threshold; "DOWN" if there isn't enough disk space |
JmsHealthIndicator | jms | "UP" and JMS provider name if the message broker can be contacted; "DOWN" otherwise |
MailHealthIndicator | "UP" and the mail server host and port if the mail server can be contacted; "DOWN" otherwise | |
MongoHealthIndicator | mongo | "UP" and the MongoDB server version; "DOWN" otherwise |
RabbitHealthIndicator | rabbit | "UP" and the RabbitMQ broker version; "DOWN" otherwise |
RedisHealthIndicator | redis | "UP" and the Redis server version; "DOWN" otherwise |
SolrHealthIndicator | solr | "UP" if the Solr server can be contacted; "DOWN" otherwise |
Suppose you need to shut down your application, such as in a microservice architecture, and you need to gracefully shut down one of the application instances, you can do this:
curl -X POST http://localhost:8080/shutdown
Obviously, closing an application is a dangerous behavior, so / shutdown is not enabled by default. You need to set endpoints.shutdown.enabled to true to open, and you should pay attention to the permissions of the / shutdown interface.
The / Info interface returns information about the application and the empty JSON object ({}) is returned by default. You add more returns by configuring the properties of the info header:
info:
contact:
email: support@myreadinglist.com
phone: 1-888-555-1971
7.3 Remote Shell
Spring Boot integrates CRaSH (a shell built into Java applications) and provides a series of commands, starting with dependencies:
compile("org.springframework.boot:spring-boot-starter-remote-shell")
Then, when applied, you can use SSH to connect to it (port 2000). The password is the random password printed in the log.
ssh user@localhost -p 2000
You can use the commands provided by Spring Boot: autoconfig, beans, metrics (you can see dynamic updates, Ctrl-C exits), but not every Web interface has a corresponding command, at this time you need the endpoint command:
endpoint list
This returns the endpoint list, but not url s, but their bean name s:
requestMappingEndpoint
environmentEndpoint
healthEndpoint
beansEndpoint
infoEndpoint
metricsEndpoint
traceEndpoint
dumpEndpoint
autoConfigurationReportEndpoint
configurationPropertiesReportEndpoint
Then use the endpoint invoke command (remove the "Endpoint" suffix):
endpoint invoke health
7.4 Customization
7.4.1 Modify endpoint IDs
Each Actuator endpoint has an ID to determine the path. For example, the default ID of / beans is beans. You can modify the path by modifying the endpoints.endpoint-id.id attribute, such as / shutdown to / kill:
endpoints:
shutdown:
id: kill
7.4.2 Disable (Enable) endpoints
You can also disable some endpoint s:
endpoints:
metrics:
enabled: false
You can disable all and enable some:
endpoints:
enabled: false
metrics:
enabled: true
7.4.3 Add custom metrics and gauges
For example, we need to record how many times the user saved the book to the reading list, and how long it last saved, and expose it through / metrics. Actuator automatically configures a CounterService instance for us to help complete the counting function:
package org.springframework.boot.actuate.metrics;
public interface CounterService {
void increment(String metricName);
void decrement(String metricName);
void reset(String metricName);
}
Another example of GaugeService helps set a value for an indicator:
package org.springframework.boot.actuate.metrics;
public interface GaugeService {
void submit(String metricName, double value);
}
You just need to inject the two bean s and call the method directly:
@RequestMapping(method = RequestMethod.POST)
public String addToReadingList(Reader reader, Book book) {
book.setReader(reader);
readingListRepository.save(book);
counterService.increment("books.saved");
gaugeService.submit("books.last.saved", System.currentTimeMillis());
return "redirect:/";
}
For a slightly more complex metrics, the two services above are not enough. At this point, you can implement the PublicMetrics interface:
package org.springframework.boot.actuate.endpoint;
public interface PublicMetrics {
Collection<Metric<?>> metrics();
}
For example, we need to know when application context starts, the number of beans, the number of beans defined, and the number of beans annotated @Controller:
package readinglist;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.endpoint.PublicMetrics;
import org.springframework.boot.actuate.metrics.Metric;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
@Component
public class ApplicationContextMetrics implements PublicMetrics {
@Autowired
private ApplicationContext context;
@Override
public Collection<Metric<?>> metrics() {
List<Metric<?>> metrics = new ArrayList<Metric<?>>();
metrics.add(new Metric<Long>("spring.context.startup-date", context.getStartupDate()));
metrics.add(new Metric<Integer>("spring.beans.definitions", context.getBeanDefinitionCount()));
metrics.add(new Metric<Integer>("spring.beans", context.getBeanNamesForType(Object.class).length));
metrics.add(new Metric<Integer>("spring.controllers", context.getBeanNamesForAnnotation(Controller.class).length));
return metrics;
}
}
Then access / metrics and display our custom metrics:
{
...
spring.context.startup-date: 1429398980443,
spring.beans.definitions: 261,
spring.beans: 272,
spring.controllers: 2,
books.count: 1,
gauge.books.save.time: 1429399793260,
...
}
spring.controllers are 2 because the Basic Error Controller provided by ReadingListController and Spring Book is counted.
7.4.4 Add custom trace repository
By default, the / trace interface uses memory repository with a capacity of 100. We can declare the InMemoryTraceRepository bean ourselves, such as setting the capacity to 1000:
package readinglist;
import org.springframework.boot.actuate.trace.InMemoryTraceRepository;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ActuatorConfig {
@Bean
public InMemoryTraceRepository traceRepository() {
InMemoryTraceRepository traceRepo = new InMemoryTraceRepository();
traceRepo.setCapacity(1000);
return traceRepo;
}
}
Although the capacity has increased, it still consumes memory and has no persistence, so we can implement Spring Boot's TraceRepository interface ourselves:
package org.springframework.boot.actuate.trace;
import java.util.List;
import java.util.Map;
public interface TraceRepository {
List<Trace> findAll();
void add(Map<String, Object> traceInfo);
}
For example, the implementation saves to MongoDB:
package readinglist;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.trace.Trace;
import org.springframework.boot.actuate.trace.TraceRepository;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.stereotype.Service;
@Service
public class MongoTraceRepository implements TraceRepository {
@Autowired
private MongoOperations mongoOps;
@Override
public List<Trace> findAll() {
return mongoOps.findAll(Trace.class);
}
@Override
public void add(Map<String, Object> traceInfo) {
mongoOps.save(new Trace(new Date(), traceInfo));
}
}
As long as you join the starter of MongoDB, you will automatically configure the MongoOperations bean:
compile("org.springframework.boot:spring-boot-starter-data-mongodb")
7.4.5 Custom Health Indicators
For example, we need to add a health indicator to test whether Amazon can access:
package readinglist;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
@Component
public class AmazonHealth implements HealthIndicator {
@Override
public Health health() {
try {
RestTemplate rest = new RestTemplate();
rest.getForObject("http://www.amazon.com", String.class);
return Health.up().build();
} catch (Exception e) {
return Health.down().build();
}
}
}
If you need more detailed information, you can call the withDetail() method, such as changing the code in catch to:
return Health.down().withDetail("reason", e.getMessage()).build();
7.5 Actuator Interface Security
The weighting limit for Actuator paths is the same as that for general paths, but it is obviously troublesome to list all interfaces once with antMatchers, so a common prefix can be configured:
management:
context-path: /mgmt
Then add in the configure() method in SecurityConfig.java:
.antMatchers("/mgmt/**").access("hasRole('ADMIN')")