本文介绍获取系统信息的方法,另外给出根据不同系统编译的方法。

问题提出

由于多年来接触了不同系统的兼容工程,对使用宏区分不同的代码一直有一种莫名的感觉。像 Linux 内核中就有很多这样的代码,coreboot 中有,nRF52 SDK中也有。在实现的工程库也要往这方向考虑,比如线程库和socket库。当接触 golang 后,因其跨平台,编码快,所以在工作中也使用了。但并不是所有代码都是跨平台,像 syscall这样的包,就无法做到。最近的工程中需要获取系统信息,但无法只使用 golang 官方的接口达到目的,最终找到了第三方库github.com/shirou/gopsutil

在找到第三方库前,也想过根据不同的系统编译不同的源码文件,经过考量,还是直接用现成的库。

golang 的编译选项

在进入主题前,先了解一下编译选项。C++可以直接在文件开始和结束处分别加#if 0#endif解决,相应的,golang 可以在.go文件定义包前添加// +build windows// +build linux来区别在哪个系统编译。

如果后面跟着注释,会提示//go:build comment without // +build comment

另一种方法,是直接使用源码文件名称来区分。比如ccall_linux.goccall_windows.go分别在 Linux 系统和 Windows 系统下编译,这种方法非常直观。golang 中带_test的文件是测试用例,这其中的设计思想是一致的。

实际中,笔者使用的工程会调用 Linux 的动态库,但在编译调试时,还是以 Windows 为主,因为涉及 web 前端的设计,这样就可以在 Windows 中不调用动态库,即接口函数做空实现。

获取系统信息

gopsutil 抽象了不同系统,提供统一接口,因为不存在上述问题,本节给出一些示例代码,可以获取一些必要的系统信息,如CPU、内存、磁盘等。

package ginimport ("fmt""os""runtime""time""github.com/shirou/gopsutil/cpu""github.com/shirou/gopsutil/disk""github.com/shirou/gopsutil/host""github.com/shirou/gopsutil/net""github.com/shirou/gopsutil/v3/mem"
)type LSysInfo struct {MemAll         uint64MemFree        uint64MemUsed        uint64MemUsedPercent float64Days           int64Hours          int64Minutes        int64Seconds        int64CpuUsedPercent float64OS             stringArch           stringCpuCores       int
}func GetSysInfo() (info LSysInfo) {unit := uint64(1024 * 1024) // MBv, _ := mem.VirtualMemory()info.MemAll = v.Totalinfo.MemFree = v.Freeinfo.MemUsed = info.MemAll - info.MemFree// 注:使用SwapMemory或VirtualMemory,在不同系统中使用率不一样,因此直接计算一次info.MemUsedPercent = float64(info.MemUsed) / float64(info.MemAll) * 100.0 // v.UsedPercentinfo.MemAll /= unitinfo.MemUsed /= unitinfo.MemFree /= unitinfo.OS = runtime.GOOSinfo.Arch = runtime.GOARCHinfo.CpuCores = runtime.GOMAXPROCS(0)// 获取200ms内的CPU信息,太短不准确,也可以获几秒内的,但这样会有延时,因为要等待cc, _ := cpu.Percent(time.Millisecond*200, false)info.CpuUsedPercent = cc[0]// 获取开机时间boottime, _ := host.BootTime()ntime := time.Now().Unix()btime := time.Unix(int64(boottime), 0).Unix()deltatime := ntime - btimeinfo.Seconds = int64(deltatime)info.Minutes = info.Seconds / 60info.Seconds -= info.Minutes * 60info.Hours = info.Minutes / 60info.Minutes -= info.Hours * 60info.Days = info.Hours / 24info.Hours -= info.Days * 24fmt.Printf("info: %#v\n", info)infoTest()os.Exit(0)return
}func infoTest() {c, _ := cpu.Info()cc, _ := cpu.Percent(time.Second, false) // 1秒d, _ := disk.Usage("/")n, _ := host.Info()nv, _ := net.IOCounters(true)physicalCnt, _ := cpu.Counts(false)logicalCnt, _ := cpu.Counts(true)if len(c) > 1 {for _, sub_cpu := range c {modelname := sub_cpu.ModelNamecores := sub_cpu.Coresfmt.Printf("CPUs: %v   %v cores \n", modelname, cores)}} else {sub_cpu := c[0]modelname := sub_cpu.ModelNamecores := sub_cpu.Coresfmt.Printf("CPU: %v   %v cores \n", modelname, cores)}fmt.Printf("physical count:%d logical count:%d\n", physicalCnt, logicalCnt)fmt.Printf("CPU Used: used %f%%\n", cc[0])fmt.Printf("HD: %v GB Free: %v GB Usage:%f%%\n", d.Total/1024/1024/1024, d.Free/1024/1024/1024, d.UsedPercent)fmt.Printf("OS: %v(%v) %v\n", n.Platform, n.PlatformFamily, n.PlatformVersion)fmt.Printf("Hostname: %v\n", n.Hostname)fmt.Printf("Network: %v bytes / %v bytes\n", nv[0].BytesRecv, nv[0].BytesSent)
}

