Skip to content

Commit 6655182

Browse files
committed
Create disk memory health checker
1 parent 5cb0fa7 commit 6655182

3 files changed

Lines changed: 129 additions & 0 deletions

File tree

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
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 or total disk space exceed a file disk usable or total memory space.
26+
* For example:
27+
* <pre>{@code
28+
* final DiskMemoryHealthChecker diskMemoryHealthChecker = HealthChecker.ofDisk(100, 100, "/tmp");
29+
*
30+
* // Returns false if a file disk usable/total memory space is less than 100 bytes,
31+
* // or true if a file disk usable/total 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 File file;
39+
40+
private final long targetFreeDiskSpace;
41+
42+
private final long targetTotalDiskSpace;
43+
44+
DiskMemoryHealthChecker(long targetFreeDiskSpace, long targetTotalDiskSpace, String path) {
45+
this(targetFreeDiskSpace, targetTotalDiskSpace, new File(requireNonNull(path, "path")));
46+
}
47+
48+
private DiskMemoryHealthChecker(long targetFreeDiskSpace, long targetTotalDiskSpace, File file) {
49+
checkArgument(targetFreeDiskSpace >= 0, "freeDiskSpace: %s (expected: >= 0)", targetFreeDiskSpace);
50+
checkArgument(targetTotalDiskSpace > 0, "totalDiskSpace: %s (expected: > 0)", targetTotalDiskSpace);
51+
this.targetFreeDiskSpace = targetFreeDiskSpace;
52+
this.targetTotalDiskSpace = targetTotalDiskSpace;
53+
this.file = file;
54+
}
55+
56+
/**
57+
* Returns true if the file usable and total disk space are greater or equal than the target space.
58+
* @return boolean
59+
*/
60+
@Override
61+
public boolean isHealthy() {
62+
return file.getUsableSpace() >= targetFreeDiskSpace && file.getTotalSpace() >= targetTotalDiskSpace;
63+
}
64+
}

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
@@ -105,6 +105,20 @@ static HealthChecker ofCpu(double targetSystemCpuUsage, double targetProcessCpuU
105105
return new CpuHealthChecker(targetSystemCpuUsage, targetProcessCpuUsage);
106106
}
107107

108+
/**
109+
* Creates a new instance of {@link HealthChecker}
110+
* which reports health based on disk space of specific file path.
111+
* Both free disk space and total disk space must be (inclusive) lower than the specified threshold in order
112+
* for the {@link HealthChecker} to report as healthy.
113+
*
114+
* @param targetFreeDiskSpace Target free disk space in bytes.
115+
* @param targetTotalDiskSpace Target total disk space in bytes.
116+
* @return an instance of {@link HealthChecker} configured with the provided disk memory space targets.
117+
*/
118+
static HealthChecker ofDisk(long targetFreeDiskSpace, long targetTotalDiskSpace, String path) {
119+
return new DiskMemoryHealthChecker(targetFreeDiskSpace, targetTotalDiskSpace, path);
120+
}
121+
108122
/**
109123
* Returns {@code true} if and only if the {@link Server} is healthy.
110124
*/
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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 org.junit.jupiter.api.Test;
22+
23+
class DiskMemoryCheckerTest {
24+
25+
@Test
26+
void throwExceptionWhenTargetFreeDiskSpaceLowerThanZero() {
27+
assertThatThrownBy(() -> {
28+
final DiskMemoryHealthChecker healthChecker =
29+
(DiskMemoryHealthChecker) HealthChecker.ofDisk(-1, 1, "/tmp");
30+
}).isInstanceOf(IllegalArgumentException.class)
31+
.hasMessageContaining("freeDiskSpace: -1 (expected: >= 0)");
32+
}
33+
34+
@Test
35+
void throwExceptionWhenTargetTotalDiskSpaceLowerOrEqualThanZero() {
36+
assertThatThrownBy(() -> {
37+
final DiskMemoryHealthChecker healthChecker =
38+
(DiskMemoryHealthChecker) HealthChecker.ofDisk(1, 0, "/tmp");
39+
}).isInstanceOf(IllegalArgumentException.class)
40+
.hasMessageContaining("totalDiskSpace: 0 (expected: > 0)");
41+
}
42+
43+
@Test
44+
void shouldReturnTrueWhenDiskSpaceIsHealthy() {
45+
final DiskMemoryHealthChecker diskMemoryHealthChecker =
46+
(DiskMemoryHealthChecker) HealthChecker.ofDisk(
47+
1, 1, System.getProperty("user.dir")
48+
);
49+
assertThat(diskMemoryHealthChecker.isHealthy()).isTrue();
50+
}
51+
}

0 commit comments

Comments
 (0)