以编程方式将健康指标添加到 Springboot Actuator Group

bur*_*555 5 java spring-boot spring-boot-actuator

问题

我想以编程方式将运行状况指标包含到执行器组中。他们现在执行此操作的唯一方法是在*.properties文件中。

使用案例

根据应用程序中发现的 bean 或其他属性,自动或手动将运行状况指示器添加到就绪/活跃组中会很棒。虽然设置该属性看起来很容易,但在许多情况下,开发人员可能会忘记设置它,或者存在人们不知道可能需要配置哪些健康指标的旧项目。

例子:

如果在应用程序中启用了数据源运行状况指示器,那么最好将该运行状况指示器自动配置到就绪组中。但是,如果数据源运行状况指示器未处于活动状态,我们就不会希望出现这种情况。

谢谢!

小智 0

您需要添加 HealthIndicator bean 来实现自定义运行状况指示器,然后需要注入 CustomHealthIndicator。

第 1 步:在您的应用程序中创建自定义运行状况指示器

import com.google.common.collect.ImmutableMap;
import com.netflix.appinfo.HealthCheckHandler;
import com.netflix.appinfo.InstanceInfo;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.actuate.health.CompositeHealthIndicator;
import org.springframework.boot.actuate.health.HealthAggregator;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.actuate.health.Status;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.Assert;

import java.util.Map;

/**
 * Update #getStatus() to do your detailed application check (testing for databases, external services, queues, etc.)
 * to represent your health check by indicating all its components are also functional (as opposed to a simple
 * application-is-running check).
 */
public class EurekaHealthCheckHandler implements HealthCheckHandler, ApplicationContextAware, InitializingBean {

    public final static ImmutableMap<Status, InstanceInfo.InstanceStatus> healthStatuses =
            new ImmutableMap.Builder<Status, InstanceInfo.InstanceStatus>()
                    .put(Status.UNKNOWN, InstanceInfo.InstanceStatus.UNKNOWN)
                    .put(Status.OUT_OF_SERVICE, InstanceInfo.InstanceStatus.OUT_OF_SERVICE)
                    .put(Status.DOWN, InstanceInfo.InstanceStatus.DOWN)
                    .put(Status.UP, InstanceInfo.InstanceStatus.UP)
                    .build();

    private final CompositeHealthIndicator healthIndicator;

    private ApplicationContext applicationContext;

    public EurekaHealthCheckHandler(HealthAggregator healthAggregator) {
        Assert.notNull(healthAggregator, "HealthAggregator must not be null");
        this.healthIndicator = new CompositeHealthIndicator(healthAggregator);
    }

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

    @Override
    public void afterPropertiesSet() throws Exception {
        final Map<String, HealthIndicator> healthIndicators = applicationContext.getBeansOfType(HealthIndicator.class);
        for (Map.Entry<String, HealthIndicator> entry : healthIndicators.entrySet()) {
            healthIndicator.addHealthIndicator(entry.getKey(), entry.getValue());
        }
    }

    @Override
    public InstanceInfo.InstanceStatus getStatus(InstanceInfo.InstanceStatus instanceStatus) {
        Status status = healthIndicator.health().getStatus();
        return healthStatuses.containsKey(status) ? healthStatuses.get(status) : InstanceInfo.InstanceStatus.UNKNOWN;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后根据您的需求实施健康指标

import lombok.extern.slf4j.Slf4j;
import com.application.services.SmsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;

/**
 * Spring Cloud Health Indicator (for Eureka discovery). Sends a ping to Twilio and if sent successfully reports
 * service as UP otherwise DOWN.
 */
@Component
@Slf4j
public class SmsHealthIndicator implements HealthIndicator {
    @Autowired
    private SmsService smsService;

    /**
     * Performs health check by getting first SMS from Twilio.
     */
    @Override
    public Health health() {
        try {
            smsService.testSampleMessage();
            return Health.up().build();
        } catch (Exception e) {
            log.error("HealthCheck with Twilio failed", e);
            return Health.down(e).build();
        }
    }
}

Run Code Online (Sandbox Code Playgroud)

这应该可以满足你的要求