需要注意的,计算内存的使用率,是根据已获取的已用内存除以总内存,而不是直接由gopsutil获取。计算CPU使用率,需要指定时间间隔,如果秒级别,用户会感觉卡顿,文中代码使用 200 毫秒,经测试,有时获取的值为0。至于运行时间,则通过时间戳直接计算出天数。

某windows系统运行结果如下:

info: gin.LSysInfo{MemAll:0x2ec6, MemFree:0x11a5, MemUsed:0x1d21, MemUsedPercent:62.27692697126946, Days:0, Hours:9, Minutes:26, Seconds:6, CpuUsedPercent:5.882352941068881, OS:"windows", Arch:"amd64", CpuCores:4}
CPU: Intel(R) Core(TM) i5-4210M CPU @ 2.60GHz   4 cores
physical count:2 logical count:4
CPU Used: used 8.593750%
HD: 330 GB Free: 32 GB Usage:90.242198%
OS: Microsoft Windows 7 Ultimate Service Pack 1(Standalone Workstation) 6.1.7601 Build 7601
Hostname: SKY-20210126BVC
Network: 0 bytes / 0 bytes

某 linux 服务器运行结果:

info: gin.LSysInfo{MemAll:0xf84b, MemFree:0x527, MemUsed:0xf323, MemUsedPercent:97.92430801663596, Days:0, Hours:1, Minutes:6, Seconds:38, CpuUsedPercent:0.25062656021506197, OS:"linux", Arch:"amd64", CpuCores:20}
CPUs: Intel(R) Xeon(R) CPU E5-2640 v4 @ 2.40GHz   1 cores
CPUs: Intel(R) Xeon(R) CPU E5-2640 v4 @ 2.40GHz   1 cores
...
physical count:10 logical count:20
CPU Used: used 0.702459%
HD: 49 GB Free: 38 GB Usage:16.708842%
OS: centos(rhel) 7.6.000
Hostname: localhost.localdomain
Network: 1915935 bytes / 224926648 bytes

