提交 36b98f0f 编写于 作者: 武汉红喜's avatar 武汉红喜

actuator

上级 b55f7c46
## My Actuator Starter
- ActuatorEnvironmentPostProcessor: 设置actuator相关properties,限定用户不可修改endpoint相关属性,关闭`spring-boot-starter-actuator`默认配置
- StandardWebSecurityConfigurer: 重写Security策略
- ActuatorReporter: 上报metrics数据至时序数据库
```
http://localhost:8080/actuator/prometheus?x_token=whatsmars-spring-boot
curl http://localhost:8080/actuator/mappings -u application:whatsmars-spring-boot
```
\ No newline at end of file
......@@ -24,8 +24,8 @@
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.hongxi</groupId>
......
package org.hongxi.whatsmars.boot.sample.actuator;
import org.hongxi.whatsmars.boot.sample.actuator.filter.ActuatorFilter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.WebSecurityConfigurer;
/**
* Created by shenhongxi on 2020/7/17.
......@@ -12,8 +13,14 @@ import org.springframework.context.annotation.Configuration;
@ConditionalOnWebApplication
public class ActuatorAutoConfiguration {
@Order(99)
@Bean
public ActuatorFilter actuatorFilter() {
return new ActuatorFilter();
public WebSecurityConfigurer standardWebSecurityConfigurer() {
return new StandardWebSecurityConfigurer();
}
@Bean
public ActuatorReporter actuatorReporter() {
return new ActuatorReporter();
}
}
package org.hongxi.whatsmars.boot.sample.actuator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.ConfigurableEnvironment;
/**
* Created by shenhongxi on 2020/7/17.
*/
public class ActuatorEnvironmentPostProcessor implements EnvironmentPostProcessor {
private static final String TRUE = "true";
private static final String FALSE = "false";
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
resolveManagement(environment);
resolveSecurity(environment);
}
private void resolveSecurity(final ConfigurableEnvironment environment) {
if (!environment.containsProperty("spring.security.user.name")) {
System.setProperty("spring.security.user.name", "application");
}
if (!environment.containsProperty("spring.security.user.password")) {
System.setProperty("spring.security.user.password", "whatsmars-spring-boot");
}
if (!environment.containsProperty("spring.security.user.roles")) {
System.setProperty("spring.security.user.roles", "application");
}
}
private void resolveManagement(final ConfigurableEnvironment environment) {
// 有关Endpoints安全问题
String excludes = environment.getProperty("spring.autoconfigure.exclude");
StringBuilder sb = new StringBuilder();
if (excludes != null) {
sb.append(",");
}
// 关闭spring-boot默认的security配置
sb.append(ManagementWebSecurityAutoConfiguration.class.getName());
System.setProperty("spring.autoconfigure.exclude", sb.toString());
// 默认全部关闭
System.setProperty("management.endpoints.enabled-by-default", FALSE);
System.setProperty("management.endpoints.web.exposure.include", "*");
System.setProperty("management.endpoints.web.exposure.exclude", "shutdown,threaddump,heapdump");
System.setProperty("management.endpoint.health.enabled", TRUE);
System.setProperty("management.endpoint.health.show-details", "never");
System.setProperty("management.endpoint.info.enabled", TRUE);
System.setProperty("management.endpoint.mappings.enabled", TRUE);
System.setProperty("management.endpoint.env.enabled", TRUE);
System.setProperty("management.endpoint.conditions.enabled", TRUE);
System.setProperty("management.endpoint.configprops.enabled", TRUE);
System.setProperty("management.endpoint.beans.enabled", TRUE);
System.setProperty("management.endpoint.loggers.enabled", TRUE);
System.setProperty("management.endpoint.metrics.enabled", TRUE);
System.setProperty("management.metrics.enable.http", FALSE);
System.setProperty("management.metrics.enable.log4j2", FALSE);
System.setProperty("server.tomcat.mbeanregistry.enabled", TRUE);
}
}
package org.hongxi.whatsmars.boot.sample.actuator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.actuate.metrics.MetricsEndpoint;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* Created by shenhongxi on 2020/7/30.
*/
@Slf4j
public class ActuatorReporter implements CommandLineRunner {
@Autowired(required = false)
private MetricsEndpoint metricsEndpoint;
private ExecutorService executorService;
@Override
public void run(String... args) throws Exception {
log.info("metrics endpoint is open : {}", metricsEndpoint != null);
if (metricsEndpoint != null) {
Set<String> names = metricsEndpoint.listNames().getNames();
if (names.isEmpty()) {
return;
}
executorService = Executors.newFixedThreadPool(4);
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(
() -> report(names), 1, 3, TimeUnit.SECONDS
);
}
}
private void report(Set<String> names) {
names.forEach(name -> {
executorService.submit(() -> {
// store in time series database
});
});
}
}
package org.hongxi.whatsmars.boot.sample.actuator;
import org.hongxi.whatsmars.common.util.SystemUtils;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.ConfigurableEnvironment;
/**
* Created by shenhongxi on 2020/7/17.
*/
public class EnvironmentProcessor implements EnvironmentPostProcessor {
public static final String PROP_METRICS_INCLUDE = "management.endpoints.web.exposure.include";
public static final String PROP_METRICS_TAGS = "management.metrics.tags.application";
public static final String PROP_TOMCAT_MBEAN_ENABLED = "server.tomcat.mbeanregistry.enabled";
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
if (!SystemUtils.contains(PROP_METRICS_INCLUDE)) {
System.setProperty(PROP_METRICS_INCLUDE, "prometheus");
}
if (!SystemUtils.contains(PROP_METRICS_TAGS)) {
System.setProperty(PROP_METRICS_TAGS, environment.getProperty("spring.application.name", "actuator-sample"));
}
if (!SystemUtils.contains(PROP_TOMCAT_MBEAN_ENABLED)) {
System.setProperty(PROP_TOMCAT_MBEAN_ENABLED, "true");
}
}
}
package org.hongxi.whatsmars.boot.sample.actuator;
import org.springframework.boot.actuate.autoconfigure.condition.ConditionsReportEndpoint;
import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
import org.springframework.boot.actuate.beans.BeansEndpoint;
import org.springframework.boot.actuate.context.properties.ConfigurationPropertiesReportEndpoint;
import org.springframework.boot.actuate.env.EnvironmentEndpoint;
import org.springframework.boot.actuate.logging.LoggersEndpoint;
import org.springframework.boot.actuate.metrics.MetricsEndpoint;
import org.springframework.boot.actuate.web.mappings.MappingsEndpoint;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
/**
* Created by shenhongxi on 2020/7/30.
*/
public class StandardWebSecurityConfigurer extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) throws Exception {
// 普通web资源
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.requestMatchers(EndpointRequest.to(
MappingsEndpoint.class,
EnvironmentEndpoint.class,
ConditionsReportEndpoint.class,
ConfigurationPropertiesReportEndpoint.class,
BeansEndpoint.class,
LoggersEndpoint.class,
MetricsEndpoint.class))
.hasRole("application")
.anyRequest()
.permitAll()
.and()
.httpBasic();
}
}
\ No newline at end of file
package org.hongxi.whatsmars.boot.sample.actuator.filter;
import org.springframework.http.HttpStatus;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Created by shenhongxi on 2020/7/17.
*/
public class ActuatorFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
if (security(request)) {
filterChain.doFilter(request, response);
} else {
response.sendError(HttpStatus.UNAUTHORIZED.value());
}
}
private boolean security(HttpServletRequest request) {
// 当用requestURI时用 curl http://127.0.0.1:8080/actuator/svg/../prometheus 可以访问
if (request.getServletPath() == null) {
return true;
}
if (!request.getServletPath().startsWith("/actuator")) {
return true;
}
return "whatsmars-spring-boot".equals(request.getParameter("x_token"));
}
}
# Post Processors
org.springframework.boot.env.EnvironmentPostProcessor=\
org.hongxi.whatsmars.boot.sample.actuator.EnvironmentProcessor
org.hongxi.whatsmars.boot.sample.actuator.ActuatorEnvironmentPostProcessor
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册