Skip to content

Commit 8070a07

Browse files
committed
Create disk memory health checker
1 parent 72ebfe1 commit 8070a07

3 files changed

Lines changed: 121 additions & 0 deletions

File tree

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright 2024 LY Corporation
3+
*
4+
* LY Corporation licenses this file to you under the Apache License,
5+
* version 2.0 (the "License"); you may not use this file except in compliance
6+
* with the License. You may obtain a copy of the License at:
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations
14+
* under the License.
15+
*/
16+
package com.linecorp.armeria.server.healthcheck;
17+
18+
import static com.google.common.base.Preconditions.checkArgument;
19+
import static java.util.Objects.requireNonNull;
20+
21+
import java.io.File;
22+
23+
/**
24+
* A {@link HealthChecker} that reports as unhealthy
25+
* when the target free disk space exceeds a file disk usable space.
26+
* For example:
27+
* <pre>{@code
28+
* final DiskMemoryHealthChecker diskMemoryHealthChecker = HealthChecker.ofDisk(100, new File("/tmp"));
29+
*
30+
* // Returns false if a file disk usable memory space is less than 100 bytes,
31+
* // or true if a file disk usable memory space is greater than or equal to 100 bytes.
32+
* final boolean healthy = diskMemoryHealthChecker.isHealthy();
33+
* }</pre>
34+
*/
35+
// 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.
36+
final class DiskMemoryHealthChecker implements HealthChecker {
37+
38+
private final double targetFreeDiskSpace;
39+
40+
private final File path;
41+
42+
DiskMemoryHealthChecker(double targetFreeDiskSpace, File path) {
43+
checkArgument(targetFreeDiskSpace >= 0, "freeDiskSpace: %s (expected: >= 0)", targetFreeDiskSpace);
44+
requireNonNull(path);
45+
this.targetFreeDiskSpace = targetFreeDiskSpace;
46+
this.path = path;
47+
}
48+
49+
/**
50+
* Returns true if the file usable space is greater or equal than the target space.
51+
* @return boolean
52+
*/
53+
@Override
54+
public boolean isHealthy() {
55+
return path.getUsableSpace() >= targetFreeDiskSpace;
56+
}
57+
}

core/src/main/java/com/linecorp/armeria/server/healthcheck/HealthChecker.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static com.google.common.base.Preconditions.checkArgument;
2020
import static java.util.Objects.requireNonNull;
2121

22+
import java.io.File;
2223
import java.time.Duration;
2324
import java.util.concurrent.CompletionStage;
2425
import java.util.function.Supplier;
@@ -105,6 +106,19 @@ static HealthChecker ofCpu(double targetSystemCpuUsage, double targetProcessCpuU
105106
return new CpuHealthChecker(targetSystemCpuUsage, targetProcessCpuUsage);
106107
}
107108

109+
/**
110+
* Creates a new instance of {@link HealthChecker}
111+
* which reports health based on disk space of specific file path.
112+
* Both free disk space must be (inclusive) lower than the specified threshold in order
113+
* for the {@link HealthChecker} to report as healthy.
114+
*
115+
* @param targetFreeDiskSpace Target free disk space in bytes.
116+
* @return an instance of {@link HealthChecker} configured with the provided disk memory space targets.
117+
*/
118+
static HealthChecker ofDisk(double targetFreeDiskSpace, File path) {
119+
return new DiskMemoryHealthChecker(targetFreeDiskSpace, path);
120+
}
121+
108122
/**
109123
* Returns {@code true} if and only if the {@link Server} is healthy.
110124
*/
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright 2024 LY Corporation
3+
*
4+
* LY Corporation licenses this file to you under the Apache License,
5+
* version 2.0 (the "License"); you may not use this file except in compliance
6+
* with the License. You may obtain a copy of the License at:
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations
14+
* under the License.
15+
*/
16+
package com.linecorp.armeria.server.healthcheck;
17+
18+
import static org.assertj.core.api.Assertions.assertThat;
19+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
20+
21+
import java.io.File;
22+
23+
import org.junit.jupiter.api.Test;
24+
25+
class DiskMemoryCheckerTest {
26+
27+
@Test
28+
void throwExceptionWhenTargetFreeDiskSpaceLowerThanZero() {
29+
final double targetFreeDiskSpace = -1.0;
30+
assertThatThrownBy(() -> HealthChecker.ofDisk(targetFreeDiskSpace, new File("/tmp")))
31+
.isInstanceOf(IllegalArgumentException.class)
32+
.hasMessageContaining("freeDiskSpace: %.1f (expected: >= 0)", targetFreeDiskSpace);
33+
}
34+
35+
@Test
36+
void throwExceptionWhenPathIsNull() {
37+
final double targetFreeDiskSpace = 1.0;
38+
assertThatThrownBy(() -> HealthChecker.ofDisk(targetFreeDiskSpace, null))
39+
.isInstanceOf(NullPointerException.class);
40+
}
41+
42+
@Test
43+
void shouldReturnTrueWhenDiskSpaceIsHealthy() {
44+
final DiskMemoryHealthChecker diskMemoryHealthChecker =
45+
(DiskMemoryHealthChecker) HealthChecker.ofDisk(
46+
1.0, new File(".")
47+
);
48+
assertThat(diskMemoryHealthChecker.isHealthy()).isTrue();
49+
}
50+
}

0 commit comments

Comments
 (0)