blob: 131ff9f5ac8bf0dd247270c26188d52a3130372b [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF 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
*
* http://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 org.apache.iotdb.metrics.metricsets.system;
import org.apache.iotdb.metrics.AbstractMetricService;
import org.apache.iotdb.metrics.MetricConstant;
import org.apache.iotdb.metrics.config.MetricConfig;
import org.apache.iotdb.metrics.config.MetricConfigDescriptor;
import org.apache.iotdb.metrics.metricsets.IMetricSet;
import org.apache.iotdb.metrics.utils.FileStoreUtils;
import org.apache.iotdb.metrics.utils.MetricLevel;
import org.apache.iotdb.metrics.utils.MetricType;
import org.apache.iotdb.metrics.utils.SystemMetric;
import org.apache.iotdb.metrics.utils.SystemTag;
import org.apache.iotdb.metrics.utils.SystemType;
import org.apache.iotdb.tsfile.utils.FSUtils;
import com.sun.management.OperatingSystemMXBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.management.ManagementFactory;
import java.nio.file.FileStore;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class SystemMetrics implements IMetricSet {
private static final Logger logger = LoggerFactory.getLogger(SystemMetrics.class);
private static final MetricConfig CONFIG = MetricConfigDescriptor.getInstance().getMetricConfig();
private final Runtime runtime = Runtime.getRuntime();
private final String[] getSystemMemoryCommand = new String[] {"/bin/sh", "-c", "free"};
private final String[] linuxMemoryTitles =
new String[] {"Total", "Used", "Free", "Shared", "Buff/Cache", "Available"};
private long lastUpdateTime = 0L;
private volatile long usedMemory = 0L;
private volatile long sharedMemory = 0L;
private volatile long buffCacheMemory = 0L;
private volatile long availableMemory = 0L;
static final String SYSTEM = "system";
private final com.sun.management.OperatingSystemMXBean osMxBean;
private Set<FileStore> fileStores = new HashSet<>();
private static final String FAILED_TO_STATISTIC = "Failed to statistic the size of {}, because";
public SystemMetrics() {
this.osMxBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
}
public void setDiskDirs(List<String> diskDirs) {
if (!MetricConfigDescriptor.getInstance()
.getMetricConfig()
.getMetricLevel()
.equals(MetricLevel.OFF)) {
this.fileStores = getFileStores(diskDirs);
}
}
public static Set<FileStore> getFileStores(List<String> dirs) {
Set<FileStore> fileStoreSet = new HashSet<>();
for (String diskDir : dirs) {
if (!FSUtils.isLocal(diskDir)) {
continue;
}
FileStore fileStore = FileStoreUtils.getFileStore(diskDir);
if (fileStore != null) {
fileStoreSet.add(fileStore);
}
}
return fileStoreSet;
}
@Override
public void bindTo(AbstractMetricService metricService) {
collectSystemCpuInfo(metricService);
collectSystemMemInfo(metricService);
collectSystemDiskInfo(metricService);
}
@Override
public void unbindFrom(AbstractMetricService metricService) {
removeSystemCpuInfo(metricService);
removeSystemDiskInfo(metricService);
removeSystemMemInfo(metricService);
}
private void collectSystemCpuInfo(AbstractMetricService metricService) {
metricService.createAutoGauge(
SystemMetric.SYS_CPU_LOAD.toString(),
MetricLevel.CORE,
osMxBean,
a -> osMxBean.getSystemCpuLoad() * 100,
SystemTag.NAME.toString(),
SYSTEM);
metricService
.getOrCreateGauge(
SystemMetric.SYS_CPU_CORES.toString(),
MetricLevel.CORE,
SystemTag.NAME.toString(),
SYSTEM)
.set(osMxBean.getAvailableProcessors());
}
private void removeSystemCpuInfo(AbstractMetricService metricService) {
metricService.remove(
MetricType.AUTO_GAUGE,
SystemMetric.SYS_CPU_LOAD.toString(),
SystemTag.NAME.toString(),
SYSTEM);
metricService.remove(
MetricType.GAUGE, SystemMetric.SYS_CPU_CORES.toString(), SystemTag.NAME.toString(), SYSTEM);
}
private void collectSystemMemInfo(AbstractMetricService metricService) {
metricService
.getOrCreateGauge(
SystemMetric.SYS_TOTAL_PHYSICAL_MEMORY_SIZE.toString(),
MetricLevel.CORE,
SystemTag.NAME.toString(),
SYSTEM)
.set(osMxBean.getTotalPhysicalMemorySize());
metricService.createAutoGauge(
SystemMetric.SYS_FREE_PHYSICAL_MEMORY_SIZE.toString(),
MetricLevel.CORE,
osMxBean,
a -> osMxBean.getFreePhysicalMemorySize(),
SystemTag.NAME.toString(),
SYSTEM);
metricService.createAutoGauge(
SystemMetric.SYS_TOTAL_SWAP_SPACE_SIZE.toString(),
MetricLevel.CORE,
osMxBean,
a -> osMxBean.getTotalSwapSpaceSize(),
SystemTag.NAME.toString(),
SYSTEM);
metricService.createAutoGauge(
SystemMetric.SYS_FREE_SWAP_SPACE_SIZE.toString(),
MetricLevel.CORE,
osMxBean,
a -> osMxBean.getFreeSwapSpaceSize(),
SystemTag.NAME.toString(),
SYSTEM);
metricService.createAutoGauge(
SystemMetric.SYS_COMMITTED_VM_SIZE.toString(),
MetricLevel.CORE,
osMxBean,
a -> osMxBean.getCommittedVirtualMemorySize(),
SystemTag.NAME.toString(),
SYSTEM);
if (CONFIG.getSystemType() == SystemType.LINUX) {
metricService.createAutoGauge(
SystemMetric.LINUX_MEMORY_SIZE.toString(),
MetricLevel.CORE,
this,
a -> {
updateLinuxSystemMemInfo();
return usedMemory;
},
SystemTag.NAME.toString(),
linuxMemoryTitles[1]);
metricService.createAutoGauge(
SystemMetric.LINUX_MEMORY_SIZE.toString(),
MetricLevel.CORE,
this,
a -> {
updateLinuxSystemMemInfo();
return sharedMemory;
},
SystemTag.NAME.toString(),
linuxMemoryTitles[3]);
metricService.createAutoGauge(
SystemMetric.LINUX_MEMORY_SIZE.toString(),
MetricLevel.CORE,
this,
a -> {
updateLinuxSystemMemInfo();
return buffCacheMemory;
},
SystemTag.NAME.toString(),
linuxMemoryTitles[4]);
metricService.createAutoGauge(
SystemMetric.LINUX_MEMORY_SIZE.toString(),
MetricLevel.CORE,
this,
a -> {
updateLinuxSystemMemInfo();
return availableMemory;
},
SystemTag.NAME.toString(),
linuxMemoryTitles[5]);
}
}
private void updateLinuxSystemMemInfo() {
long time = System.currentTimeMillis();
if (time - lastUpdateTime > MetricConstant.UPDATE_INTERVAL) {
lastUpdateTime = time;
try {
Process process = runtime.exec(getSystemMemoryCommand);
StringBuilder result = new StringBuilder();
try (BufferedReader input =
new BufferedReader(new InputStreamReader(process.getInputStream()))) {
String line;
while ((line = input.readLine()) != null) {
result.append(line).append("\n");
}
}
String[] lines = result.toString().split("\n");
// if failed to get result
if (lines.length >= 2) {
String[] memParts = lines[1].trim().split("\\s+");
if (memParts.length == linuxMemoryTitles.length) {
usedMemory = Long.parseLong(memParts[2]) * 1024;
sharedMemory = Long.parseLong(memParts[4]) * 1024;
buffCacheMemory = Long.parseLong(memParts[5]) * 1024;
availableMemory = Long.parseLong(memParts[6]) * 1024;
}
}
} catch (IOException e) {
logger.debug("Failed to get memory, because ", e);
}
}
}
private void removeSystemMemInfo(AbstractMetricService metricService) {
metricService.remove(
MetricType.GAUGE,
SystemMetric.SYS_TOTAL_PHYSICAL_MEMORY_SIZE.toString(),
SystemTag.NAME.toString(),
SYSTEM);
metricService.remove(
MetricType.AUTO_GAUGE,
SystemMetric.SYS_FREE_PHYSICAL_MEMORY_SIZE.toString(),
SystemTag.NAME.toString(),
SYSTEM);
metricService.remove(
MetricType.AUTO_GAUGE,
SystemMetric.SYS_TOTAL_SWAP_SPACE_SIZE.toString(),
SystemTag.NAME.toString(),
SYSTEM);
metricService.remove(
MetricType.AUTO_GAUGE,
SystemMetric.SYS_FREE_SWAP_SPACE_SIZE.toString(),
SystemTag.NAME.toString(),
SYSTEM);
metricService.remove(
MetricType.AUTO_GAUGE,
SystemMetric.SYS_COMMITTED_VM_SIZE.toString(),
SystemTag.NAME.toString(),
SYSTEM);
if (CONFIG.getSystemType() == SystemType.LINUX) {
for (String title : linuxMemoryTitles) {
metricService.remove(
MetricType.GAUGE,
SystemMetric.LINUX_MEMORY_SIZE.toString(),
SystemTag.NAME.toString(),
title);
}
}
}
private void collectSystemDiskInfo(AbstractMetricService metricService) {
metricService.createAutoGauge(
SystemMetric.SYS_DISK_TOTAL_SPACE.toString(),
MetricLevel.CORE,
this,
SystemMetrics::getSystemDiskTotalSpace,
SystemTag.NAME.toString(),
SYSTEM);
metricService.createAutoGauge(
SystemMetric.SYS_DISK_FREE_SPACE.toString(),
MetricLevel.CORE,
this,
SystemMetrics::getSystemDiskFreeSpace,
SystemTag.NAME.toString(),
SYSTEM);
metricService.createAutoGauge(
SystemMetric.SYS_DISK_AVAILABLE_SPACE.toString(),
MetricLevel.CORE,
this,
SystemMetrics::getSystemDiskAvailableSpace,
SystemTag.NAME.toString(),
SYSTEM);
}
private void removeSystemDiskInfo(AbstractMetricService metricService) {
metricService.remove(
MetricType.AUTO_GAUGE,
SystemMetric.SYS_DISK_TOTAL_SPACE.toString(),
SystemTag.NAME.toString(),
SYSTEM);
metricService.remove(
MetricType.AUTO_GAUGE,
SystemMetric.SYS_DISK_FREE_SPACE.toString(),
SystemTag.NAME.toString(),
SYSTEM);
metricService.remove(
MetricType.AUTO_GAUGE,
SystemMetric.SYS_DISK_AVAILABLE_SPACE.toString(),
SystemTag.NAME.toString(),
SYSTEM);
fileStores.clear();
}
public long getSystemDiskTotalSpace() {
long sysTotalSpace = 0L;
for (FileStore fileStore : fileStores) {
try {
sysTotalSpace += fileStore.getTotalSpace();
} catch (IOException e) {
logger.error(FAILED_TO_STATISTIC, fileStore, e);
}
}
return sysTotalSpace;
}
public long getSystemDiskFreeSpace() {
long sysFreeSpace = 0L;
for (FileStore fileStore : fileStores) {
try {
sysFreeSpace += fileStore.getUnallocatedSpace();
} catch (IOException e) {
logger.error(FAILED_TO_STATISTIC, fileStore, e);
}
}
return sysFreeSpace;
}
public long getSystemDiskAvailableSpace() {
long sysAvailableSpace = 0L;
for (FileStore fileStore : fileStores) {
try {
sysAvailableSpace += fileStore.getUsableSpace();
} catch (IOException e) {
logger.error(FAILED_TO_STATISTIC, fileStore, e);
}
}
return sysAvailableSpace;
}
public static SystemMetrics getInstance() {
return SystemMetricsHolder.INSTANCE;
}
private static class SystemMetricsHolder {
private static final SystemMetrics INSTANCE = new SystemMetrics();
private SystemMetricsHolder() {}
}
}