[case15]springboot2 adds diskspace indicator

  springboot

Order

This article mainly studies how to add a diskspace index to springboot2.

disk health indicator

DiskSpaceHealthIndicatorProperties

spring-boot-actuator-autoconfigure-2.0.1.RELEASE-sources.jar! /org/springframework/boot/actuate/autoconfigure/system/DiskSpaceHealthIndicatorProperties.java

/**
 * External configuration properties for {@link DiskSpaceHealthIndicator}.
 *
 * @author Andy Wilkinson
 * @since 1.2.0
 */
@ConfigurationProperties(prefix = "management.health.diskspace")
public class DiskSpaceHealthIndicatorProperties {

    private static final int MEGABYTES = 1024 * 1024;

    private static final int DEFAULT_THRESHOLD = 10 * MEGABYTES;

    /**
     * Path used to compute the available disk space.
     */
    private File path = new File(".");

    /**
     * Minimum disk space, in bytes, that should be available.
     */
    private long threshold = DEFAULT_THRESHOLD;

    public File getPath() {
        return this.path;
    }

    public void setPath(File path) {
        Assert.isTrue(path.exists(), () -> "Path '" + path + "' does not exist");
        Assert.isTrue(path.canRead(), () -> "Path '" + path + "' cannot be read");
        this.path = path;
    }

    public long getThreshold() {
        return this.threshold;
    }

    public void setThreshold(long threshold) {
        Assert.isTrue(threshold >= 0, "threshold must be greater than 0");
        this.threshold = threshold;
    }

}

DiskSpaceHealthIndicator

spring-boot-actuator-2.0.1.RELEASE-sources.jar! /org/springframework/boot/actuate/system/DiskSpaceHealthIndicator.java

/**
 * A {@link HealthIndicator} that checks available disk space and reports a status of
 * {@link Status#DOWN} when it drops below a configurable threshold.
 *
 * @author Mattias Severson
 * @author Andy Wilkinson
 * @since 2.0.0
 */
public class DiskSpaceHealthIndicator extends AbstractHealthIndicator {

    private static final Log logger = LogFactory.getLog(DiskSpaceHealthIndicator.class);

    private final File path;

    private final long threshold;

    /**
     * Create a new {@code DiskSpaceHealthIndicator} instance.
     * @param path the Path used to compute the available disk space
     * @param threshold the minimum disk space that should be available (in bytes)
     */
    public DiskSpaceHealthIndicator(File path, long threshold) {
        super("DiskSpace health check failed");
        this.path = path;
        this.threshold = threshold;
    }

    @Override
    protected void doHealthCheck(Health.Builder builder) throws Exception {
        long diskFreeInBytes = this.path.getUsableSpace();
        if (diskFreeInBytes >= this.threshold) {
            builder.up();
        }
        else {
            logger.warn(String.format(
                    "Free disk space below threshold. "
                            + "Available: %d bytes (threshold: %d bytes)",
                    diskFreeInBytes, this.threshold));
            builder.down();
        }
        builder.withDetail("total", this.path.getTotalSpace())
                .withDetail("free", diskFreeInBytes)
                .withDetail("threshold", this.threshold);
    }

}

metrics

Here we turn disk’s health indicator into metrics.

@Component
public class DiskMetrics implements MeterBinder {

    private File rootFilePath;

    public DiskMetrics() {
        this.rootFilePath = new File(".");
    }

    @Override
    public void bindTo(MeterRegistry registry) {
        Gauge.builder("diskspace.total", rootFilePath, c -> c.getTotalSpace())
                .register(registry);
        Gauge.builder("diskspace.free", rootFilePath, c -> c.getFreeSpace())
                .register(registry);
        Gauge.builder("diskspace.usage", rootFilePath, c -> {
            long totalDiskSpace = rootFilePath.getTotalSpace();
            if (totalDiskSpace == 0) {
                return 0.0;
            }

            long usedDiskSpace = totalDiskSpace - rootFilePath.getFreeSpace();
            return Double.valueOf(usedDiskSpace) / totalDiskSpace * 100;
        })
                .register(registry);
    }
}

Output

  • /actuator/metrics
{
  "names": [
    "jvm.memory.committed",
    "jvm.buffer.memory.used",
    "jvm.gc.memory.allocated",
    "jvm.memory.used",
    "jvm.gc.max.data.size",
    "logback.events",
    "system.cpu.count",
    "jvm.memory.max",
    "jvm.buffer.total.capacity",
    "jvm.buffer.count",
    "process.files.max",
    "jvm.threads.daemon",
    "process.start.time",
    "diskspace.usage",
    "jvm.gc.live.data.size",
    "process.files.open",
    "process.cpu.usage",
    "process.uptime",
    "system.load.average.1m",
    "statsd.queue.size",
    "statsd.queue.capacity",
    "http.server.requests",
    "system.cpu.usage",
    "diskspace.free",
    "jvm.threads.live",
    "jvm.classes.loaded",
    "jvm.classes.unloaded",
    "jvm.threads.peak",
    "jvm.gc.pause",
    "jvm.gc.memory.promoted",
    "diskspace.total"
  ]
}
  • /actuator/metrics/diskspace.usage
{
  "name": "diskspace.usage",
  "measurements": [
    {
      "statistic": "VALUE",
      "value": 96.99886102691765
    }
  ],
  "availableTags": []
}

Summary

Springboot2 takes diskspace as a healthIndicator by default and its threshold value is 10M by default. Here, by customizing the metrics of micrometer and adding diskspace related indicators, monitoring and alarm can be carried out uniformly through metrcis.

doc