fix: 表结构更新,修复前端新增数据库端口号为string问题

This commit is contained in:
meilin.huang
2021-11-18 14:40:12 +08:00
parent 8fcdde3711
commit e8d04413f6
11 changed files with 665 additions and 465 deletions

View File

@@ -3,45 +3,41 @@ package machine
import (
"io/ioutil"
"mayfly-go/base/biz"
"mayfly-go/base/global"
"mayfly-go/base/utils"
"mayfly-go/server/devops/domain/entity"
"time"
)
const BasePath = "./machine/shell/"
const BasePath = "./devops/infrastructure/machine/shell/"
const MonitorTemp = "cpuRate:{cpuRate}%,memRate:{memRate}%,sysLoad:{sysLoad}\n"
// const MonitorTemp = "cpuRate:{cpuRate}%,memRate:{memRate}%,sysLoad:{sysLoad}\n"
// shell文件内容缓存避免每次读取文件
var shellCache = make(map[string]string)
func (c *Cli) GetProcessByName(name string) (*string, error) {
return c.Run(getShellContent("sys_info"))
}
// func (c *Cli) GetProcessByName(name string) (*string, error) {
// return c.Run(getShellContent("sys_info"))
// }
func (c *Cli) GetSystemInfo() (*string, error) {
return c.Run(getShellContent("system_info"))
}
// func (c *Cli) GetSystemInfo() (*string, error) {
// return c.Run(getShellContent("system_info"))
// }
func (c *Cli) GetMonitorInfo() *entity.MachineMonitor {
mm := new(entity.MachineMonitor)
res, _ := c.Run(getShellContent("monitor"))
if res == nil {
return nil
}
resMap := make(map[string]interface{})
utils.ReverStrTemplate(MonitorTemp, *res, resMap)
// func (c *Cli) GetMonitorInfo() *entity.MachineMonitor {
// mm := new(entity.MachineMonitor)
// res, _ := c.Run(getShellContent("monitor"))
// if res == nil {
// return nil
// }
// resMap := make(map[string]interface{})
// utils.ReverStrTemplate(MonitorTemp, *res, resMap)
err := utils.Map2Struct(resMap, mm)
if err != nil {
global.Log.Error("解析machine monitor: %s", err.Error())
return nil
}
mm.MachineId = c.machine.Id
mm.CreateTime = time.Now()
return mm
}
// err := utils.Map2Struct(resMap, mm)
// if err != nil {
// global.Log.Error("解析machine monitor: %s", err.Error())
// return nil
// }
// mm.MachineId = c.machine.Id
// mm.CreateTime = time.Now()
// return mm
// }
// 获取shell内容
func getShellContent(name string) string {
@@ -49,6 +45,7 @@ func getShellContent(name string) string {
if cacheShell != "" {
return cacheShell
}
bytes, err := ioutil.ReadFile(BasePath + name + ".sh")
biz.ErrIsNil(err, "获取shell文件失败")
shellStr := string(bytes)

View File

@@ -1,23 +0,0 @@
#! /bin/bash
# Function: 根据输入的程序的名字过滤出所对应的PID并显示出详细信息如果有几个PID则全部显示
NAME=%s
N=`ps -aux | grep $NAME | grep -v grep | wc -l` ##统计进程总数
if [ $N -le 0 ];then
echo "该进程名没有运行!"
fi
i=1
while [ $N -gt 0 ]
do
echo "进程PID: `ps -aux | grep $NAME | grep -v grep | awk 'NR=='$i'{print $0}'| awk '{print $2}'`"
echo "进程命令:`ps -aux | grep $NAME | grep -v grep | awk 'NR=='$i'{print $0}'| awk '{print $11}'`"
echo "进程所属用户: `ps -aux | grep $NAME | grep -v grep | awk 'NR=='$i'{print $0}'| awk '{print $1}'`"
echo "CPU占用率`ps -aux | grep $NAME | grep -v grep | awk 'NR=='$i'{print $0}'| awk '{print $3}'`%"
echo "内存占用率:`ps -aux | grep $NAME | grep -v grep | awk 'NR=='$i'{print $0}'| awk '{print $4}'`%"
echo "进程开始运行的时刻:`ps -aux | grep $NAME | grep -v grep | awk 'NR=='$i'{print $0}'| awk '{print $9}'`"
echo "进程运行的时间:` ps -aux | grep $NAME | grep -v grep | awk 'NR=='$i'{print $0}'| awk '{print $11}'`"
echo "进程状态:`ps -aux | grep $NAME | grep -v grep | awk 'NR=='$i'{print $0}'| awk '{print $8}'`"
echo "进程虚拟内存:`ps -aux | grep $NAME | grep -v grep | awk 'NR=='$i'{print $0}'| awk '{print $5}'`"
echo "进程共享内存:`ps -aux | grep $NAME | grep -v grep | awk 'NR=='$i'{print $0}'| awk '{print $6}'`"
echo "***************************************************************"
let N-- i++
done

View File

@@ -0,0 +1,15 @@
cat /proc/uptime
echo '-----'
/bin/hostname -f
echo '-----'
cat /proc/loadavg
echo '-----'
cat /proc/meminfo
echo '-----'
df -B1
echo '-----'
/sbin/ip -o addr
echo '-----'
/bin/cat /proc/net/dev
echo '-----'
cat /proc/stat

View File

@@ -1,192 +0,0 @@
#!/bin/bash
# func:sys info check
[ $(id -u) -ne 0 ] && echo "请用root用户执行此脚本" && exit 1
sysversion=$(rpm -q centos-release | cut -d- -f3)
line="-------------------------------------------------"
# 获取系统cpu信息
function get_cpu_info() {
Physical_CPUs=$(grep "physical id" /proc/cpuinfo | sort | uniq | wc -l)
Virt_CPUs=$(grep "processor" /proc/cpuinfo | wc -l)
CPU_Kernels=$(grep "cores" /proc/cpuinfo | uniq | awk -F ': ' '{print $2}')
CPU_Type=$(grep "model name" /proc/cpuinfo | awk -F ': ' '{print $2}' | sort | uniq)
CPU_Arch=$(uname -m)
cpu_usage=$(cat /proc/stat | awk '/cpu/{printf("%.2f%\n"), ($2+$4)*100/($2+$4+$5)}' | awk '{print $0}' | head -1)
#echo -e '\033[32m CPU信息\033[0m'
echo -e ' CPU信息'
cat <<EOF | column -t
物理CPU个数: $Physical_CPUs
逻辑CPU个数: $Virt_CPUs
每CPU核心数: $CPU_Kernels
CPU型号: $CPU_Type
CPU架构: $CPU_Arch
CPU使用率: $cpu_usage
EOF
}
# 获取系统内存信息
function get_mem_info() {
Total=$(free -m | sed -n '2p' | awk '{print $2"M"}')
Used=$(free -m | sed -n '2p' | awk '{print $3"M"}')
Rate=$(free -m | sed -n '2p' | awk '{print""($3/$2)*100"%"}')
echo -e ' 内存信息:'
cat <<EOF | column -t
内存总容量:$Total
内存已使用:$Used
内存使用率:$Rate
EOF
}
# 获取系统网络信息
function get_net_info() {
pri_ipadd=$(ifconfig | awk 'NR==2{print $2}')
#pub_ipadd=$(curl ip.sb 2>&1)
pub_ipadd=$(curl -s http://ddns.oray.com/checkip | awk -F ":" '{print $2}' | awk -F "<" '{print $1}' | awk '{print $1}')
gateway=$(ip route | grep default | awk '{print $3}')
mac_info=$(ip link | egrep -v "lo" | grep link | awk '{print $2}')
dns_config=$(egrep 'nameserver' /etc/resolv.conf)
route_info=$(route -n)
echo -e ' IP信息'
cat <<EOF | column -t
系统公网地址: ${pub_ipadd}
系统私网地址: ${pri_ipadd}
网关地址: ${gateway}
MAC地址: ${mac_info}
路由信息:
${route_info}
DNS 信息:
${dns_config}
EOF
}
# 获取系统磁盘信息
function get_disk_info() {
disk_info=$(fdisk -l | grep "Disk /dev" | cut -d, -f1)
disk_use=$(df -hTP | awk '$2!="tmpfs"{print}')
disk_inode=$(df -hiP | awk '$1!="tmpfs"{print}')
echo -e ' 磁盘信息:'
cat <<EOF
${disk_info}
磁盘使用:
${disk_use}
inode信息:
${disk_inode}
EOF
}
# 获取系统信息
function get_systatus_info() {
sys_os=$(uname -o)
sys_release=$(cat /etc/redhat-release)
sys_kernel=$(uname -r)
sys_hostname=$(hostname)
sys_selinux=$(getenforce)
sys_lang=$(echo $LANG)
sys_lastreboot=$(who -b | awk '{print $3,$4}')
sys_runtime=$(uptime | awk '{print $3,$4}' | cut -d, -f1)
sys_time=$(date)
sys_load=$(uptime | cut -d: -f5)
echo -e ' 系统信息:'
cat <<EOF | column -t
系统: ${sys_os}
发行版本: ${sys_release}
系统内核: ${sys_kernel}
主机名: ${sys_hostname}
selinux状态: ${sys_selinux}
系统语言: ${sys_lang}
系统当前时间: ${sys_time}
系统最后重启时间: ${sys_lastreboot}
系统运行时间: ${sys_runtime}
系统负载: ${sys_load}
---------------------------------------
EOF
}
# 获取服务信息
function get_service_info() {
port_listen=$(netstat -lntup | grep -v "Active Internet")
kernel_config=$(sysctl -p 2>/dev/null)
if [ ${sysversion} -gt 6 ]; then
service_config=$(systemctl list-unit-files --type=service --state=enabled | grep "enabled")
run_service=$(systemctl list-units --type=service --state=running | grep ".service")
else
service_config=$(/sbin/chkconfig | grep -E ":on|:启用" | column -t)
run_service=$(/sbin/service --status-all | grep -E "running")
fi
echo -e ' 服务启动配置:'
cat <<EOF
${service_config}
${line}
运行的服务:
${run_service}
${line}
监听端口:
${port_listen}
${line}
内核参考配置:
${kernel_config}
EOF
}
function get_sys_user() {
login_user=$(awk -F: '{if ($NF=="/bin/bash") print $0}' /etc/passwd)
ssh_config=$(egrep -v "^#|^$" /etc/ssh/sshd_config)
sudo_config=$(egrep -v "^#|^$" /etc/sudoers | grep -v "^Defaults")
host_config=$(egrep -v "^#|^$" /etc/hosts)
crond_config=$(for cronuser in /var/spool/cron/*; do
ls ${cronuser} 2>/dev/null | cut -d/ -f5
egrep -v "^$|^#" ${cronuser} 2>/dev/null
echo ""
done)
echo -e ' 系统登录用户:'
cat <<EOF
${login_user}
${line}
ssh 配置信息:
${ssh_config}
${line}
sudo 配置用户:
${sudo_config}
${line}
定时任务配置:
${crond_config}
${line}
hosts 信息:
${host_config}
EOF
}
function process_top_info() {
top_title=$(top -b n1 | head -7 | tail -1)
cpu_top10=$(top b -n1 | head -17 | tail -10)
mem_top10=$(top -b n1 | head -17 | tail -10 | sort -k10 -r)
echo -e ' CPU占用top10'
cat <<EOF
${top_title}
${cpu_top10}
EOF
echo -e ' 内存占用top10'
cat <<EOF
${top_title}
${mem_top10}
EOF
}
function sys_check() {
get_systatus_info
echo ${line}
get_cpu_info
echo ${line}
get_mem_info
echo ${line}
# get_net_info
# echo ${line}
get_disk_info
echo ${line}
get_service_info
echo ${line}
# get_sys_user
# echo ${line}
process_top_info
}
sys_check

View File

@@ -1,41 +0,0 @@
# 获取系统cpu信息
function get_cpu_info() {
Physical_CPUs=$(grep "physical id" /proc/cpuinfo | sort | uniq | wc -l)
Virt_CPUs=$(grep "processor" /proc/cpuinfo | wc -l)
CPU_Kernels=$(grep "cores" /proc/cpuinfo | uniq | awk -F ': ' '{print $2}')
CPU_Type=$(grep "model name" /proc/cpuinfo | awk -F ': ' '{print $2}' | sort | uniq)
CPU_Arch=$(uname -m)
echo -e '\n-------------------------- CPU信息 --------------------------'
cat <<EOF | column -t
物理CPU个数: $Physical_CPUs
逻辑CPU个数: $Virt_CPUs
每CPU核心数: $CPU_Kernels
CPU型号: $CPU_Type
CPU架构: $CPU_Arch
EOF
}
# 获取系统信息
function get_systatus_info() {
sys_os=$(uname -o)
sys_release=$(cat /etc/redhat-release)
sys_kernel=$(uname -r)
sys_hostname=$(hostname)
sys_selinux=$(getenforce)
sys_lang=$(echo $LANG)
sys_lastreboot=$(who -b | awk '{print $3,$4}')
echo -e '-------------------------- 系统信息 --------------------------'
cat <<EOF | column -t
系统: ${sys_os}
发行版本: ${sys_release}
系统内核: ${sys_kernel}
主机名: ${sys_hostname}
selinux状态: ${sys_selinux}
系统语言: ${sys_lang}
系统最后重启时间: ${sys_lastreboot}
EOF
}
get_systatus_info
#echo -e "\n"
get_cpu_info

View File

@@ -0,0 +1,437 @@
package machine
import (
"bufio"
"fmt"
"io"
"sort"
"strconv"
"strings"
"time"
)
type FSInfo struct {
MountPoint string
Used uint64
Free uint64
}
type NetIntfInfo struct {
IPv4 string
IPv6 string
Rx uint64
Tx uint64
}
type cpuRaw struct {
User uint64 // time spent in user mode
Nice uint64 // time spent in user mode with low priority (nice)
System uint64 // time spent in system mode
Idle uint64 // time spent in the idle task
Iowait uint64 // time spent waiting for I/O to complete (since Linux 2.5.41)
Irq uint64 // time spent servicing interrupts (since 2.6.0-test4)
SoftIrq uint64 // time spent servicing softirqs (since 2.6.0-test4)
Steal uint64 // time spent in other OSes when running in a virtualized environment
Guest uint64 // time spent running a virtual CPU for guest operating systems under the control of the Linux kernel.
Total uint64 // total of all time fields
}
type CPUInfo struct {
User float32
Nice float32
System float32
Idle float32
Iowait float32
Irq float32
SoftIrq float32
Steal float32
Guest float32
}
type Stats struct {
Uptime time.Duration
Hostname string
Load1 string
Load5 string
Load10 string
RunningProcs string
TotalProcs string
MemTotal uint64
MemFree uint64
MemBuffers uint64
MemCached uint64
SwapTotal uint64
SwapFree uint64
FSInfos []FSInfo
NetIntf map[string]NetIntfInfo
CPU CPUInfo // or []CPUInfo to get all the cpu-core's stats?
}
func (c *Cli) GetAllStats() *Stats {
res, _ := c.Run(getShellContent("stats"))
infos := strings.Split(*res, "-----")
stats := new(Stats)
getUptime(infos[0], stats)
getHostname(infos[1], stats)
getLoad(infos[2], stats)
getMemInfo(infos[3], stats)
getFSInfo(infos[4], stats)
getInterfaces(infos[5], stats)
getInterfaceInfo(infos[6], stats)
getCPU(infos[7], stats)
return stats
}
func getUptime(uptime string, stats *Stats) (err error) {
parts := strings.Fields(uptime)
if len(parts) == 2 {
var upsecs float64
upsecs, err = strconv.ParseFloat(parts[0], 64)
if err != nil {
return
}
stats.Uptime = time.Duration(upsecs * 1e9)
}
return
}
func getHostname(hostname string, stats *Stats) (err error) {
stats.Hostname = strings.TrimSpace(hostname)
return
}
func getLoad(loadInfo string, stats *Stats) (err error) {
parts := strings.Fields(loadInfo)
if len(parts) == 5 {
stats.Load1 = parts[0]
stats.Load5 = parts[1]
stats.Load10 = parts[2]
if i := strings.Index(parts[3], "/"); i != -1 {
stats.RunningProcs = parts[3][0:i]
if i+1 < len(parts[3]) {
stats.TotalProcs = parts[3][i+1:]
}
}
}
return
}
func getMemInfo(memInfo string, stats *Stats) (err error) {
// "/bin/cat /proc/meminfo"
scanner := bufio.NewScanner(strings.NewReader(memInfo))
for scanner.Scan() {
line := scanner.Text()
parts := strings.Fields(line)
if len(parts) == 3 {
val, err := strconv.ParseUint(parts[1], 10, 64)
if err != nil {
continue
}
val *= 1024
switch parts[0] {
case "MemTotal:":
stats.MemTotal = val
case "MemFree:":
stats.MemFree = val
case "Buffers:":
stats.MemBuffers = val
case "Cached:":
stats.MemCached = val
case "SwapTotal:":
stats.SwapTotal = val
case "SwapFree:":
stats.SwapFree = val
}
}
}
return
}
func getFSInfo(fsInfo string, stats *Stats) (err error) {
// "/bin/df -B1"
scanner := bufio.NewScanner(strings.NewReader(fsInfo))
flag := 0
for scanner.Scan() {
line := scanner.Text()
parts := strings.Fields(line)
n := len(parts)
dev := n > 0 && strings.Index(parts[0], "/dev/") == 0
if n == 1 && dev {
flag = 1
} else if (n == 5 && flag == 1) || (n == 6 && dev) {
i := flag
flag = 0
used, err := strconv.ParseUint(parts[2-i], 10, 64)
if err != nil {
continue
}
free, err := strconv.ParseUint(parts[3-i], 10, 64)
if err != nil {
continue
}
stats.FSInfos = append(stats.FSInfos, FSInfo{
parts[5-i], used, free,
})
}
}
return
}
func getInterfaces(iInfo string, stats *Stats) (err error) {
// "/sbin/ip -o addr"
if stats.NetIntf == nil {
stats.NetIntf = make(map[string]NetIntfInfo)
}
scanner := bufio.NewScanner(strings.NewReader(iInfo))
for scanner.Scan() {
line := scanner.Text()
parts := strings.Fields(line)
if len(parts) >= 4 && (parts[2] == "inet" || parts[2] == "inet6") {
ipv4 := parts[2] == "inet"
intfname := parts[1]
if info, ok := stats.NetIntf[intfname]; ok {
if ipv4 {
info.IPv4 = parts[3]
} else {
info.IPv6 = parts[3]
}
stats.NetIntf[intfname] = info
} else {
info := NetIntfInfo{}
if ipv4 {
info.IPv4 = parts[3]
} else {
info.IPv6 = parts[3]
}
stats.NetIntf[intfname] = info
}
}
}
return
}
func getInterfaceInfo(iInfo string, stats *Stats) (err error) {
// /bin/cat /proc/net/dev
if stats.NetIntf == nil {
return
} // should have been here already
scanner := bufio.NewScanner(strings.NewReader(iInfo))
for scanner.Scan() {
line := scanner.Text()
parts := strings.Fields(line)
if len(parts) == 17 {
intf := strings.TrimSpace(parts[0])
intf = strings.TrimSuffix(intf, ":")
if info, ok := stats.NetIntf[intf]; ok {
rx, err := strconv.ParseUint(parts[1], 10, 64)
if err != nil {
continue
}
tx, err := strconv.ParseUint(parts[9], 10, 64)
if err != nil {
continue
}
info.Rx = rx
info.Tx = tx
stats.NetIntf[intf] = info
}
}
}
return
}
func parseCPUFields(fields []string, stat *cpuRaw) {
numFields := len(fields)
for i := 1; i < numFields; i++ {
val, err := strconv.ParseUint(fields[i], 10, 64)
if err != nil {
continue
}
stat.Total += val
switch i {
case 1:
stat.User = val
case 2:
stat.Nice = val
case 3:
stat.System = val
case 4:
stat.Idle = val
case 5:
stat.Iowait = val
case 6:
stat.Irq = val
case 7:
stat.SoftIrq = val
case 8:
stat.Steal = val
case 9:
stat.Guest = val
}
}
}
// the CPU stats that were fetched last time round
var preCPU cpuRaw
func getCPU(cpuInfo string, stats *Stats) (err error) {
var (
nowCPU cpuRaw
total float32
)
scanner := bufio.NewScanner(strings.NewReader(cpuInfo))
for scanner.Scan() {
line := scanner.Text()
fields := strings.Fields(line)
if len(fields) > 0 && fields[0] == "cpu" { // changing here if want to get every cpu-core's stats
parseCPUFields(fields, &nowCPU)
break
}
}
if preCPU.Total == 0 { // having no pre raw cpu data
goto END
}
total = float32(nowCPU.Total - preCPU.Total)
stats.CPU.User = float32(nowCPU.User-preCPU.User) / total * 100
stats.CPU.Nice = float32(nowCPU.Nice-preCPU.Nice) / total * 100
stats.CPU.System = float32(nowCPU.System-preCPU.System) / total * 100
stats.CPU.Idle = float32(nowCPU.Idle-preCPU.Idle) / total * 100
stats.CPU.Iowait = float32(nowCPU.Iowait-preCPU.Iowait) / total * 100
stats.CPU.Irq = float32(nowCPU.Irq-preCPU.Irq) / total * 100
stats.CPU.SoftIrq = float32(nowCPU.SoftIrq-preCPU.SoftIrq) / total * 100
stats.CPU.Guest = float32(nowCPU.Guest-preCPU.Guest) / total * 100
END:
preCPU = nowCPU
return
}
func fmtUptime(stats *Stats) string {
dur := stats.Uptime
dur = dur - (dur % time.Second)
var days int
for dur.Hours() > 24.0 {
days++
dur -= 24 * time.Hour
}
s1 := dur.String()
s2 := ""
if days > 0 {
s2 = fmt.Sprintf("%dd ", days)
}
for _, ch := range s1 {
s2 += string(ch)
if ch == 'h' || ch == 'm' {
s2 += " "
}
}
return s2
}
func fmtBytes(val uint64) string {
if val < 1024 {
return fmt.Sprintf("%d bytes", val)
} else if val < 1024*1024 {
return fmt.Sprintf("%6.2f KiB", float64(val)/1024.0)
} else if val < 1024*1024*1024 {
return fmt.Sprintf("%6.2f MiB", float64(val)/1024.0/1024.0)
} else {
return fmt.Sprintf("%6.2f GiB", float64(val)/1024.0/1024.0/1024.0)
}
}
func ShowStats(output io.Writer, stats *Stats) {
used := stats.MemTotal - stats.MemFree - stats.MemBuffers - stats.MemCached
fmt.Fprintf(output,
`%s%s%s%s up %s%s%s
Load:
%s%s %s %s%s
CPU:
%s%.2f%s%% user, %s%.2f%s%% sys, %s%.2f%s%% nice, %s%.2f%s%% idle, %s%.2f%s%% iowait, %s%.2f%s%% hardirq, %s%.2f%s%% softirq, %s%.2f%s%% guest
Processes:
%s%s%s running of %s%s%s total
Memory:
free = %s%s%s
used = %s%s%s
buffers = %s%s%s
cached = %s%s%s
swap = %s%s%s free of %s%s%s
`,
escClear,
escBrightWhite, stats.Hostname, escReset,
escBrightWhite, fmtUptime(stats), escReset,
escBrightWhite, stats.Load1, stats.Load5, stats.Load10, escReset,
escBrightWhite, stats.CPU.User, escReset,
escBrightWhite, stats.CPU.System, escReset,
escBrightWhite, stats.CPU.Nice, escReset,
escBrightWhite, stats.CPU.Idle, escReset,
escBrightWhite, stats.CPU.Iowait, escReset,
escBrightWhite, stats.CPU.Irq, escReset,
escBrightWhite, stats.CPU.SoftIrq, escReset,
escBrightWhite, stats.CPU.Guest, escReset,
escBrightWhite, stats.RunningProcs, escReset,
escBrightWhite, stats.TotalProcs, escReset,
escBrightWhite, fmtBytes(stats.MemFree), escReset,
escBrightWhite, fmtBytes(used), escReset,
escBrightWhite, fmtBytes(stats.MemBuffers), escReset,
escBrightWhite, fmtBytes(stats.MemCached), escReset,
escBrightWhite, fmtBytes(stats.SwapFree), escReset,
escBrightWhite, fmtBytes(stats.SwapTotal), escReset,
)
if len(stats.FSInfos) > 0 {
fmt.Println("Filesystems:")
for _, fs := range stats.FSInfos {
fmt.Fprintf(output, " %s%8s%s: %s%s%s free of %s%s%s\n",
escBrightWhite, fs.MountPoint, escReset,
escBrightWhite, fmtBytes(fs.Free), escReset,
escBrightWhite, fmtBytes(fs.Used+fs.Free), escReset,
)
}
fmt.Println()
}
if len(stats.NetIntf) > 0 {
fmt.Println("Network Interfaces:")
keys := make([]string, 0, len(stats.NetIntf))
for intf := range stats.NetIntf {
keys = append(keys, intf)
}
sort.Strings(keys)
for _, intf := range keys {
info := stats.NetIntf[intf]
fmt.Fprintf(output, " %s%s%s - %s%s%s",
escBrightWhite, intf, escReset,
escBrightWhite, info.IPv4, escReset,
)
if len(info.IPv6) > 0 {
fmt.Fprintf(output, ", %s%s%s\n",
escBrightWhite, info.IPv6, escReset,
)
} else {
fmt.Fprintf(output, "\n")
}
fmt.Fprintf(output, " rx = %s%s%s, tx = %s%s%s\n",
escBrightWhite, fmtBytes(info.Rx), escReset,
escBrightWhite, fmtBytes(info.Tx), escReset,
)
fmt.Println()
}
fmt.Println()
}
}
const (
escClear = ""
escRed = ""
escReset = ""
escBrightWhite = ""
)