Java+Vue 网口进出口流量的获取,Echarts展示

35 篇文章 0 订阅
18 篇文章 0 订阅

当前的需求是获取当前wan网口的进口和出口流量,页面每隔5秒钟去轮询一次,实现如下图所示的效果:
在这里插入图片描述

1.获取进出口流量的脚本
脚本中的enp2s0 是WAN口的名称

#! /bin/bash

for val in $(ifconfig -a | grep "BROADCAST" | awk '{print $1}'|awk -F ":" '{print $1}')
do
        if [ "$val" == "enp2s0" ]; then
                addr="no"
                link_stat=$(ethtool $val | grep 'Link detected' | awk '{print $3}')
                rx=$(ifconfig $val  | grep "RX packets" |awk '{print $5}')
                tx=$(ifconfig $val  | grep "TX packets" |awk '{print $5}')

                echo $val"-"$addr"-"$rx"-"$tx"-"$link_stat"#"
        fi
done

2.Java根据脚本获取数据

  • 业务实现层代码
/**
* 默认sh文件名 getEthIF.sh
* sh %s/getEthIF.sh
*/
private static final String SH_COMMAND = "sh %s/getEthIF.sh";

/**
* 存放上一次查询的各网卡网络流量统计值
*/
private Map<String, Map<String, Long>> networkFlowMap = new HashMap<>(16);
@Override
public List<NetMonitorVO> getNetworkSituation() {
    String shScriptPath = "/usr/local/nss";
    String nowTimeString = DateUtils.getTimeString();
    String command = String.format(SH_COMMAND, shScriptPath);
    List<NetMonitorVO> networkSituationVOList = new ArrayList<>();
    try {
        String callCmdResult = JavaLinuxCmdUtil.onlyCallCmd(command);
        if (StringUtils.isEmpty(callCmdResult)) {
            throw new BusinessException("Abnormal execution of sh script");
        }
        String[] netWorkInterfacesDatas = callCmdResult.split("\n");
        //遍历每个网口的流量信息
        //网卡接口名称
        String ethName = "";
        //入流量
        Long inRateOfFlow = 0L;
        //出流量
        Long outRateOfFlow = 0L;
        // 上次查询的入口流量
        Long lastInRateOfFlow = 0L;
        // 上次查询的出口流量
        Long lastOutRateOfFlow = 0L;
        // 上次查询的入口流量的差值
        Long diffInFlow = 0L;
        // 上次查询的出口流量的差值
        Long diffOutFlow = 0L;

        NetMonitorVO.InEthFlow inEthFlow = null;
        NetMonitorVO.OutEthFlow outEthFlow = null;
        NetMonitorVO networkSituationVO = null;
        for (String eth : netWorkInterfacesDatas) {
            if (StringUtils.isBlank(eth)) {
                continue;
            }
            String[] ethInfos = eth.trim().split("-");
            //满足数组长度,才能正确获取结果
            if (ethInfos.length == 5) {
                //ens192-192.168.103.191/-504058335-155566011-yes#
                // 网卡接口名称-IP/-入流量总和-出流量总和
                ethName = ethInfos[0];
                networkSituationVO = new NetMonitorVO();
                networkSituationVO.setEthName(ethName);
                // 进口流量
                inRateOfFlow = StringUtils.isNumeric(ethInfos[2]) ? Long.parseLong(ethInfos[2]) : 0L;
                // 出口流量
                outRateOfFlow = StringUtils.isNumeric(ethInfos[3]) ? Long.parseLong(ethInfos[3]) : 0L;

                inEthFlow = new NetMonitorVO.InEthFlow();
                outEthFlow = new NetMonitorVO.OutEthFlow();

                inEthFlow.setDateTime(nowTimeString);
                outEthFlow.setDateTime(nowTimeString);

                //未记录上一次流量时,将当前值存入map,并向前端返回0为流量统计结果
                if (!networkFlowMap.containsKey(ethName)) {
                    Map<String, Long> flowMap = new HashMap<>();
                    flowMap.put("inRateOfFlow", inRateOfFlow);
                    flowMap.put("outRateOfFlow", outRateOfFlow);
                    networkFlowMap.put(ethName, flowMap);
                    inEthFlow.setCount(0L);
                    outEthFlow.setCount(0L);
                } else {
                    lastInRateOfFlow = networkFlowMap.get(ethName).get("inRateOfFlow");
                    lastOutRateOfFlow = networkFlowMap.get(ethName).get("outRateOfFlow");

                    diffInFlow = inRateOfFlow - lastInRateOfFlow;
                    diffOutFlow = outRateOfFlow - lastOutRateOfFlow;

                    //如果此次采集值比上一次值低,可能由于此网口重新启动过,需要重新统计流量,并将向前台返回0为些网口的流量统计值
                    if (diffInFlow < 0) {
                        inEthFlow.setCount(0L);
                    } else {
                        inEthFlow.setCount(diffInFlow / 1024);
                    }
                    if (diffOutFlow < 0) {
                        outEthFlow.setCount(0L);
                    } else {
                        outEthFlow.setCount(diffOutFlow / 1024);
                    }
                }
                networkSituationVO.setInEthFlow(inEthFlow);
                networkSituationVO.setOutEthFlow(outEthFlow);
                Map<String, Long> flowMap = new HashMap<>();
                flowMap.put("inRateOfFlow", inRateOfFlow);
                flowMap.put("outRateOfFlow", outRateOfFlow);
                networkFlowMap.put(ethName, flowMap);
                networkSituationVOList.add(networkSituationVO);
            }
        }
    } catch (Exception e) {
        throw new BusinessException("Abnormal execution of sh script");
    }
    return networkSituationVOList;
}

  • NetMonitorVO代码

