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 Jul 21, 2024
1 parent 72ebfe1 commit 8ce5606
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* 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;

/**
* 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(80, 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 HealthChecker {

private final double targetFreeSpacePercentage;

private final File path;

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

/**
* Returns true if the file usable space is greater or equal than the target space.
* @return boolean
*/
@Override
public boolean isHealthy() {
return targetFreeSpacePercentage * path.getTotalSpace() <= path.getUsableSpace();
}
}
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,19 @@ static HealthChecker ofCpu(double targetSystemCpuUsage, double targetProcessCpuU
return new CpuHealthChecker(targetSystemCpuUsage, targetProcessCpuUsage);
}

/**
* Creates a new instance of {@link HealthChecker} which reports health based on free disk space
* of the file system the specified path belongs to.
* Both free disk space must be (inclusive) lower than the specified threshold in order
* for the {@link HealthChecker} to report as healthy.
*
* @param targetDiskSpacePercentage the target free disk space as a percentage (0 - 1).
* @return an instance of {@link HealthChecker} configured with the provided disk memory space targets.
*/
static HealthChecker ofDisk(double targetDiskSpacePercentage, File path) {
return new DiskMemoryHealthChecker(targetDiskSpacePercentage, path);
}

/**
* 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,51 @@
/*
* 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("freeDiskSpace: %.1f (expected < 0 or 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 =
(DiskMemoryHealthChecker) HealthChecker.ofDisk(
0.01, new File(".")
);
assertThat(diskMemoryHealthChecker.isHealthy()).isTrue();
}
}

0 comments on commit 8ce5606

Please sign in to comment.