1 Star 0 Fork 0

lihaiping1603 / monitor

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
sysmonitor.go 13.02 KB
一键复制 编辑 原始数据 按行查看 历史
lihaiping1603 提交于 2022-08-31 17:52 . 修改package名
//The MIT License (MIT)
//
//Copyright (c) 2020 lihp1603
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
package monitor
import (
"time"
"gitee.com/lihaiping1603/monitor/proc"
)
//系统状态
type SystemStats struct {
CpuMI *CpuMonitorInfo `json:"cpu"`
VmMI *VmMonitorInfo `json:"vm"`
DiskMI *DiskMonitorInfo `json:"disk"`
MemMI *MemMonitorInfo `json:"mem"`
UptimeMI *UptimeMonitorInfo `json:"uptime"`
LoadavgMI *LoadavgMonitorInfo `json:"loadavg"`
NetDevMI *NetDevicesMonitorInfo `json:"network_devcice"`
}
func NewSystemStats(disk_catalog, disk_name string) (*SystemStats, error) {
sys_stat := &SystemStats{}
cmi, err := NewCpuMonitorInfo()
if err != nil {
return nil, err
}
vmmi, err := NewVmMonitorInfo()
if err != nil {
return nil, err
}
dmi, err := NewDiskMonitorInfo(disk_catalog, disk_name)
if err != nil {
return nil, err
}
mmi, err := NewMemMonitorInfo()
if err != nil {
return nil, err
}
uptimemi, err := NewUptimeMonitorInfo()
if err != nil {
return nil, err
}
lmi, err := NewLoadavgMonitorInfo()
if err != nil {
return nil, err
}
ndi, err := NewNetDevicesMonitorInfo()
if err != nil {
return nil, err
}
//
sys_stat.CpuMI = cmi
sys_stat.VmMI = vmmi
sys_stat.DiskMI = dmi
sys_stat.MemMI = mmi
sys_stat.UptimeMI = uptimemi
sys_stat.LoadavgMI = lmi
sys_stat.NetDevMI = ndi
return sys_stat, nil
}
func (sysstat *SystemStats) GetCpuMI() *CpuMonitorInfo {
return sysstat.CpuMI
}
var (
sys_cpu_info *proc.CPUInfo = nil
)
//更新系统cpu信息
func InitSysCpuInfo() error {
if sys_cpu_info != nil {
return nil
}
cpu_info, err := proc.ReadCPUInfo()
if err != nil {
return err
}
sys_cpu_info = cpu_info
return nil
}
func init() {
if err := InitSysCpuInfo(); err != nil {
LogErr("init system cpu info:", err)
}
}
// UsagePctCPU is an object that represents the average cpu usage over a
// time period. It is calculated by taking the difference between two
// CPUSamples (whose units are clock ticks), dividing by the number of elapsed
// ticks between the samples, and converting to a percent.
type CpuMonitorInfo struct {
cpustat proc.CPUStat
CpuUsagePercent float64 `json:"cpu_percent"` //系统cpu使用率
Cpus int16 `json:"cpus"` //处理器数量
CpuOnline int16 `json:"cpus_online"` //可用的cpu数量
}
func NewCpuMonitorInfo() (*CpuMonitorInfo, error) {
cmi := &CpuMonitorInfo{}
if err := cmi.UpdateMonitorInfo(); err != nil {
return nil, err
}
return cmi, nil
}
func (cmi *CpuMonitorInfo) UpdateMonitorInfo() error {
cur_cpus_stat, err := proc.ReadProcSystemStat()
if err != nil {
return err
}
cur_cpu_stat := cur_cpus_stat.GetCpuStatAll()
cmi.calculateUsagePercent(cur_cpu_stat)
cmi.cpustat = *cur_cpu_stat
//
if cmi.Cpus <= 0 {
cpu_info, err := proc.ReadCPUInfo()
if err != nil {
return err
}
cmi.Cpus = int16(cpu_info.NumCPU())
cmi.CpuOnline = cmi.Cpus
}
return nil
}
func (cmi *CpuMonitorInfo) calculateUsagePercent(cur *proc.CPUStat) {
if cmi.cpustat.GetCpuTotal() <= 0 {
return
}
total := float64(cur.GetCpuTotal() - cmi.cpustat.GetCpuTotal())
idled := float64(cur.GetCpuIdle() - cmi.cpustat.GetCpuIdle())
invQuotient := 100.00 / total
cmi.CpuUsagePercent = (total - idled) * invQuotient
}
type CpuStatPercent struct {
UserPct float64
NicePct float64
SystemPct float64
IdlePct float64
IowaitPct float64
IrqPct float64
SoftIrqPct float64
StealPct float64
GuestPct float64
}
//计算这段时间内的cpu平均指标百分比
func CalculateCPUStat(second, first proc.CPUStat) (res CpuStatPercent) {
total := float64(second.GetCpuTotal() - first.GetCpuTotal())
//idled := float64(second.GetCpuIdle() - first.GetCpuIdle())
invQuotient := 100.00 / total
//differentiate: actual value minus the previous one
res.UserPct = subtractAndConvertTicks(second.User, first.User) * invQuotient
res.NicePct = subtractAndConvertTicks(second.Nice, first.Nice) * invQuotient
res.SystemPct = subtractAndConvertTicks(second.System, first.System) * invQuotient
res.IdlePct = subtractAndConvertTicks(second.Idle, first.Idle) * invQuotient
res.IowaitPct = subtractAndConvertTicks(second.IOWait, first.IOWait) * invQuotient
res.IrqPct = subtractAndConvertTicks(second.IRQ, first.IRQ) * invQuotient
res.SoftIrqPct = subtractAndConvertTicks(second.SoftIRQ, first.SoftIRQ) * invQuotient
res.StealPct = subtractAndConvertTicks(second.Steal, first.Steal) * invQuotient
res.GuestPct = subtractAndConvertTicks(second.Guest, first.Guest) * invQuotient
return
}
func subtractAndConvertTicks(second, first uint64) float64 {
return float64(second - first)
}
type VmMonitorInfo struct {
vmstat proc.VMStat
VmReadKBps int64 `json:"disk_read_KBps"` //读速度
VmWriteKBps int64 `json:"disk_write_KBps"` //写速度
}
func NewVmMonitorInfo() (*VmMonitorInfo, error) {
vmmi := &VmMonitorInfo{}
if err := vmmi.UpdateMonitorInfo(); err != nil {
return nil, err
}
return vmmi, nil
}
func (vmmi *VmMonitorInfo) UpdateMonitorInfo() error {
cur_vmstat, err := proc.ReadVMStat()
if err != nil {
return err
}
vmmi.calculate(cur_vmstat)
vmmi.vmstat = *cur_vmstat
return nil
}
func (vmmi *VmMonitorInfo) calculate(cur *proc.VMStat) {
last := vmmi.vmstat
if last.GetPagePagein() <= 0 || last.GetPagePageout() <= 0 {
return
}
// KBps = KB * 1000 / ms = KB/s
duration_ms := cur.GetSampleTime().Sub(last.GetSampleTime()).Milliseconds()
invQuotient := 1000 / duration_ms
vmmi.VmReadKBps = int64(cur.GetPagePagein()-last.GetPagePagein()) * invQuotient
vmmi.VmWriteKBps = int64(cur.GetPagePageout()-last.GetPagePageout()) * invQuotient
return
}
type DiskMonitorInfo struct {
path string //监控的盘符路径
diskName string //监控状态的磁盘名 divece name
diskstat proc.DiskStat //
DiskBusyPercent float64 `json:"disk_busy_percent"` //磁盘繁忙度
DiskUsedPercent float64 `json:"disk_usage_percent"` //磁盘容量占比
DiskCapacityMb uint64 `json:"disk_capacity_mb"` //磁盘容量
DiskUsedMb uint64 `json:"disk_used_mb"` //磁盘用了
DiskFreeMb uint64 `json:"disk_free_mb"` //磁盘空闲
}
func NewDiskMonitorInfo(disk_path, disk_name string) (*DiskMonitorInfo, error) {
if disk_path == "" {
disk_path = "/"
}
if disk_name == "" {
disk_name = "sda"
}
diskmi := &DiskMonitorInfo{path: disk_path, diskName: disk_name}
if err := diskmi.UpdateMonitorInfo(); err != nil {
return nil, err
}
return diskmi, nil
}
func (dmi *DiskMonitorInfo) UpdateMonitorInfo() error {
disk_path := dmi.path
disk_capacity, err := proc.ReadDisk(disk_path)
if err != nil {
return err
}
dmi.calculateDiskCapacity(disk_capacity)
//disk stat
disk_stats, err := proc.ReadDiskStats()
if err != nil {
return err
}
for _, disk_stat := range disk_stats {
if disk_stat.GetName() == dmi.diskName {
//计算busy度
dmi.calculateDiskBusyPercent(&disk_stat)
dmi.diskstat = disk_stat
}
}
return nil
}
const (
SYS_KB = 1024
SYS_MB = 1024 * SYS_KB
)
func (dmi *DiskMonitorInfo) calculateDiskCapacity(cur *proc.Disk) {
if cur.GetTotalCapacityByte() <= 0 {
return
}
dmi.DiskCapacityMb = cur.GetTotalCapacityByte() / SYS_MB
dmi.DiskUsedMb = cur.GetUsedByte() / SYS_MB
dmi.DiskFreeMb = cur.GetFreeByte() / SYS_MB
dmi.DiskUsedPercent = 100.0 * float64(dmi.DiskUsedMb) / float64(dmi.DiskCapacityMb)
return
}
func (dmi *DiskMonitorInfo) calculateDiskBusyPercent(cur_disk_stat *proc.DiskStat) {
last_disk_stat := dmi.diskstat
if last_disk_stat.GetIOTicks() <= 0 || cur_disk_stat.GetIOTicks() <= 0 {
return
}
delta_ms := cur_disk_stat.GetSampleTime().Sub(last_disk_stat.GetSampleTime()).Milliseconds()
io_delta_ticks := cur_disk_stat.GetIOTicks() - last_disk_stat.GetIOTicks()
io_delta_ms := io_delta_ticks.Milliseconds()
busy_percent := 100.0 * float64(io_delta_ms) / float64(delta_ms)
dmi.DiskBusyPercent = busy_percent
return
}
type MemMonitorInfo struct {
MemRamKByte uint64 `json:"mem_ram_kbyte"` //内存大小
MemRamPercent float64 `json:"mem_ram_percent"` //内存使用率
MemSwapKByte uint64 `json:"mem_swap_kbyte"` //swap内存大小
MemSwapPercent float64 `json:"mem_swap_percent"` //swap使用率
}
func NewMemMonitorInfo() (*MemMonitorInfo, error) {
mmi := &MemMonitorInfo{}
if err := mmi.UpdateMonitorInfo(); err != nil {
return nil, err
}
return mmi, nil
}
func (mmi *MemMonitorInfo) UpdateMonitorInfo() error {
cur_mem_info, err := proc.ReadMemInfo()
if err != nil {
return err
}
mmi.calculateUsage(cur_mem_info)
return nil
}
func (mmi *MemMonitorInfo) calculateUsage(cur_mem_info *proc.MemInfo) {
mem_total := cur_mem_info.GetMemTotalKB()
mem_free := cur_mem_info.GetMemFreeKB()
mem_buffered := cur_mem_info.GetMemBuffersKB()
mem_cached := cur_mem_info.GetMemCachedKB()
mem_swaped_total := cur_mem_info.GetSwapTotalKB()
mem_swaped_free := cur_mem_info.GetSwapFreeKB()
mem_active := mem_total - mem_free
mem_inused := mem_active - mem_buffered - mem_cached
//mem_notused := mem_total - mem_inused
if mem_total > 0 {
used_percent := 100.0 * float64(mem_inused) / float64(mem_total)
mmi.MemRamPercent = used_percent
mmi.MemRamKByte = mem_total
}
if mem_swaped_total > 0 {
mmi.MemSwapKByte = mem_swaped_total
mmi.MemSwapPercent = 100.0 * (1.0 - float64(mem_swaped_free)/float64(mem_swaped_total))
}
return
}
type UptimeMonitorInfo struct {
UptimeIdlePercent float64 `json:"ilde_percent"` //uptime衡量系统自启动以来的空闲度
UptimeTotalSec uint64 `json:"uptime"` //自系统启动来的时间
UptimeIdleSec uint64 `json:"ilde_time"` //空闲时间
}
func NewUptimeMonitorInfo() (*UptimeMonitorInfo, error) {
utmi := &UptimeMonitorInfo{}
if err := utmi.UpdateMonitorInfo(); err != nil {
return nil, err
}
return utmi, nil
}
func (utmi *UptimeMonitorInfo) UpdateMonitorInfo() error {
uptime, err := proc.ReadUptime()
if err != nil {
return err
}
utmi.UptimeTotalSec = uint64(uptime.GetTotalDuration())
utmi.UptimeIdleSec = uint64(uptime.GetIdleDuration())
if sys_cpu_info != nil {
utmi.UptimeIdlePercent = uptime.CalculateIdlePercent(int16(sys_cpu_info.NumCPU()))
}
return nil
}
type LoadavgMonitorInfo struct {
Loadavg1Min float64 `json:"load_1m"` //最近1min的负荷情况
Loadavg5min float64 `json:"load_5m"`
Loadavg15min float64 `json:"load_15m"`
}
func NewLoadavgMonitorInfo() (*LoadavgMonitorInfo, error) {
lmi := &LoadavgMonitorInfo{}
if err := lmi.UpdateMonitorInfo(); err != nil {
return nil, err
}
return lmi, nil
}
func (lmi *LoadavgMonitorInfo) UpdateMonitorInfo() error {
loadavg, err := proc.ReadLoadAvg()
if err != nil {
return err
}
lmi.Loadavg1Min = loadavg.GetLast1Min()
lmi.Loadavg5min = loadavg.GetLast5Min()
lmi.Loadavg15min = loadavg.GetLast15Min()
return nil
}
type NetDevicesMonitorInfo struct {
NetSampleTime time.Time `json:"net_sample_time"` //网络数据采集时间
NetRecvBytePublic uint64 `json:"net_recv_bytes"` //公有网络数据
NetSendBytePublic uint64 `json:"net_send_bytes"`
NetRecvBytePriv uint64 `json:"net_recvi_bytes"` //私有网络数据
NetSendBytePriv uint64 `json:"net_sendi_bytes"`
}
func NewNetDevicesMonitorInfo() (*NetDevicesMonitorInfo, error) {
ndmi := &NetDevicesMonitorInfo{}
if err := ndmi.UpdateMonitorInfo(); err != nil {
return nil, err
}
return ndmi, nil
}
func (ndmi *NetDevicesMonitorInfo) UpdateMonitorInfo() error {
netdev_stats, err := proc.ReadNetDevStat()
if err != nil {
return err
}
var (
privRecvByte uint64 = 0
privSendByte uint64 = 0
pubRecvByte uint64 = 0
pubSendByte uint64 = 0
)
sampletime := time.Now()
for _, netdev_stat := range netdev_stats {
if netdev_stat.GetIfaceName() == "lo" { //
privRecvByte += netdev_stat.GetRxBytes()
privSendByte += netdev_stat.GetTxBytes()
continue
}
pubRecvByte += netdev_stat.GetRxBytes()
pubSendByte += netdev_stat.GetTxBytes()
sampletime = netdev_stat.GetSampleTime()
}
ndmi.NetRecvBytePriv = privRecvByte
ndmi.NetSendBytePriv = privSendByte
ndmi.NetRecvBytePublic = pubRecvByte
ndmi.NetSendBytePublic = pubSendByte
ndmi.NetSampleTime = sampletime
return nil
}
Go
1
https://gitee.com/lihaiping1603/monitor.git
git@gitee.com:lihaiping1603/monitor.git
lihaiping1603
monitor
monitor
06ce4da2b892

搜索帮助