Skip to content

Commit

Permalink
Create disk memory health checker
Browse files Browse the repository at this point in the history
  • Loading branch information
AnneMayor committed Sep 21, 2024
1 parent 104855a commit 04f40a6
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright 2024 LY Corporation
*
* LY Corporation licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package com.linecorp.armeria.server.healthcheck;

import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;

import java.io.File;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.function.Supplier;

/**
* A {@link HealthChecker} that reports as unhealthy
* when the target free disk space exceeds a file disk usable space.
* For example:
* <pre>{@code
* final DiskMemoryHealthChecker diskMemoryHealthChecker = HealthChecker.ofDisk(0.8, new File("/tmp"));
*
* // Returns false if a file disk usable memory space is less than 80%,
* // or true if a file disk usable memory space is greater than or equal to 80%.
* final boolean healthy = diskMemoryHealthChecker.isHealthy();
* }</pre>
*/
// Forked from <a href="https://github.com/micrometer-metrics/micrometer/blob/8339d57bef8689beb8d7a18b429a166f6595f2af/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/system/DiskSpaceMetrics.java">DiskSpaceMetrics.java</a> in the micrometer core.
final class DiskMemoryHealthChecker implements Supplier<CompletionStage<HealthCheckStatus>> {

private final double freeDiskSpacePercentage;

private final File path;

DiskMemoryHealthChecker(double freeDiskSpacePercentage, File path) {
checkArgument(freeDiskSpacePercentage >= 0 && freeDiskSpacePercentage <= 1,
"freeDiskSpacePercentage: %s (expected >= 0 and expected <= 1)", freeDiskSpacePercentage);
requireNonNull(path);
this.freeDiskSpacePercentage = freeDiskSpacePercentage;
this.path = path;
}

/**
* Returns true if the file usable space is greater or equal than the target space.
* @return boolean
*/
public boolean isHealthy() {
return freeDiskSpacePercentage * path.getTotalSpace() <= path.getUsableSpace();
}

/**
* Returns a {@link HealthCheckStatus} that represents the health of the file disk usable space asynchronously.
* @return CompletionStage<HealthCheckStatus>
*/

@Override
public CompletionStage<HealthCheckStatus> get() {
return CompletableFuture.supplyAsync(() -> new HealthCheckStatus(isHealthy(), 500));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;

import java.io.File;
import java.time.Duration;
import java.util.concurrent.CompletionStage;
import java.util.function.Supplier;
Expand Down Expand Up @@ -105,6 +106,21 @@ static HealthChecker ofCpu(double targetSystemCpuUsage, double targetProcessCpuU
return new CpuHealthChecker(targetSystemCpuUsage, targetProcessCpuUsage);
}

/**
* Creates a new instance of {@link ListenableHealthChecker} which reports health based on free disk space
* of the file system the specified path belongs to.
* There must be more free space (inclusive) than the specified threshold in order
* for the {@link ListenableHealthChecker} to report as healthy.
*
* @param freeDiskSpacePercentage the target free disk space as a percentage (0 - 1).
* @param path the path to the file system to check.
* @return an instance of {@link ListenableHealthChecker} configured with the provided disk memory space targets.
*/
static ListenableHealthChecker ofDisk(double freeDiskSpacePercentage, File path) {
return new ScheduledHealthChecker(new DiskMemoryHealthChecker(freeDiskSpacePercentage, path),
Duration.ofSeconds(5), CommonPools.workerGroup().next());
}

/**
* Returns {@code true} if and only if the {@link Server} is healthy.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright 2024 LY Corporation
*
* LY Corporation licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package com.linecorp.armeria.server.healthcheck;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

import java.io.File;

import org.junit.jupiter.api.Test;

class DiskMemoryCheckerTest {

@Test
void throwExceptionWhenTargetFreeDiskSpaceLowerThanZero() {
final double targetFreeDiskSpace = -1.0;
assertThatThrownBy(() -> HealthChecker.ofDisk(targetFreeDiskSpace, new File("/tmp")))
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("freeDiskSpacePercentage: %.1f (expected >= 0 and expected <= 1)",
targetFreeDiskSpace);
}

@Test
void throwExceptionWhenPathIsNull() {
final double targetFreeDiskSpace = 1.0;
assertThatThrownBy(() -> HealthChecker.ofDisk(targetFreeDiskSpace, null))
.isInstanceOf(NullPointerException.class);
}

@Test
void shouldReturnTrueWhenDiskSpaceIsHealthy() {
final DiskMemoryHealthChecker diskMemoryHealthChecker = new DiskMemoryHealthChecker
(0.8, new File(""));
assertThat(diskMemoryHealthChecker.isHealthy()).isTrue();
}
}

0 comments on commit 04f40a6

Please sign in to comment.