From fbc8f9598deb53fb952f3fac60986efd081d02c9 Mon Sep 17 00:00:00 2001 From: LollipopKit <2036293523@qq.com> Date: Mon, 1 Nov 2021 21:29:12 +0800 Subject: [PATCH] Support to get net speed --- lib/data/model/server/net_speed.dart | 71 ++++++++++++++++++++++++ lib/data/model/server/server_status.dart | 16 +++--- lib/data/provider/server.dart | 38 ++++++++++++- lib/view/page/server/detail.dart | 8 ++- 4 files changed, 123 insertions(+), 10 deletions(-) create mode 100644 lib/data/model/server/net_speed.dart diff --git a/lib/data/model/server/net_speed.dart b/lib/data/model/server/net_speed.dart new file mode 100644 index 00000000..b688f4fc --- /dev/null +++ b/lib/data/model/server/net_speed.dart @@ -0,0 +1,71 @@ +import 'dart:math'; + +class NetSpeedPart { + String device; + int bytesIn; + int bytesOut; + int time; + NetSpeedPart(this.device, this.bytesIn, this.bytesOut, this.time); +} + +class NetSpeed { + List old; + List now; + NetSpeed(this.old, this.now); + + List get devices { + final devices = []; + for (var item in now) { + devices.add(item.device); + } + return devices; + } + + NetSpeed update(List newOne) => NetSpeed(now, newOne); + + int get timeDiff => now[0].time - old[0].time; + + String speedIn({String? device}) { + if (old[0].device == '' || now[0].device == '') return '0kb/s'; + int idx = 0; + if (device != null) { + for (var item in now) { + if (item.device == device) { + idx = now.indexOf(item); + break; + } + } + } + final speedInBytesPerSecond = + (now[idx].bytesIn - old[idx].bytesIn) / timeDiff; + int squareTimes = 0; + for (; speedInBytesPerSecond / pow(1024, squareTimes) > 1024;) { + if (squareTimes >= suffixs.length - 1) break; + squareTimes++; + } + return '${(speedInBytesPerSecond / pow(1024, squareTimes)).toStringAsFixed(1)} ${suffixs[squareTimes]}'; + } + + String speedOut({String? device}) { + if (old[0].device == '' || now[0].device == '') return '0kb/s'; + int idx = 0; + if (device != null) { + for (var item in now) { + if (item.device == device) { + idx = now.indexOf(item); + break; + } + } + } + final speedInBytesPerSecond = + (now[idx].bytesOut - old[idx].bytesOut) / timeDiff; + int squareTimes = 0; + for (; speedInBytesPerSecond / pow(1024, squareTimes) > 1024;) { + if (squareTimes >= suffixs.length - 1) break; + squareTimes++; + } + return '${(speedInBytesPerSecond / pow(1024, squareTimes)).toStringAsFixed(1)} ${suffixs[squareTimes]}'; + } +} + +const suffixs = ['b/s', 'kb/s', 'mb/s', 'gb/s']; diff --git a/lib/data/model/server/server_status.dart b/lib/data/model/server/server_status.dart index 43c42562..b3c3427e 100644 --- a/lib/data/model/server/server_status.dart +++ b/lib/data/model/server/server_status.dart @@ -1,5 +1,6 @@ import 'package:toolbox/data/model/server/cpu_2_status.dart'; import 'package:toolbox/data/model/server/disk_info.dart'; +import 'package:toolbox/data/model/server/net_speed.dart'; import 'package:toolbox/data/model/server/tcp_status.dart'; /// @@ -28,13 +29,14 @@ class ServerStatus { } */ - late Cpu2Status cpu2Status; - late List memList; - late String sysVer; - late String uptime; - late List disk; - late TcpStatus tcp; + Cpu2Status cpu2Status; + List memList; + String sysVer; + String uptime; + List disk; + TcpStatus tcp; + NetSpeed netSpeed; ServerStatus(this.cpu2Status, this.memList, this.sysVer, this.uptime, - this.disk, this.tcp); + this.disk, this.tcp, this.netSpeed); } diff --git a/lib/data/provider/server.dart b/lib/data/provider/server.dart index 7b3971b4..7666d418 100644 --- a/lib/data/provider/server.dart +++ b/lib/data/provider/server.dart @@ -6,6 +6,7 @@ import 'package:toolbox/core/extension/stringx.dart'; import 'package:toolbox/core/provider_base.dart'; import 'package:toolbox/data/model/server/cpu_2_status.dart'; import 'package:toolbox/data/model/server/cpu_status.dart'; +import 'package:toolbox/data/model/server/net_speed.dart'; import 'package:toolbox/data/model/server/server_connection_state.dart'; import 'package:toolbox/data/model/server/disk_info.dart'; import 'package:toolbox/data/model/server/server.dart'; @@ -22,6 +23,11 @@ class ServerProvider extends BusyProvider { final logger = Logger('ServerProvider'); + NetSpeedPart get emptyNetSpeedPart => NetSpeedPart('', 0, 0, 0); + + NetSpeed get emptyNetSpeed => + NetSpeed([emptyNetSpeedPart], [emptyNetSpeedPart]); + CpuStatus get emptyCpuStatus => CpuStatus('cpu', 0, 0, 0, 0, 0, 0, 0); Cpu2Status get emptyCpu2Status => @@ -33,7 +39,8 @@ class ServerProvider extends BusyProvider { 'Loading...', '', [DiskInfo('/', '/', 0, '0', '0', '0')], - TcpStatus(0, 0, 0, 0)); + TcpStatus(0, 0, 0, 0), + emptyNetSpeed); Future loadLocalData() async { setBusyState(true); @@ -144,6 +151,8 @@ class ServerProvider extends BusyProvider { final upTime = await client.execute('uptime') ?? ''; final disk = await client.execute('df -h') ?? ''; final tcp = await client.execute('cat /proc/net/snmp') ?? ''; + final netSpeed = + await client.execute('cat /proc/net/dev && date +%s') ?? ''; return ServerStatus( _getCPU(cpu, _servers[idx].status.cpu2Status, cpuTemp), @@ -151,7 +160,8 @@ class ServerProvider extends BusyProvider { _getSysVer(sysVer), _getUpTime(upTime), _getDisk(disk), - _getTcp(tcp)); + _getTcp(tcp), + _getNetSpeed(netSpeed, _servers[idx].status.netSpeed)); } catch (e) { _servers[idx].connectionState = ServerConnectionState.failed; notifyListeners(); @@ -160,6 +170,30 @@ class ServerProvider extends BusyProvider { } } + /// [raw] example: + /// Inter-| Receive | Transmit + /// face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed + /// lo: 45929941 269112 0 0 0 0 0 0 45929941 269112 0 0 0 0 0 0 + /// eth0: 48481023 505772 0 0 0 0 0 0 36002262 202307 0 0 0 0 0 0 + /// 1635752901 + NetSpeed _getNetSpeed(String raw, NetSpeed old) { + final split = raw.split('\n'); + final deviceCount = split.length - 3; + if (deviceCount < 1) return emptyNetSpeed; + final time = int.parse(split[split.length - 2]); + final results = []; + for (int idx = 2; idx < deviceCount; idx++) { + final data = split[idx].trim().split(':'); + final device = data.first; + final bytes = data.last.trim().split(' '); + bytes.removeWhere((element) => element == ''); + final bytesIn = int.parse(bytes.first); + final bytesOut = int.parse(bytes[8]); + results.add(NetSpeedPart(device, bytesIn, bytesOut, time)); + } + return old.update(results); + } + String _getSysVer(String raw) { final s = raw.split('='); if (s.length == 2) { diff --git a/lib/view/page/server/detail.dart b/lib/view/page/server/detail.dart index cfdb6dcf..7fcd04a6 100644 --- a/lib/view/page/server/detail.dart +++ b/lib/view/page/server/detail.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:toolbox/data/model/server/net_speed.dart'; import 'package:toolbox/data/model/server/server.dart'; import 'package:toolbox/data/model/server/server_status.dart'; import 'package:toolbox/data/provider/server.dart'; @@ -47,7 +48,8 @@ class _ServerDetailPageState extends State _buildUpTimeAndSys(si.status), _buildCPUView(si.status), _buildDiskView(si.status), - _buildMemView(si.status) + _buildMemView(si.status), + _buildNetView(si.status.netSpeed) ], ), ); @@ -264,6 +266,10 @@ class _ServerDetailPageState extends State )); } + Widget _buildNetView(NetSpeed ns) { + return Text(ns.speedIn() + '' + ns.speedOut()); + } + static const ignorePath = [ '/run', '/sys',