Golang实践录:获取系统信息相关推荐

  1. Golang实践录:命令行cobra库实例再三优化

    本文是上一文章<Golang实践录:命令行cobra库实例优化> 的优化,主要的子命令的业务实现的整理. 起因 上一版本实现的方式,还是有点不满意,格式也不对齐,重要的是,似乎不是正规的方 ...

  2. Golang实践录:命令行cobra库实例优化

    本文上一文章<Golang实践录:命令行cobra库实例> 的优化,主要的子命令的业务实现的整理. 起因 旧版本中,每个子命令的入口函数,均需一一判断传入参数,并调用对应的业务实现函数,编 ...

  3. go 获得 mysql 实际运行 SQL,Golang实践录:一个数据库迁移的代码记录

    实现一个数据库迁移的案子.有些知识点值得记录. 技术框架 github.com/go-xorm/xorm:数据库操作 github.com/denisenkom/go-mssqldb:sqlserve ...

  4. Golang实践录:利用反射reflect构建通用打印结构体接口

    本文针对 Golang 的结构体字段的打印进行一些研究.其中涉及到一些反射的知识. 问题提出 总结一些实践情况,结构体字段值的输出还是比较常见的,至少笔者目前常用.比如输出某些数据表的数据(代码中会转 ...

  5. Golang实践录:静态资源文件整合:初步使用

    趁着五一放假,趁着有时间,把欠的一些技术集中研究研究,写写文章,好给自己一个交待. 本文介绍如何在 Golang 中整合静态资源文件,将静态资源文件编译到二进制可执行文件中,这与其它程序的打包可能是一 ...

  6. Golang实践录:调用C++函数

    趁着五一放假,趁着有时间,把欠的一些技术集中研究研究,写写文章,好给自己一个交待. 本文介绍如何在 Golang 中调用 C++ 函数. 起因 因工作需求,需要将一个工具由终端行的运行方式迁移到 we ...

  7. Golang实践录:一个数据库迁移的代码记录

    实现一个数据库迁移的案子.有些知识点值得记录. 技术框架 github.com/go-xorm/xorm:数据库操作 github.com/denisenkom/go-mssqldb:sqlserve ...

  8. Golang实践录:静态资源文件整合:web服务

    趁着五一放假,趁着有时间,把欠的一些技术集中研究研究,写写文章,好给自己一个交待. 本文研究静态资源文件的在 web 服务器的整合. 基础 Golang 中的 web 服务框架有很多种,本文选取 gi ...

  9. Golang实践录:oracle数据库实践

    本文在 Windows 7 64bit 系统上使用 golang 连接查询 oracle 数据库. 环境准备 前置条件: 安装mingw(取其gcc及库,因为要用cgo编译),安装git(取其bash ...

最新文章

  1. oracle 强制 断开,ORA-01092 ORACLE 实例终止。强制断开连接 解决方案(下)
  2. jsp mysql修改密码_Servlet+JSP+MySQL实现用户管理模块之七、实现用户信息更新和重置密码...
  3. 【Linux部署】第一次部署ZooKeeper启动两次报错问题解决 Could not find or load main class+Failed to bind to /0.0.0.0:8080
  4. Vagrant挂载目录失败mount: unknown filesystem type ‘vboxsf’
  5. 数据预测之BP神经网络具体应用以及matlab实现
  6. OpenCV辅助对象(help objects)(1)_TermCriteria
  7. layui图片上传按钮按着没反应_关于layui动态生成文件上传按钮后点击无效的解决办法...
  8. oracle读写文件--利用utl_file包对磁盘文件的读写操作
  9. 初识Scrapy,在充满爬虫的世界里做一个好公民
  10. 手把手:教你如何用深度学习模型预测加密货币价格
  11. Win Form不能响应键盘事件
  12. 计算机EV录屏培训体会,停课不停学19|好用的EV录屏软件助力线上教学
  13. Win10字体模糊怎么办?
  14. 如何使用GoldWave中文版将语音转化为文字
  15. 第三阶段应用层——1.7 数码相册—电子书(2)—编写通用的Makefile
  16. qq代理服务器传输文件失败,qq接收文件时显示传输文件失败?
  17. [苹果开发者账号]04 申请苹果开发者账号 美国报税表
  18. ai水墨晕染效果_AI可能是一位优秀的西方画家,但它在中国水墨画中表现良好吗?...
  19. 解决python同时执行多个程序的方案
  20. js中类似${xx,xxxy}的语句——${}占位符的使用 ``模板字符串的使用

热门文章

  1. s时钟画布 android,Canvas画布实现自定义时钟效果
  2. 很详细的“追女生技巧”
  3. 孙宏斌,真的押上了全部身家?
  4. 巴菲特发布2022年致股东公开信:盛赞苹果CEO
  5. CINNO:2025年全球折叠屏智能手机销量有望超5700万部
  6. 格力接受美国5.83亿巨额罚款!官方紧急回应...
  7. 外媒:特斯拉正寻求扩大在华法律事务和对外关系员工队伍
  8. 抖音发布女性数据报告:平均每天31.8万女性发布自拍视频又删除
  9. 工信部下架37款侵害用户权益APP 114票务网等在列
  10. 腾讯砸1亿斗地主欢乐豆签约前《英雄联盟》电竞职业选手Uzi