监控服务常见功能使用
服务环境状态查看
监控面板展示微服务所在宿主机的磁盘、Java 运行环境、堆栈内存以及其他中间件的资源占用等信息。
在线日志查看
服务部署在服务器上时,大部分公司都有对服务器的安全管理要求,开发人员通常无法登录服务器查看后台日志。这导致应用系统报错时,程序员无法快速定位错误。
通过 Spring Boot Admin(pigx-monitor)组件,可以在线查看后端服务日志,无需登录服务器即可进行问题排查。
配置 Logback 输出路径
配置步骤:
- 修改目标微服务的
logback-spring.xml 文件
- 修改
log.path 为服务器实际的日志文件存储目录
配置 Monitor 日志加载
在监控服务中配置日志文件路径:
LOGGING_PATH: 对应如上图②处实际的日志文件存储目录
💡路径配置一致性
确保 Monitor 服务的 LOGGING_PATH 配置与微服务的 logback-spring.xml 中的 log.path 路径保持一致。
动态日志级别
应用默认的日志输出级别是 INFO,生产环境建议使用 ERROR 级别。
当遇到某些 Bug 时,动态调整日志输出级别非常有效。Spring Boot Admin 提供了在线调整日志级别的功能,无需重启服务即可调整日志输出详细程度。
⚠配置临时生效
目标服务重启后,动态调整的日志级别配置将失效,恢复为配置文件中的默认级别。
监控安全认证
默认情况下,Spring Boot Admin 不提供安全认证,任何用户都可以访问监控面板。为了保护监控信息,建议配置安全认证。
添加安全依赖
在监控服务的 pom.xml 中添加 Spring Security 依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
创建 CustomCsrfFilter
创建自定义 CSRF 过滤器,处理跨站请求伪造防护:
package com.pig4cloud.pigx.monitor.config;
public class CustomCsrfFilter extends OncePerRequestFilter {
public static final String CSRF_COOKIE_NAME = "XSRF-TOKEN";
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, CSRF_COOKIE_NAME);
String token = csrf.getToken();
if (cookie == null || token != null && !token.equals(cookie.getValue())) {
cookie = new Cookie(CSRF_COOKIE_NAME, token);
cookie.setPath("/");
response.addCookie(cookie);
}
}
filterChain.doFilter(request, response);
}
}
创建 SecurityConfig
创建 Spring Security 配置类,定义安全策略:
package com.pig4cloud.pigx.monitor.config;
@Configuration(proxyBeanMethods = false)
public class SecuritySecureConfig {
private final AdminServerProperties adminServer;
private final SecurityProperties security;
public SecuritySecureConfig(AdminServerProperties adminServer, SecurityProperties security) {
this.adminServer = adminServer;
this.security = security;
}
@Bean
protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
successHandler.setTargetUrlParameter("redirectTo");
successHandler.setDefaultTargetUrl(this.adminServer.path("/"));
http.authorizeHttpRequests((authorizeRequests) -> authorizeRequests //
.requestMatchers(new AntPathRequestMatcher(this.adminServer.path("/assets/**")))
.permitAll()
.requestMatchers(new AntPathRequestMatcher(this.adminServer.path("/actuator/info")))
.permitAll()
.requestMatchers(new AntPathRequestMatcher(adminServer.path("/actuator/health")))
.permitAll()
.requestMatchers(new AntPathRequestMatcher(this.adminServer.path("/login")))
.permitAll()
.dispatcherTypeMatchers(DispatcherType.ASYNC)
.permitAll() // https://github.com/spring-projects/spring-security/issues/11027
.anyRequest()
.authenticated())
.formLogin(
(formLogin) -> formLogin.loginPage(this.adminServer.path("/login")).successHandler(successHandler))
.logout((logout) -> logout.logoutUrl(this.adminServer.path("/logout")))
.httpBasic(Customizer.withDefaults());
http.addFilterAfter(new CustomCsrfFilter(), BasicAuthenticationFilter.class) // <5>
.csrf((csrf) -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.csrfTokenRequestHandler(new CsrfTokenRequestAttributeHandler())
.ignoringRequestMatchers(
new AntPathRequestMatcher(this.adminServer.path("/instances"), POST.toString()), // <6>
new AntPathRequestMatcher(this.adminServer.path("/instances/*"), DELETE.toString()), // <6>
new AntPathRequestMatcher(this.adminServer.path("/actuator/**")) // <7>
));
http.rememberMe((rememberMe) -> rememberMe.key(UUID.randomUUID().toString()).tokenValiditySeconds(1209600));
return http.build();
}
// Required to provide UserDetailsService for "remember functionality"
@Bean
public InMemoryUserDetailsManager userDetailsService(PasswordEncoder passwordEncoder) {
UserDetails user = User.withUsername(security.getUser().getName())
.password(passwordEncoder.encode(security.getUser().getPassword()))
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
配置登录用户
在 application.yml 中配置登录用户名和密码:
spring:
security:
user:
name: pigx
password: pigx
⚠修改默认密码
生产环境请务必修改默认的用户名和密码,使用强密码策略以确保监控服务的安全性。