All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.didiglobal.knowframework.system.metrcis.service.linux.LinuxDiskIOMetricsServiceImpl Maven / Gradle / Ivy

package com.didiglobal.knowframework.system.metrcis.service.linux;

import com.didiglobal.knowframework.system.metrcis.annotation.PeriodMethod;
import com.didiglobal.knowframework.system.metrcis.bean.PeriodStatistics;
import com.didiglobal.knowframework.system.metrcis.service.DiskIOMetricsService;
import com.didiglobal.knowframework.system.metrcis.util.MathUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class LinuxDiskIOMetricsServiceImpl extends LinuxMetricsService implements DiskIOMetricsService {

    private static final Logger LOGGER = LoggerFactory.getLogger(LinuxDiskIOMetricsServiceImpl.class);

    private Map iOUtil = new HashMap<>();
    private Map avgQuSz = new HashMap<>();
    private Map avgRqSz = new HashMap<>();
    private Map iOAwait = new HashMap();
    private Map iORAwait = new HashMap();
    private Map iOReadRequest = new HashMap();
    private Map iOReadBytes = new HashMap();
    private Map iORRQMS = new HashMap();
    private Map iOSVCTM = new HashMap();
    private Map iOWAwait = new HashMap();
    private Map iOWriteRequest = new HashMap();
    private Map iOWriteBytes = new HashMap();
    private Map iOReadWriteBytes = new HashMap();
    private Map iOWRQMS = new HashMap();
    private Map diskReadTime = new HashMap();
    private Map readTimePercent = new HashMap();
    private Map writeTime = new HashMap<>();
    private Map writeTimePercent = new HashMap<>();

    private static LinuxDiskIOMetricsServiceImpl instance;

    private LinuxDiskIOMetricsServiceImpl() {}

    public static synchronized LinuxDiskIOMetricsServiceImpl getInstance() {
        if(null == instance) {
            instance = new LinuxDiskIOMetricsServiceImpl();
        }
        return instance;
    }

    @Override
    public Map getIOUtil() {
        return getIOUtilOnly();
    }

    @PeriodMethod(periodMs = 5 * 1000)
    private void calcIOUtil() {
        Map device2IOUtilMap = getIOUtilOnly();
        for (Map.Entry entry : device2IOUtilMap.entrySet()) {
            String device = entry.getKey();
            Double value = entry.getValue();
            if(this.iOUtil.containsKey(device)) {
                this.iOUtil.get(device).add(value);
            } else {
                PeriodStatistics iOUtilPeriodStatistics = new PeriodStatistics();
                iOUtilPeriodStatistics.add(value);
                this.iOUtil.put(device, iOUtilPeriodStatistics);
            }
        }
    }

    private Map getIOUtilOnly() {
        Map result = new HashMap<>();
        List lines = getOutputByCmd("iostat -dkx | head -n -1 | awk 'NR>3{print $1,$14}'", "各设备I/O请求的CPU时间百分比", null);
        for (String line : lines) {
            String[] array = line.split("\\s+");
            if (array.length < 2) {
                LOGGER.error("class=LinuxDiskIOMetricsServiceImpl()||method=getIOUtil()||msg=data is not enough");
                return result;
            }
            String key = array[0];
            double value = Double.parseDouble(array[1]);
            result.put(key, value);
        }
        return result;
    }

    @Override
    public Map getAvgQuSz() {
        return getAvgQuSzOnly();
    }

    @PeriodMethod(periodMs = 5 * 1000)
    private void calcAvgQuSzOnly() {
        Map device2AvgQuSzMap = getAvgQuSzOnly();
        for (Map.Entry entry : device2AvgQuSzMap.entrySet()) {
            String device = entry.getKey();
            Double value = entry.getValue();
            if(this.avgQuSz.containsKey(device)) {
                this.avgQuSz.get(device).add(value);
            } else {
                PeriodStatistics periodStatistics = new PeriodStatistics();
                periodStatistics.add(value);
                this.avgQuSz.put(device, periodStatistics);
            }
        }
    }

    private Map getAvgQuSzOnly() {
        Map result = new HashMap<>();
        String procFDShell = String.format("iostat -dkx | head -n -1 | awk 'NR>3{print $1,$%d}'", 9);
        List lines = getOutputByCmd(procFDShell, "各设备平均队列长度", null);
        for (String line : lines) {
            String[] array = line.split("\\s+");
            if (array.length < 2) {
                LOGGER.error("class=LinuxSystemMetricsService()||method={}||msg=data is not enough", "getAvgQuSz()");
                return result;
            }
            String key = array[0];
            double value = Double.parseDouble(array[1]);
            result.put(key, value);
        }
        return result;
    }

    @Override
    public Map getAvgRqSz() {
        if(avgRqSz.isEmpty()) {
            calcAvgRqSz();
        }
        for (PeriodStatistics value : avgRqSz.values()) {
            value.snapshot();
        }
        return avgRqSz;
    }

    @PeriodMethod(periodMs = 5 * 1000)
    private void calcAvgRqSz() {
        Map device2AvgRqSzMap = getAvgRqSzOnly();
        for (Map.Entry entry : device2AvgRqSzMap.entrySet()) {
            String device = entry.getKey();
            Double value = entry.getValue();
            if(this.avgRqSz.containsKey(device)) {
                this.avgRqSz.get(device).add(value);
            } else {
                PeriodStatistics periodStatistics = new PeriodStatistics();
                periodStatistics.add(value);
                this.avgRqSz.put(device, periodStatistics);
            }
        }
    }

    private Map getAvgRqSzOnly() {
        Map result = new HashMap<>();
        String procFDShell = String.format("iostat -dkx | head -n -1 | awk 'NR>3{print $1,$%d}'", 8);
        List lines = getOutputByCmd(procFDShell, "各设备平均请求大小", null);
        for (String line : lines) {
            String[] array = line.split("\\s+");
            if (array.length < 2) {
                LOGGER.error("class=LinuxSystemMetricsService()||method={}||msg=data is not enough", "getAvgRqSzOnly()");
                return result;
            }
            String key = array[0];
            double value = Double.parseDouble(array[1]);
            result.put(key, value);
        }
        return result;
    }

    @Override
    public Map getIOAwait() {
        if(iOAwait.isEmpty()) {
            calcIOAwait();
        }
        for (PeriodStatistics value : iOAwait.values()) {
            value.snapshot();
        }
        return iOAwait;
    }

    @PeriodMethod(periodMs = 5 * 1000)
    private void calcIOAwait() {
        Map device2IOAwaitMap = getIOAwaitOnly();
        for (Map.Entry entry : device2IOAwaitMap.entrySet()) {
            String device = entry.getKey();
            Double value = entry.getValue();
            if(this.iOAwait.containsKey(device)) {
                this.iOAwait.get(device).add(value);
            } else {
                PeriodStatistics periodStatistics = new PeriodStatistics();
                periodStatistics.add(value);
                this.iOAwait.put(device, periodStatistics);
            }
        }
    }

    private Map getIOAwaitOnly() {
        Map result = new HashMap<>();
        String procFDShell = String.format("iostat -dkx | head -n -1 | awk 'NR>3{print $1,$%d}'", 10);
        List lines = getOutputByCmd(procFDShell, "各设备每次IO平均处理时间", null);
        for (String line : lines) {
            String[] array = line.split("\\s+");
            if (array.length < 2) {
                LOGGER.error("class=LinuxSystemMetricsService()||method={}||msg=data is not enough", "getIOAwaitOnly()");
                return result;
            }
            String key = array[0];
            double value = Double.parseDouble(array[1]);
            result.put(key, value);
        }
        return result;
    }

    @Override
    public Map getIORAwait() {
        if(iORAwait.isEmpty()) {
            calcIORAwait();
        }
        for (PeriodStatistics value : iORAwait.values()) {
            value.snapshot();
        }
        return iORAwait;
    }

    private Map getIORAwaitOnly() {
        Map result = new HashMap<>();
        String procFDShell = String.format("iostat -dkx | head -n -1 | awk 'NR>3{print $1,$%d}'", 11);
        List lines = getOutputByCmd(procFDShell, "各设备读请求平均耗时", null);
        for (String line : lines) {
            String[] array = line.split("\\s+");
            if (array.length < 2) {
                LOGGER.error("class=LinuxSystemMetricsService()||method={}||msg=data is not enough", "getIORAwaitOnly()");
                return result;
            }
            String key = array[0];
            double value = Double.parseDouble(array[1]);
            result.put(key, value);
        }
        return result;
    }

    @PeriodMethod(periodMs = 5 * 1000)
    private void calcIORAwait() {
        Map device2IORAwaitMap = getIORAwaitOnly();
        for (Map.Entry entry : device2IORAwaitMap.entrySet()) {
            String device = entry.getKey();
            Double value = entry.getValue();
            if(this.iORAwait.containsKey(device)) {
                this.iORAwait.get(device).add(value);
            } else {
                PeriodStatistics periodStatistics = new PeriodStatistics();
                periodStatistics.add(value);
                this.iORAwait.put(device, periodStatistics);
            }
        }
    }

    @Override
    public Map getIOReadRequest() {
        if(iOReadRequest.isEmpty()) {
            calcIOReadRequest();
        }
        for (PeriodStatistics value : iOReadRequest.values()) {
            value.snapshot();
        }
        return iOReadRequest;
    }

    @PeriodMethod(periodMs = 5 * 1000)
    private void calcIOReadRequest() {
        Map device2IOReadRequestMap = getIOReadRequestOnly();
        for (Map.Entry entry : device2IOReadRequestMap.entrySet()) {
            String device = entry.getKey();
            Double value = entry.getValue();
            if(this.iOReadRequest.containsKey(device)) {
                this.iOReadRequest.get(device).add(value);
            } else {
                PeriodStatistics periodStatistics = new PeriodStatistics();
                periodStatistics.add(value);
                this.iOReadRequest.put(device, periodStatistics);
            }
        }
    }

    private Map getIOReadRequestOnly() {
        Map result = new HashMap<>();
        String procFDShell = String.format("iostat -dkx | head -n -1 | awk 'NR>3{print $1,$%d}'", 4);
        List lines = getOutputByCmd(procFDShell, "各设备每秒读请求数量", null);
        for (String line : lines) {
            String[] array = line.split("\\s+");
            if (array.length < 2) {
                LOGGER.error("class=LinuxSystemMetricsService()||method={}||msg=data is not enough", "getIOReadRequest()");
                return result;
            }
            String key = array[0];
            double value = Double.parseDouble(array[1]);
            result.put(key, value);
        }
        return result;
    }

    @Override
    public Map getIOReadBytes() {
        if(iOReadBytes.isEmpty()) {
            calcIOReadBytes();
        }
        for (PeriodStatistics value : iOReadBytes.values()) {
            value.snapshot();
        }
        return iOReadBytes;
    }

    @PeriodMethod(periodMs = 5 * 1000)
    private void calcIOReadBytes() {
        Map device2IOReadBytesMap = getIOReadBytesOnly();
        for (Map.Entry entry : device2IOReadBytesMap.entrySet()) {
            String device = entry.getKey();
            Double value = entry.getValue();
            if(this.iOReadBytes.containsKey(device)) {
                this.iOReadBytes.get(device).add(value);
            } else {
                PeriodStatistics periodStatistics = new PeriodStatistics();
                periodStatistics.add(value);
                this.iOReadBytes.put(device, periodStatistics);
            }
        }
    }

    private Map getIOReadBytesOnly() {
        Map result = new HashMap<>();
        List lines = getOutputByCmd("iostat -dkx | head -n -1 | awk 'NR>3{print $1,$6}'", "各设备每秒读取字节数", null);
        for (String line : lines) {
            String[] array = line.split("\\s+");
            if (array.length < 2) {
                LOGGER.error("class=LinuxSystemMetricsService()||method=getIOReadBytesOnly()||msg=data is not enough");
                return result;
            }
            String key = array[0];
            double value = 1024 * Double.parseDouble(array[1]);
            result.put(key, value);
        }
        return result;
    }

    @Override
    public Map getIORRQMS() {
        if(iORRQMS.isEmpty()) {
            calcIORRQMS();
        }
        for (PeriodStatistics value : iORRQMS.values()) {
            value.snapshot();
        }
        return iORRQMS;
    }

    @PeriodMethod(periodMs = 5 * 1000)
    private void calcIORRQMS() {
        Map device2IORRQMSMap = getIORRQMSOnly();
        for (Map.Entry entry : device2IORRQMSMap.entrySet()) {
            String device = entry.getKey();
            Double value = entry.getValue();
            if(this.iORRQMS.containsKey(device)) {
                this.iORRQMS.get(device).add(value);
            } else {
                PeriodStatistics periodStatistics = new PeriodStatistics();
                periodStatistics.add(value);
                this.iORRQMS.put(device, periodStatistics);
            }
        }
    }

    private Map getIORRQMSOnly() {
        Map result = new HashMap<>();
        String procFDShell = String.format("iostat -dkx | head -n -1 | awk 'NR>3{print $1,$%d}'", 2);
        List lines = getOutputByCmd(procFDShell, "各设备每秒合并到设备队列的读请求数", null);
        for (String line : lines) {
            String[] array = line.split("\\s+");
            if (array.length < 2) {
                LOGGER.error("class=LinuxSystemMetricsService()||method={}||msg=data is not enough", "getIORRQMSOnly()");
                return result;
            }
            String key = array[0];
            double value = Double.parseDouble(array[1]);
            result.put(key, value);
        }
        return result;
    }

    @Override
    public Map getIOSVCTM() {
        if(iOSVCTM.isEmpty()) {
            calcIOSVCTM();
        }
        for (PeriodStatistics value : iOSVCTM.values()) {
            value.snapshot();
        }
        return iOSVCTM;
    }

    @PeriodMethod(periodMs = 5 * 1000)
    private void calcIOSVCTM() {
        Map device2IOSVCTMMap = getIOSVCTMOnly();
        for (Map.Entry entry : device2IOSVCTMMap.entrySet()) {
            String device = entry.getKey();
            Double value = entry.getValue();
            if(this.iOSVCTM.containsKey(device)) {
                this.iOSVCTM.get(device).add(value);
            } else {
                PeriodStatistics periodStatistics = new PeriodStatistics();
                periodStatistics.add(value);
                this.iOSVCTM.put(device, periodStatistics);
            }
        }
    }

    private Map getIOSVCTMOnly() {
        Map result = new HashMap<>();
        String procFDShell = String.format("iostat -dkx | head -n -1 | awk 'NR>3{print $1,$%d}'", 13);
        List lines = getOutputByCmd(procFDShell, "每次各设备IO平均服务时间", null);
        for (String line : lines) {
            String[] array = line.split("\\s+");
            if (array.length < 2) {
                LOGGER.error("class=LinuxSystemMetricsService()||method={}||msg=data is not enough", "getIOSVCTM()");
                return result;
            }
            String key = array[0];
            double value = Double.parseDouble(array[1]);
            result.put(key, value);
        }
        return result;
    }

    @Override
    public Map getIOWAwait() {
        if(iOWAwait.isEmpty()) {
            calcIOWAwait();
        }
        for (PeriodStatistics value : iOWAwait.values()) {
            value.snapshot();
        }
        return iOWAwait;
    }

    @PeriodMethod(periodMs = 5 * 1000)
    private void calcIOWAwait() {
        Map device2IOWAwaitMap = getIOWAwaitOnly();
        for (Map.Entry entry : device2IOWAwaitMap.entrySet()) {
            String device = entry.getKey();
            Double value = entry.getValue();
            if(this.iOWAwait.containsKey(device)) {
                this.iOWAwait.get(device).add(value);
            } else {
                PeriodStatistics periodStatistics = new PeriodStatistics();
                periodStatistics.add(value);
                this.iOWAwait.put(device, periodStatistics);
            }
        }
    }

    private Map getIOWAwaitOnly() {
        Map result = new HashMap<>();
        String procFDShell = String.format("iostat -dkx | head -n -1 | awk 'NR>3{print $1,$%d}'", 12);
        List lines = getOutputByCmd(procFDShell, "各设备写请求平均耗时", null);
        for (String line : lines) {
            String[] array = line.split("\\s+");
            if (array.length < 2) {
                LOGGER.error("class=LinuxSystemMetricsService()||method={}||msg=data is not enough", "getIOWAwaitOnly()");
                return result;
            }
            String key = array[0];
            double value = Double.parseDouble(array[1]);
            result.put(key, value);
        }
        return result;
    }

    @Override
    public Map getIOWriteRequest() {
        if(iOWriteRequest.isEmpty()) {
            calcIOWriteRequest();
        }
        for (PeriodStatistics value : iOWriteRequest.values()) {
            value.snapshot();
        }
        return iOWriteRequest;
    }

    @PeriodMethod(periodMs = 5 * 1000)
    private void calcIOWriteRequest() {
        Map device2IOWriteRequestMap = getIOWriteRequestOnly();
        for (Map.Entry entry : device2IOWriteRequestMap.entrySet()) {
            String device = entry.getKey();
            Double value = entry.getValue();
            if(this.iOWriteRequest.containsKey(device)) {
                this.iOWriteRequest.get(device).add(value);
            } else {
                PeriodStatistics periodStatistics = new PeriodStatistics();
                periodStatistics.add(value);
                this.iOWriteRequest.put(device, periodStatistics);
            }
        }
    }

    private Map getIOWriteRequestOnly() {
        Map result = new HashMap<>();
        String procFDShell = String.format("iostat -dkx | head -n -1 | awk 'NR>3{print $1,$%d}'", 5);
        List lines = getOutputByCmd(procFDShell, "各设备每秒写请求数量", null);
        for (String line : lines) {
            String[] array = line.split("\\s+");
            if (array.length < 2) {
                LOGGER.error("class=LinuxSystemMetricsService()||method={}||msg=data is not enough", "getIOWriteRequestOnly()");
                return result;
            }
            String key = array[0];
            double value = Double.parseDouble(array[1]);
            result.put(key, value);
        }
        return result;
    }

    @Override
    public Map getIOWriteBytes() {
        if(iOWriteBytes.isEmpty()) {
            calcIOWriteBytes();
        }
        for (PeriodStatistics value : iOWriteBytes.values()) {
            value.snapshot();
        }
        return iOWriteBytes;
    }

    @PeriodMethod(periodMs = 5 * 1000)
    private void calcIOWriteBytes() {
        Map device2IOWriteBytesMap = getIOWriteBytesOnly();
        for (Map.Entry entry : device2IOWriteBytesMap.entrySet()) {
            String device = entry.getKey();
            Double value = entry.getValue();
            if(this.iOWriteBytes.containsKey(device)) {
                this.iOWriteBytes.get(device).add(value);
            } else {
                PeriodStatistics periodStatistics = new PeriodStatistics();
                periodStatistics.add(value);
                this.iOWriteBytes.put(device, periodStatistics);
            }
        }
    }

    private Map getIOWriteBytesOnly() {
        Map result = new HashMap<>();
        List lines = getOutputByCmd("iostat -dkx | head -n -1 | awk 'NR>3{print $1,$7}'", "各设备每秒写字节数", null);
        for (String line : lines) {
            String[] array = line.split("\\s+");
            if (array.length < 2) {
                LOGGER.error("class=LinuxSystemMetricsService()||method=getSystemIOWriteBytes()||msg=data is not enough");
                return result;
            }
            String key = array[0];
            double value = 1024 * Double.parseDouble(array[1]);
            result.put(key, value);
        }
        return result;
    }

    @Override
    public Map getIOReadWriteBytes() {
        if(iOReadWriteBytes.isEmpty()) {
            calcIOReadWriteBytes();
        }
        for (PeriodStatistics value : iOReadWriteBytes.values()) {
            value.snapshot();
        }
        return iOReadWriteBytes;
    }

    @PeriodMethod(periodMs = 5 * 1000)
    private void calcIOReadWriteBytes() {
        Map device2IOReadWriteBytesMap = getIOReadWriteBytesOnly();
        for (Map.Entry entry : device2IOReadWriteBytesMap.entrySet()) {
            String device = entry.getKey();
            Double value = entry.getValue();
            if(this.iOReadWriteBytes.containsKey(device)) {
                this.iOReadWriteBytes.get(device).add(value);
            } else {
                PeriodStatistics periodStatistics = new PeriodStatistics();
                periodStatistics.add(value);
                this.iOReadWriteBytes.put(device, periodStatistics);
            }
        }
    }

    private Map getIOReadWriteBytesOnly() {
        Map device2IOReadBytesMap = getIOReadBytesOnly();
        Map device2IOWriteBytesMap = getIOWriteBytesOnly();
        Map device2IOReadWriteBytesMap = new HashMap<>();
        for (Map.Entry entry : device2IOReadBytesMap.entrySet()) {
            String device = entry.getKey();
            Double iOReadBytes = entry.getValue();
            Double iOWriteBytes = getMetricValueByKey(device2IOWriteBytesMap, device, "IOWriteBytes", 0d);
            Double iOReadWriteBytes = iOWriteBytes + iOReadBytes;
            device2IOReadWriteBytesMap.put(device, iOReadWriteBytes);
        }
        return device2IOReadWriteBytesMap;
    }

    @Override
    public Map getIOWRQMS() {
        if(iOWRQMS.isEmpty()) {
            calcIOWRQMS();
        }
        for (PeriodStatistics value : iOWRQMS.values()) {
            value.snapshot();
        }
        return iOWRQMS;
    }

    @PeriodMethod(periodMs = 5 * 1000)
    private void calcIOWRQMS() {
        Map device2IOWRQMSMap = getIOWRQMSOnly();
        for (Map.Entry entry : device2IOWRQMSMap.entrySet()) {
            String device = entry.getKey();
            Double value = entry.getValue();
            if(this.iOWRQMS.containsKey(device)) {
                this.iOWRQMS.get(device).add(value);
            } else {
                PeriodStatistics periodStatistics = new PeriodStatistics();
                periodStatistics.add(value);
                this.iOWRQMS.put(device, periodStatistics);
            }
        }
    }

    private Map getIOWRQMSOnly() {
        Map result = new HashMap<>();
        String procFDShell = String.format("iostat -dkx | head -n -1 | awk 'NR>3{print $1,$%d}'", 3);
        List lines = getOutputByCmd(procFDShell, "各设备每秒合并到设备队列的写请求数", null);
        for (String line : lines) {
            String[] array = line.split("\\s+");
            if (array.length < 2) {
                LOGGER.error("class=LinuxSystemMetricsService()||method={}||msg=data is not enough", "getIOWRQMSOnly()");
                return result;
            }
            String key = array[0];
            double value = Double.parseDouble(array[1]);
            result.put(key, value);
        }
        return result;
    }

    @Override
    public Map getDiskReadTime() {
        if(diskReadTime.isEmpty()) {
            calcDiskReadTime();
        }
        for (PeriodStatistics value : diskReadTime.values()) {
            value.snapshot();
        }
        return diskReadTime;
    }

    @PeriodMethod(periodMs = 5 * 1000)
    private void calcDiskReadTime() {
        Map device2DiskReadTimeMap = getDiskReadTimeOnly();
        for (Map.Entry entry : device2DiskReadTimeMap.entrySet()) {
            String device = entry.getKey();
            Double value = entry.getValue();
            if(this.diskReadTime.containsKey(device)) {
                this.diskReadTime.get(device).add(value);
            } else {
                PeriodStatistics periodStatistics = new PeriodStatistics();
                periodStatistics.add(value);
                this.diskReadTime.put(device, periodStatistics);
            }
        }
    }

    private Map getDiskReadTimeOnly() {
        Map result = new HashMap<>();
        List lines = getOutputByCmd("vmstat -d | awk 'NR>2{print $1,$5}'", "各设备读操作耗时", null);
        for (String line : lines) {
            String[] array = line.split("\\s+");
            if (array.length < 2) {
                LOGGER.error("class=LinuxSystemMetricsService()||method=getSystemDiskReadTime()||msg=data is not enough");
                return result;
            }
            String key = array[0];
            Double value = Double.parseDouble(array[1]);
            result.put(key, value);
        }
        return result;
    }

    @Override
    public Map getDiskReadTimePercent() {
        if(readTimePercent.isEmpty()) {
            calcDiskReadTimePercent();
        }
        for (PeriodStatistics value : readTimePercent.values()) {
            value.snapshot();
        }
        return readTimePercent;
    }

    @PeriodMethod(periodMs = 5 * 1000)
    private void calcDiskReadTimePercent() {
        Map device2ReadTimePercentMap = getDiskReadTimePercentOnly();
        for (Map.Entry entry : device2ReadTimePercentMap.entrySet()) {
            String device = entry.getKey();
            Double value = entry.getValue();
            if(this.readTimePercent.containsKey(device)) {
                this.readTimePercent.get(device).add(value);
            } else {
                PeriodStatistics periodStatistics = new PeriodStatistics();
                periodStatistics.add(value);
                this.readTimePercent.put(device, periodStatistics);
            }
        }
    }

    private Map getDiskReadTimePercentOnly() {
        Map result = new HashMap<>();
        List lines = getOutputByCmd("vmstat -d | awk 'NR>2{print $1,$5,$9}'", "读取磁盘时间百分比", null);
        for (String line : lines) {
            String[] array = line.split("\\s+");
            if (array.length < 3) {
                LOGGER.error("class=LinuxSystemMetricsService()||method=getDiskReadTimePercentOnly()||msg=data is not enough");
                return result;
            }
            String device = array[0];
            Double readTime = Double.parseDouble(array[1]);
            Double writeTime = Double.parseDouble(array[2]);
            Double readWriteTime = readTime + writeTime;
            Double readTimePercent = MathUtil.divideWith2Digit(readTime * 100, readWriteTime);
            result.put(device, readTimePercent);
        }
        return result;
    }

    @Override
    public Map getDiskWriteTime() {
        if(writeTime.isEmpty()) {
            calcDiskWriteTime();
        }
        for (PeriodStatistics value : writeTime.values()) {
            value.snapshot();
        }
        return writeTime;
    }

    @PeriodMethod(periodMs = 5 * 1000)
    private void calcDiskWriteTime() {
        Map device2WriteTimeMap = getDiskWriteTimeOnly();
        for (Map.Entry entry : device2WriteTimeMap.entrySet()) {
            String device = entry.getKey();
            Double value = entry.getValue();
            if(this.writeTime.containsKey(device)) {
                this.writeTime.get(device).add(value);
            } else {
                PeriodStatistics periodStatistics = new PeriodStatistics();
                periodStatistics.add(value);
                this.writeTime.put(device, periodStatistics);
            }
        }
    }

    private Map getDiskWriteTimeOnly() {
        Map result = new HashMap<>();
        List lines = getOutputByCmd("vmstat -d | awk 'NR>2{print $1,$9}'", "各设备写操作耗时", null);
        for (String line : lines) {
            String[] array = line.split("\\s+");
            if (array.length < 2) {
                LOGGER.error("class=LinuxSystemMetricsService()||method=getDiskWriteTimeOnly()||msg=data is not enough");
                return result;
            }
            String key = array[0];
            Double value = Double.parseDouble(array[1]);
            result.put(key, value);
        }
        return result;
    }

    @Override
    public Map getDiskWriteTimePercent() {
        if(writeTimePercent.isEmpty()) {
            calcDiskWriteTimePercent();
        }
        for (PeriodStatistics value : writeTimePercent.values()) {
            value.snapshot();
        }
        return writeTimePercent;
    }

    @PeriodMethod(periodMs = 5 * 1000)
    private void calcDiskWriteTimePercent() {
        Map device2WriteTimePercentMap = getDiskWriteTimePercentOnly();
        for (Map.Entry entry : device2WriteTimePercentMap.entrySet()) {
            String device = entry.getKey();
            Double value = entry.getValue();
            if(this.writeTimePercent.containsKey(device)) {
                this.writeTimePercent.get(device).add(value);
            } else {
                PeriodStatistics periodStatistics = new PeriodStatistics();
                periodStatistics.add(value);
                this.writeTimePercent.put(device, periodStatistics);
            }
        }
    }

    private Map getDiskWriteTimePercentOnly() {
        Map result = new HashMap<>();
        List lines = getOutputByCmd("vmstat -d | awk 'NR>2{print $1,$5,$9}'", "读取磁盘时间百分比", null);
        for (String line : lines) {
            String[] array = line.split("\\s+");
            if (array.length < 3) {
                LOGGER.error("class=LinuxSystemMetricsService()||method=getDiskReadTimePercentOnly()||msg=data is not enough");
                return result;
            }
            String device = array[0];
            Double readTime = Double.parseDouble(array[1]);
            Double writeTime = Double.parseDouble(array[2]);
            Double readWriteTime = readTime + writeTime;
            Double writeTimePercent = MathUtil.divideWith2Digit(writeTime * 100, readWriteTime);
            result.put(device, writeTimePercent);
        }
        return result;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy