【问题标题】:Direct access to Spring Boot Actuator Health beans/data?直接访问 Spring Boot Actuator Health bean/数据?
【发布时间】:2020-03-18 14:27:01
【问题描述】:

是否可以从 Sprig Boot 应用程序直接访问执行器/健康数据而无需进行休息调用并解析结果?

理想情况下,我可以自动装配一个 bean,然后通过方法调用获取健康数据的对象表示。

例如,如果我的健康端点显示如下:

{
    "status": "UP",
    "components": {
        "db": {
            "status": "UP",
            "details": {
                "database": "PostgreSQL",
                "result": 1,
                "validationQuery": "SELECT 1"
            }
        },
        "diskSpace": {
            "status": "UP",
            "details": {
                "total": 499963174912,
                "free": 389081399296,
                "threshold": 10485760
            }
        },
        "ping": {
            "status": "UP"
        },
        "redis": {
            "status": "UP",
            "details": {
                "version": "3.2.12"
            }
        }
    }
}

那么我可以自动连接哪些组件来找出这些信息中的每一个?

【问题讨论】:

    标签: spring-boot actuator


    【解决方案1】:

    可能有更好的方法来获取健康数据,但这对我有用。

    @RestController
    public class HealthController {
        @Autowired
        HealthContributor[] healthContributors;
        
        
        @GetMapping("/health")
        public Map<String, String> health() {
            Map<String, String> components = new HashMap<String, String>();
            for(HealthContributor healthContributor : healthContributors) {
                String componentName = healthContributor.getClass().getSimpleName().replace("HealthIndicator", "").replace("HealthCheckIndicator", "");
                String status = ((HealthIndicator)(healthContributor)).health().getStatus().toString();
                //To get details
                //Map<String,Object> details = ((HealthIndicator)(healthContributor)).health().getDetails();
                
                components.put(componentName, status);
                
            }
            return components;
        }
        
    }
    

    示例输出:

    {
      "Mail":"UP",
      "Ping":"UP",
      "Camel":"UP",
      "DiskSpace":"UP"
    }
    

    要模拟 HealthContributor[],您可以尝试使用 Mockito,如下所示:

    @Profile("test")
    @Configuration
    public class HealthContributorsMockConfig {
    
    
        @Primary
        @Bean(name = "healthContributors")
        public HealthContributor[] healthContributors() {
            HealthContributor[] healthContributors = new HealthContributor[2];
            
            HealthContributor healthContributorA = Mockito.mock(HealthIndicator.class, new Answer<Object>() {
    
                @Override
                public Object answer(InvocationOnMock invocation) throws Throwable {
                    // TODO Auto-generated method stub
                    Health health = Health.up().build();
                    return health;
                }
                
            });
            
            HealthContributor healthContributorB = Mockito.mock(HealthIndicator.class, new Answer<Object>() {
    
                @Override
                public Object answer(InvocationOnMock invocation) throws Throwable {
                    // TODO Auto-generated method stub
                    Health health = Health.down().build();
                    return health;
                }
                
            });
            
            healthContributors[0] = healthContributorA;
            healthContributors[1] = healthContributorB;
            return healthContributors;
            
        }
    }
    

    【讨论】:

    • 你好@rr_nm,我真的很喜欢你的解决方案,但我有一个关于测试的问题,如何模拟 HealthContributor[]?
    • @BSL 查看我编辑的帖子,了解如何模拟 HealthContributor[]。
    • 非常感谢@rr_nm,这是个好主意!
    【解决方案2】:

    当然你可以注入相应的Endpoint。例如,如果您对HealthEndpoint 感兴趣,您可以这样做:

    @RestController
    public class ActuatorController {
    
        private final HealthEndpoint healthEndpoint;
    
        public ActuatorController(HealthEndpoint healthEndpoint) {
            this.healthEndpoint = healthEndpoint;
        }
    
        @GetMapping("health")
        public String health() {
            return healthEndpoint.health().getStatus().getCode();
        }
    }
    

    【讨论】:

    • 谢谢,这似乎是朝着正确方向迈出的一步。我可以从中获得整体上/下状态。我没有看到如何访问各个组件的详细信息。
    【解决方案3】:

    此外,默认情况下,执行器中启用了信息和健康点,您无需手动公开它们。将依赖项添加到 pom.xml 的那一刻,它将被启用,您可以访问 url 端点而不暴露它们

    【讨论】:

    • 谢谢,但我并没有试图公开它们,我试图从我的应用程序中访问信息而不调用和解析端点。
    • 你想用 Java 代码发出请求并解析响应
    • @JVM我会写个课给你
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-01
    • 1970-01-01
    • 2020-09-15
    • 2016-09-01
    • 2022-07-08
    • 2017-10-25
    • 2019-08-05
    相关资源
    最近更新 更多