diff options
author | valerijf <valerijf@yahoo-inc.com> | 2017-06-20 13:30:45 +0200 |
---|---|---|
committer | valerijf <valerijf@yahoo-inc.com> | 2017-06-20 13:30:45 +0200 |
commit | e1204bb76fab8e181d49a1d69d8247d319be253d (patch) | |
tree | 50a86f48a951a546292abe262160055c3aeed3ac /node-admin | |
parent | 1addc80f2a1ccd9ee727906b0cf3a5666435cb8b (diff) |
Add a method to read total memory of host
Diffstat (limited to 'node-admin')
2 files changed, 42 insertions, 0 deletions
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainer.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainer.java index fd5029162bc..baab7c92b0d 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainer.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainer.java @@ -6,6 +6,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.yahoo.collections.Pair; import com.yahoo.io.IOUtils; +import com.yahoo.log.LogLevel; import com.yahoo.net.HostName; import com.yahoo.system.ProcessExecuter; import com.yahoo.vespa.hosted.dockerapi.ContainerName; @@ -35,6 +36,8 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; +import java.util.regex.Matcher; import java.util.regex.Pattern; import static com.yahoo.vespa.defaults.Defaults.getDefaults; @@ -43,17 +46,20 @@ import static com.yahoo.vespa.defaults.Defaults.getDefaults; * @author freva */ public class StorageMaintainer { + private static final Pattern TOTAL_MEMORY_PATTERN = Pattern.compile("^MemTotal:\\s*(?<totalMem>\\d+) kB$", Pattern.MULTILINE); private static final ContainerName NODE_ADMIN = new ContainerName("node-admin"); private static final ObjectMapper objectMapper = new ObjectMapper(); private static Optional<String> kernelVersion = Optional.empty(); private static final long intervalSec = 1000; + private final Logger logger = Logger.getLogger(StorageMaintainer.class.getName()); private final Object monitor = new Object(); private final CounterWrapper numberOfNodeAdminMaintenanceFails; private final Docker docker; private final Environment environment; private final Clock clock; + private double hostTotalMemoryGb = 0; private Map<ContainerName, MaintenanceThrottler> maintenanceThrottlerByContainerName = new ConcurrentHashMap<>(); @@ -167,6 +173,29 @@ public class StorageMaintainer { return diskUsageKB * 1024; } + Optional<String> readMeminfo() { + try { + return Optional.of(new String(Files.readAllBytes(Paths.get("/proc/meminfo")))); + } catch (IOException e) { + logger.log(LogLevel.WARNING, "Failed to read meminfo", e); + return Optional.empty(); + } + } + + public double getHostTotalMemoryGb() { + if (hostTotalMemoryGb == 0) { + readMeminfo().ifPresent(memInfo -> { + Matcher matcher = TOTAL_MEMORY_PATTERN.matcher(memInfo); + if (matcher.find()) { + hostTotalMemoryGb = Integer.valueOf(matcher.group("totalMem")) / 1024d / 1024; + } else { + logger.log(LogLevel.WARNING, "Failed to parse total memory from meminfo: " + memInfo); + } + }); + } + + return hostTotalMemoryGb; + } /** * Deletes old log files for vespa, nginx, logstash, etc. diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainerTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainerTest.java index 4092c967bb7..74f09d36e9d 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainerTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainerTest.java @@ -19,6 +19,7 @@ import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.time.Duration; +import java.util.Optional; import static org.junit.Assert.*; import static org.mockito.Matchers.any; @@ -119,6 +120,18 @@ public class StorageMaintainerTest { verify(docker, times(2)).executeInContainerAsRoot(any(), anyVararg()); } + @Test + public void testGetTotalMemory() { + StorageMaintainer storageMaintainer = mock(StorageMaintainer.class); + when(storageMaintainer.getHostTotalMemoryGb()).thenCallRealMethod(); + + when(storageMaintainer.readMeminfo()).thenReturn(Optional.empty()); + assertEquals(0d, storageMaintainer.getHostTotalMemoryGb(), 0); + + when(storageMaintainer.readMeminfo()).thenReturn(Optional.of("MemTotal: 1572864 kB\nMemUsed: 1000000 kB\n")); + assertEquals(1.5d, storageMaintainer.getHostTotalMemoryGb(), 0); + } + private static void writeNBytesToFile(File file, int nBytes) throws IOException { Files.write(file.toPath(), new byte[nBytes]); } |