Spring Boot Actuator端点扩展
Actuator 支持自定义端点暴露业务监控数据。
端点配置
YAML
management:
endpoints:
web:
exposure:
include: health,info,custom
base-path: /actuator
endpoint:
custom:
enabled: true
自定义端点方式
@Endpoint注解
Java
@Component
@Endpoint(id = "custom")
public class CustomEndpoint {
@ReadOperation
public Map<String, Object> info() {
Map<String, Object> info = new HashMap<>();
info.put("app", "my-application");
info.put("version", "1.0.0");
info.put("status", "running");
return info;
}
@ReadOperation
public Map<String, Object> detail(@Selector String name) {
Map<String, Object> detail = new HashMap<>();
detail.put("name", name);
detail.put("value", System.getProperty(name));
return detail;
}
@WriteOperation
public void update(@Selector String name, String value) {
System.setProperty(name, value);
}
@DeleteOperation
public void delete(@Selector String name) {
System.clearProperty(name);
}
}
访问方式:
- GET /actuator/custom
- GET /actuator/custom/{name}
- POST /actuator/custom/{name}?value=xxx
- DELETE /actuator/custom/{name}
@WebEndpoint注解
Java
@Component
@WebEndpoint(id = "app-status")
public class AppStatusEndpoint {
@ReadOperation
public AppStatus status() {
return AppStatus.builder()
.uptime(getUptime())
.memory(getMemoryInfo())
.threads(getThreadInfo())
.build();
}
@ReadOperation
public AppStatus detail(@Selector String component) {
switch (component) {
case "memory":
return AppStatus.memoryOnly(getMemoryInfo());
case "threads":
return AppStatus.threadsOnly(getThreadInfo());
default:
throw new IllegalArgumentException("Unknown component: " + component);
}
}
}
@RestControllerEndpoint注解
Java
@Component
@RestControllerEndpoint(id = "app-info")
public class AppInfoEndpoint {
@GetMapping
public Map<String, Object> info() {
Map<String, Object> info = new HashMap<>();
info.put("name", "my-app");
info.put("version", "1.0.0");
info.put("java", System.getProperty("java.version"));
return info;
}
@GetMapping("/env")
public Map<String, String> env() {
return System.getenv();
}
@GetMapping("/props")
public Properties props() {
return System.getProperties();
}
}
业务监控端点
Java
@Component
@Endpoint(id = "business-metrics")
public class BusinessMetricsEndpoint {
@Autowired
private OrderService orderService;
@Autowired
private UserService userService;
@ReadOperation
public Map<String, Object> metrics() {
Map<String, Object> metrics = new HashMap<>();
metrics.put("order", OrderMetrics.builder()
.totalCount(orderService.getTotalCount())
.todayCount(orderService.getTodayCount())
.pendingCount(orderService.getPendingCount())
.build());
metrics.put("user", UserMetrics.builder()
.totalCount(userService.getTotalCount())
.activeCount(userService.getActiveCount())
.newToday(userService.getNewToday())
.build());
return metrics;
}
}
健康端点扩展
Java
@Component
@Endpoint(id = "app-health")
public class AppHealthEndpoint {
private final List<HealthChecker> checkers;
public AppHealthEndpoint(List<HealthChecker> checkers) {
this.checkers = checkers;
}
@ReadOperation
public HealthResponse health() {
List<HealthDetail> details = checkers.stream()
.map(this::check)
.collect(Collectors.toList());
boolean healthy = details.stream()
.allMatch(HealthDetail::isHealthy);
return HealthResponse.builder()
.status(healthy ? "UP" : "DOWN")
.checks(details)
.timestamp(LocalDateTime.now())
.build();
}
private HealthDetail check(HealthChecker checker) {
try {
boolean healthy = checker.check();
return HealthDetail.builder()
.name(checker.getName())
.healthy(healthy)
.message(healthy ? "OK" : "FAILED")
.build();
} catch (Exception e) {
return HealthDetail.builder()
.name(checker.getName())
.healthy(false)
.message(e.getMessage())
.build();
}
}
}
操作类型
| 注解 | HTTP方法 | 说明 |
|---|---|---|
| @ReadOperation | GET | 读取操作 |
| @WriteOperation | POST | 写入操作 |
| @DeleteOperation | DELETE | 删除操作 |
参数注解
| 注解 | 说明 |
|---|---|
| @Selector | 路径参数 |
| @Nullable | 可选参数 |
Java
@ReadOperation
public Map<String, Object> query(
@Selector String id,
@Nullable String filter) {
// 实现逻辑
}
端点安全
Java
@Configuration
public class ActuatorSecurityConfig {
@Bean
public SecurityFilterChain actuatorSecurity(HttpSecurity http) throws Exception {
http.requestMatcher(EndpointRequest.toAnyEndpoint())
.authorizeRequests(requests ->
requests.anyRequest().hasRole("ACTUATOR"))
.httpBasic();
return http.build();
}
}
生产环境务必配置端点访问权限,避免敏感信息泄露。
要点总结
- @Endpoint用于标准端点
- @RestControllerEndpoint提供完整MVC能力
- @ReadOperation/@WriteOperation/@DeleteOperation定义操作
- @Selector提取路径参数
📝 发现内容有误?点击此处直接编辑