import lombok.Data;

import java.io.Serializable;

@Data
public class NetMonitorVO implements Serializable {

    private static final long serialVersionUID = 1L;

    private String ethName;

    private InEthFlow inEthFlow;

    private OutEthFlow outEthFlow;


    /**
     * 封装入口流量数据
     */
    @Data
    public static class InEthFlow {
        private String dateTime;
        private Long count;
    }

    /**
     * 封装出口流量数据
     */
    @Data
    public static class OutEthFlow {
        private String dateTime;
        private Long count;
    }
}
  • DateUtils工具类
/**
 * HH:mm:ss
 */
private static final DateTimeFormatter FORMATTER_TIME = DateTimeFormatter.ofPattern("HH:mm:ss");
/**
 * 获取时分秒毫秒字符串
 *  * @return HH:mm:ss
 */
public static String getTimeString() {
    String timeString = FORMATTER_TIME.format(LocalDateTime.now());
    return timeString;
}
  • JavaLinuxCmdUtil工具类
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;


public class JavaLinuxCmdUtil {
    
    public static String onlyCallCmd(String cmd) {
        try {
            String[] command = {"/bin/sh", "-c", cmd};
            Process process = Runtime.getRuntime().exec(command);
            String sb = getCallResult(process);
            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private static String getCallResult(Process process) throws Exception {
        int exitCode = process.waitFor();
        // 取得命令结果的输出流
        InputStream is = process.getInputStream();
        // 用一个读输出流类去读
        InputStreamReader isr = new InputStreamReader(is);
        // 用缓冲器读行
        BufferedReader br = new BufferedReader(isr);
        String line = null;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line + "\n");
        }
        is.close();
        isr.close();
        br.close();
        return sb.toString();
    }
}

3.前端将折线图封装成组件

组件:WanFlowChart.vue

<template>
  <div id="flowMonitoring" :class="className" :style="{height:height,width:width}" />
</template>

<script>
import * as echarts from 'echarts'
import resize from './mixins/resize'

