mirror of
https://gitee.com/dromara/mayfly-go
synced 2026-03-06 01:55:37 +08:00
fix: 表结构更新,修复前端新增数据库端口号为string问题
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
15
server/devops/infrastructure/machine/shell/stats.sh
Normal file
15
server/devops/infrastructure/machine/shell/stats.sh
Normal 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
|
||||
@@ -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
|
||||
@@ -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
|
||||
437
server/devops/infrastructure/machine/stats.go
Normal file
437
server/devops/infrastructure/machine/stats.go
Normal 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 = ""
|
||||
)
|
||||
Reference in New Issue
Block a user