SpringBoot Actuator监控组件笔记

目录

自定义EndPoint

/beans

/health

/loggers 

/info

/threaddump 


Actuator模块可以采集应用内部运行信息暴露给外部,帮助我们监控和管理Spring Boot 应用,功能例如健康检查,运行指标收集,HTTP 跟踪,日志级别等


#开放所有端点

management.endpoints.web.exposure.include=*


#开放指定端点

management.endpoints.web.exposure.include=beans

或者

management.endpoint.beans.enabled=true



#开放所有  &&  关闭某个

management.endpoints.web.exposure.exclude=beans

management.endpoints.web.exposure.include=*



默认情况下所有端点都暴露在“/actuator”路径下,可以自定义

#/actuator/xxx路徑,都变成/manage/xxx

management.endpoints.web.base-path=/manage


#管理端口调整

management.server.port=9999

今天记录我涉及的常用EndPoint,以后有用到其他的随时再记

GET /actuator 查看有哪些 Actuator endpoint 是开放的,和对应的路径
GET /actuator/beans 查看容器中的 bean
GET /actuator/health  查看当前应用指标情况,实现HealthIndicator可以自定义指标项
GET /actuator/loggers 查看当前应用日志级别情况,可以运行时调整
GET /actuator/info

应用信息展示

GET /actuator/threaddump 当前应用线程栈dump,同 jstack

自定义EndPoint

如下代码

@Endpoint注解 定义一个监控端点类,id就是路径(/actuator/myendpoint)

@Component 扫描并交给容器管理

@ReadOperation 代表GET请求处理方法 ,@WriteOperation代表POST请求处理方法

@Endpoint(id = "myendpoint")
@Component
public class MyEndPoint implements ApplicationContextAware {

    private ApplicationContext app;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.app = applicationContext;
    }

    @ReadOperation
    public Map invokeGet() {
        Map ret = new HashMap<>();

        // 自定义监控逻辑
        ret.put("type", "get");
        ret.put("status", "okk");
        ret.put("details", "nothing to do");
        return ret;
    }

    @WriteOperation
    public Map invokePost() {
        Map ret = new HashMap<>();

        // 自定义监控逻辑
        ret.put("type", "post");
        ret.put("status", "okk");
        ret.put("details", "nothing to do");
        return ret;
    }
}

SpringBoot Actuator监控组件笔记_第1张图片SpringBoot Actuator监控组件笔记_第2张图片

加载所有EndPoint并由DispatcherServlet路由的源码位置:org.springframework.boot.actuate.autoconfigure.endpoint.web.servlet.WebMvcEndpointManagementContextConfiguration#webEndpointServletHandlerMapping

	@Bean
	@ConditionalOnMissingBean
	public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier,
			ServletEndpointsSupplier servletEndpointsSupplier, ControllerEndpointsSupplier controllerEndpointsSupplier,
			EndpointMediaTypes endpointMediaTypes, CorsEndpointProperties corsProperties,
			WebEndpointProperties webEndpointProperties, Environment environment) {
		List> allEndpoints = new ArrayList<>();

        // 这里查询bean容器中所有注解了@Endpoint的类
		Collection webEndpoints = webEndpointsSupplier.getEndpoints();
		allEndpoints.addAll(webEndpoints);
		allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());
		allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());
		String basePath = webEndpointProperties.getBasePath();
		EndpointMapping endpointMapping = new EndpointMapping(basePath);
		boolean shouldRegisterLinksMapping = StringUtils.hasText(basePath)
				|| ManagementPortType.get(environment).equals(ManagementPortType.DIFFERENT);

        // WebMvcEndpointHandlerMapping继承了AbstractHandlerMethodMapping
        // 将每个Endpoint和其中的get/post方法封装为handlermethod,由springmvc在请求时路由
		return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes,
				corsProperties.toCorsConfiguration(), new EndpointLinksResolver(allEndpoints, basePath),
				shouldRegisterLinksMapping);
	}

/beans

返回当前应用所有父子容器中的bean信息,如下图

SpringBoot Actuator监控组件笔记_第3张图片

源码实现类为 org.springframework.boot.actuate.beans.BeansEndpoint,比较简单就是从ApplicationContext挨个取出BeanDefinition,把部分信息封装到Map返回

@Endpoint(id = "beans")
public class BeansEndpoint {

	private final ConfigurableApplicationContext context;

	public BeansEndpoint(ConfigurableApplicationContext context) {
		this.context = context;
	}

	@ReadOperation
	public ApplicationBeans beans() {
        // 循环把父子容器的bean信息放到map中返回
		Map contexts = new HashMap<>();
		ConfigurableApplicationContext context = this.context;
		while (context != null) {
			contexts.put(context.getId(), ContextBeans.describing(context));
			context = getConfigurableParent(context);
		}
		return new ApplicationBeans(contexts);
	}

	    private static Map describeBeans(ConfigurableListableBeanFactory beanFactory) {
			Map beans = new HashMap<>();
			for (String beanName : beanFactory.getBeanDefinitionNames()) {
				BeanDefinition definition = beanFactory.getBeanDefinition(beanName);
				if (isBeanEligible(beanName, definition, beanFactory)) {
					beans.put(beanName, describeBean(beanName, definition, beanFactory));
				}
			}
			return beans;
	    }
}

 

/health

各个组件的运行状况

SpringBoot Actuator监控组件笔记_第4张图片

内置了很多组件的检测器如下,

SpringBoot Actuator监控组件笔记_第5张图片

 也可以自定义实现其他组件的健康检测类

@Component
public class RocketMQHealthIndicator extends AbstractHealthIndicator {

    @Override
    protected void doHealthCheck(Health.Builder builder) throws Exception {
        // 自定义逻辑

        // 展示信息
        builder.status(Status.UP);
        builder.withDetail("aaaa", "aaaa");
        builder.withDetail("bbbb", "bbbb");
        builder.withDetail("cccc", "cccc");
    }
}

/loggers 

查看当前应用日志级别情况,可以动态改变

SpringBoot Actuator监控组件笔记_第6张图片

如下应用层代码:

SpringBoot Actuator监控组件笔记_第7张图片

SpringBoot Actuator监控组件笔记_第8张图片

 首先访问/actuator/loggers路径,可以得到如下结果,目前日志级别是INFO

SpringBoot Actuator监控组件笔记_第9张图片

 

执行输出test111方法如图:

访问POST请求如下,可以动态改变日志级别,改为DEBUG级别

SpringBoot Actuator监控组件笔记_第10张图片

 访问后再次执行test111方法如图:无需重启应用,非常方便生产环境使用

 

/info

自定义显示程序信息,有两种方式定制 info 信息

一种就是在application.properties配置文件中配置如下:

SpringBoot Actuator监控组件笔记_第11张图片

访问端点返回如下

SpringBoot Actuator监控组件笔记_第12张图片 

另一种代码形式,实现InfoContributor接口

SpringBoot Actuator监控组件笔记_第13张图片SpringBoot Actuator监控组件笔记_第14张图片

 

/threaddump 

与jstack工具一样,展示当前应用所有线程堆栈

SpringBoot Actuator监控组件笔记_第15张图片

 

你可能感兴趣的:(笔记,Spring,spring,boot,java,spring)