export default {
  mixins: [resize],
  props: {
    className: {
      type: String,
      default: 'chart'
    },
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '350px'
    },
    autoResize: {
      type: Boolean,
      default: true
    },
    chartData: {
      type: Object,
      required: true
    }
  },
  data() {
    return {
      chart: null
    }
  },
  watch: {
    chartData: {
      deep: true,
      handler(val) {
        this.setOptions(val)
      }
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.initChart()
    })
  },
  beforeDestroy() {
    if (!this.chart) {
      return
    }
    this.chart.dispose()
    this.chart = null
  },
  methods: {
    initChart() {
      this.chart = echarts.init(document.getElementById('flowMonitoring'))
      console.log(this.chartData)
      this.setOptions(this.chartData)
    },
    setOptions({ xAxis, inSeries, outSeries } = {}) {
      const interval = Math.round(xAxis.length / 7) - 1
      this.chart.setOption({
        color: ['#4c8ff1', '#1cd798'],
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          }
        },
        grid: {
          left: '3%',
          right: '6%',
          bottom: '6%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          boundaryGap: false,
          data: xAxis,
          axisTick: {
            alignWithLabel: true
          },
          axisLabel: {
            interval: interval,
            color: '#858fa6'
          },
          splitLine: {
            lineStyle: {
              width: 1,
              color: '#E2E2E2'
            }
          },
          axisLine: {
            show: false,
            lineStyle: {
              width: 1,
              color: '#E2E2E2'
            }
          }
        },
        yAxis: {
          type: 'value',
          axisLabel: {
            color: '#858fa6',
            formatter: '{value} kb/s'
          },
          splitLine: {
            lineStyle: {
              width: 1,
              color: '#E2E2E2'
            }
          },
          axisTick: {
            show: false
          },
          axisLine: {
            lineStyle: {
              width: 0,
              color: '#E2E2E2',
              show: false
            }
          }
        },
        series: [
          {
            name: 'Internal flow',
            type: 'line',
            data: inSeries,
            smooth: true,
            areaStyle: {
              color: {
                type: 'linear',
                x: 0,
                y: 0,
                x2: 0,
                y2: 1,
                colorStops: [{
                  offset: 0, color: '#74AAF8'
                }, {
                  offset: 1, color: '#fff'
                }],
                global: false
              }
            }
          },
          {
            name: 'External flow',
            type: 'line',
            data: outSeries,
            smooth: true,
            areaStyle: {
              color: {
                type: 'linear',
                x: 0,
                y: 0,
                x2: 0,
                y2: 1,
                colorStops: [{
                  offset: 0, color: '#31CF9A'
                }, {
                  offset: 1, color: '#fff'
                }],
                global: false
              }
            }
          }
        ]
      })
    }
  }
}
</script>

父页面引用子组件:

<template>
  <div class="app-container">
  	<wan-flow-chart :chart-data="flowMonitorData"></wan-flow-chart>
  </div>
</template>
import { listNetworkSituation } from '@/api/state/state'
import WanFlowChart from './components/WanFlowChart'

export default {
	components: { WanFlowChart },
	data() {
		flowMonitorData: {
	        xAxis: [],
	        inSeries: [],
	        outSeries: []
	      }
	 },
	mounted() {
	    this.getNetList()
	    // 每隔5秒轮询一次
	    const timer = setInterval(() => {
	      this.getNetList()
	    }, 5000)
	
	    this.$once('hook:beforeDestroy', () => {
	      clearInterval(timer)
	    })
  },
  methods: {
    getNetList() {
      this.loading = true
      listNetworkSituation().then(response => {
        if (response.code === 200) {
          this.loading = false
          const list = response.data
          if (list && list.length > 0) {
            list.forEach((item, index) => {
              this.flowMonitorData.xAxis.push(item.inEthFlow.dateTime)
              this.flowMonitorData.inSeries.push(item.inEthFlow.count)
              this.flowMonitorData.outSeries.push(item.outEthFlow.count)
            })
          }
        }
      })
    }
  }
}
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值