v0.0.7 - 更新支持查询GPU信息

This commit is contained in:
spiritlhl
2024-07-28 13:03:04 +00:00
parent 3a3f46d5cc
commit 58e26753bb
19 changed files with 894 additions and 7 deletions

View File

@@ -24,7 +24,7 @@ jobs:
run: | run: |
git config --global user.name 'github-actions' git config --global user.name 'github-actions'
git config --global user.email 'github-actions@github.com' git config --global user.email 'github-actions@github.com'
TAG="v0.0.6-$(date +'%Y%m%d%H%M%S')" TAG="v0.0.7-$(date +'%Y%m%d%H%M%S')"
git tag $TAG git tag $TAG
git push origin $TAG git push origin $TAG
env: env:

View File

@@ -12,10 +12,10 @@ Include: https://github.com/oneclickvirt/gostun
- [x] 使用```sysctl```获取CPU信息-特化适配freebsd、openbsd系统 - [x] 使用```sysctl```获取CPU信息-特化适配freebsd、openbsd系统
- [x] 适配```MacOS```与```Windows```系统的信息查询 - [x] 适配```MacOS```与```Windows```系统的信息查询
- [x] 部分Windows10系统下打勾打叉编码错误显示已判断是Win时使用Y/N显示而不是勾叉 - [x] 部分Windows10系统下打勾打叉编码错误显示已判断是Win时使用Y/N显示而不是勾叉
- [x] 检测GPU相关信息参考[ghw](https://github.com/jaypipes/ghw)
## TODO ## TODO
- [ ] 检测GPU相关信息可参考[ghw](https://github.com/jaypipes/ghw)
- [ ] CPUCache的信息需要矫正 - [ ] CPUCache的信息需要矫正
- [ ] 纯IPV6环境下使用cdn反代获取平台信息 - [ ] 纯IPV6环境下使用cdn反代获取平台信息

11
go.mod
View File

@@ -4,6 +4,8 @@ go 1.22.4
require ( require (
github.com/imroc/req/v3 v3.43.7 github.com/imroc/req/v3 v3.43.7
github.com/jaypipes/ghw v0.12.0
github.com/json-iterator/go v1.1.12
github.com/libp2p/go-nat v0.2.0 github.com/libp2p/go-nat v0.2.0
github.com/oneclickvirt/defaultset v0.0.2-20240624082446 github.com/oneclickvirt/defaultset v0.0.2-20240624082446
github.com/oneclickvirt/gostun v0.0.3-20240702054621 github.com/oneclickvirt/gostun v0.0.3-20240702054621
@@ -13,8 +15,10 @@ require (
) )
require ( require (
github.com/StackExchange/wmi v1.2.1 // indirect
github.com/andybalholm/brotli v1.1.0 // indirect github.com/andybalholm/brotli v1.1.0 // indirect
github.com/cloudflare/circl v1.3.9 // indirect github.com/cloudflare/circl v1.3.9 // indirect
github.com/ghodss/yaml v1.0.0 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/google/gopacket v1.1.19 // indirect github.com/google/gopacket v1.1.19 // indirect
@@ -23,16 +27,21 @@ require (
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/huin/goupnp v1.2.0 // indirect github.com/huin/goupnp v1.2.0 // indirect
github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect
github.com/jaypipes/pcidb v1.0.0 // indirect
github.com/klauspost/compress v1.17.9 // indirect github.com/klauspost/compress v1.17.9 // indirect
github.com/koron/go-ssdp v0.0.4 // indirect github.com/koron/go-ssdp v0.0.4 // indirect
github.com/libp2p/go-netroute v0.2.1 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/onsi/ginkgo/v2 v2.19.0 // indirect github.com/onsi/ginkgo/v2 v2.19.0 // indirect
github.com/pion/dtls/v2 v2.2.7 // indirect github.com/pion/dtls/v2 v2.2.7 // indirect
github.com/pion/logging v0.2.2 // indirect github.com/pion/logging v0.2.2 // indirect
github.com/pion/stun/v2 v2.0.0 // indirect github.com/pion/stun/v2 v2.0.0 // indirect
github.com/pion/transport/v2 v2.2.1 // indirect github.com/pion/transport/v2 v2.2.1 // indirect
github.com/pion/transport/v3 v3.0.1 // indirect github.com/pion/transport/v3 v3.0.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect
github.com/quic-go/quic-go v0.45.1 // indirect github.com/quic-go/quic-go v0.45.1 // indirect
@@ -50,4 +59,6 @@ require (
golang.org/x/sync v0.7.0 // indirect golang.org/x/sync v0.7.0 // indirect
golang.org/x/text v0.16.0 // indirect golang.org/x/text v0.16.0 // indirect
golang.org/x/tools v0.22.0 // indirect golang.org/x/tools v0.22.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
howett.net/plist v1.0.0 // indirect
) )

33
go.sum
View File

@@ -1,3 +1,5 @@
github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=
github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8=
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
github.com/cloudflare/circl v1.3.9 h1:QFrlgFYf2Qpi8bSpVPK1HBvWpx16v/1TZivyo7pGuBE= github.com/cloudflare/circl v1.3.9 h1:QFrlgFYf2Qpi8bSpVPK1HBvWpx16v/1TZivyo7pGuBE=
@@ -5,8 +7,11 @@ github.com/cloudflare/circl v1.3.9/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZ
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
@@ -14,6 +19,7 @@ github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZ
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
github.com/google/pprof v0.0.0-20240625030939-27f56978b8b0 h1:e+8XbKB6IMn8A4OAyZccO4pYfB3s7bt6azNIPE7AnPg= github.com/google/pprof v0.0.0-20240625030939-27f56978b8b0 h1:e+8XbKB6IMn8A4OAyZccO4pYfB3s7bt6azNIPE7AnPg=
@@ -29,16 +35,33 @@ github.com/imroc/req/v3 v3.43.7 h1:dOcNb9n0X83N5/5/AOkiU+cLhzx8QFXjv5MhikazzQA=
github.com/imroc/req/v3 v3.43.7/go.mod h1:SQIz5iYop16MJxbo8ib+4LnostGCok8NQf8ToyQc2xA= github.com/imroc/req/v3 v3.43.7/go.mod h1:SQIz5iYop16MJxbo8ib+4LnostGCok8NQf8ToyQc2xA=
github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
github.com/jaypipes/ghw v0.12.0 h1:xU2/MDJfWmBhJnujHY9qwXQLs3DBsf0/Xa9vECY0Tho=
github.com/jaypipes/ghw v0.12.0/go.mod h1:jeJGbkRB2lL3/gxYzNYzEDETV1ZJ56OKr+CSeSEym+g=
github.com/jaypipes/pcidb v1.0.0 h1:vtZIfkiCUE42oYbJS0TAq9XSfSmcsgo9IdxSm9qzYU8=
github.com/jaypipes/pcidb v1.0.0/go.mod h1:TnYUvqhPBzCKnH34KrIX22kAeEbDCSRJ9cqLRCuNDfk=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0=
github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/libp2p/go-nat v0.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk= github.com/libp2p/go-nat v0.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk=
github.com/libp2p/go-nat v0.2.0/go.mod h1:3MJr+GRpRkyT65EpVPBstXLvOlAPzUVlG6Pwg9ohLJk= github.com/libp2p/go-nat v0.2.0/go.mod h1:3MJr+GRpRkyT65EpVPBstXLvOlAPzUVlG6Pwg9ohLJk=
github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU=
github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/oneclickvirt/defaultset v0.0.2-20240624082446 h1:5Pg3mK/u/vQvSz7anu0nxzrNdELi/AcDAU1mMsmPzyc= github.com/oneclickvirt/defaultset v0.0.2-20240624082446 h1:5Pg3mK/u/vQvSz7anu0nxzrNdELi/AcDAU1mMsmPzyc=
github.com/oneclickvirt/defaultset v0.0.2-20240624082446/go.mod h1:e9Jt4tf2sbemCtc84/XgKcHy9EZ2jkc5x2sW1NiJS+E= github.com/oneclickvirt/defaultset v0.0.2-20240624082446/go.mod h1:e9Jt4tf2sbemCtc84/XgKcHy9EZ2jkc5x2sW1NiJS+E=
github.com/oneclickvirt/gostun v0.0.3-20240702054621 h1:IE89eEYV9TJbF94SakQDAxTLIaqX+Tb6ZhJ/CCIP+90= github.com/oneclickvirt/gostun v0.0.3-20240702054621 h1:IE89eEYV9TJbF94SakQDAxTLIaqX+Tb6ZhJ/CCIP+90=
@@ -57,6 +80,8 @@ github.com/pion/transport/v2 v2.2.1 h1:7qYnCBlpgSJNYMbLCKuSY9KbQdBFoETvPNETv0y4N
github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g=
github.com/pion/transport/v3 v3.0.1 h1:gDTlPJwROfSfz6QfSi0ZmeCSkFcnWWiiR9ES0ouANiM= github.com/pion/transport/v3 v3.0.1 h1:gDTlPJwROfSfz6QfSi0ZmeCSkFcnWWiiR9ES0ouANiM=
github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
@@ -76,6 +101,7 @@ github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnj
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
@@ -171,6 +197,13 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM=
howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=

View File

@@ -1,6 +1,6 @@
package model package model
const BasicsVersion = "v0.0.6" const BasicsVersion = "v0.0.7"
var EnableLoger bool var EnableLoger bool
@@ -119,6 +119,7 @@ type DiskInfo struct {
type SystemInfo struct { type SystemInfo struct {
CpuInfo CpuInfo
GPUInfo
MemoryInfo MemoryInfo
DiskInfo DiskInfo
Platform string // 系统名字 Distro1 Platform string // 系统名字 Distro1
@@ -135,6 +136,11 @@ type SystemInfo struct {
TcpAccelerationMethod string // TCP拥塞控制 TcpAccelerationMethod string // TCP拥塞控制
} }
type GPUInfo struct {
GpuModel string
GpuStats string
}
type Win32_Processor struct { type Win32_Processor struct {
L2CacheSize uint32 L2CacheSize uint32
L3CacheSize uint32 L3CacheSize uint32

87
system/gpu.go Normal file
View File

@@ -0,0 +1,87 @@
package system
import (
"fmt"
"math"
"sync"
"sync/atomic"
"time"
"github.com/oneclickvirt/basics/model"
"github.com/oneclickvirt/basics/system/gpu"
gpustat "github.com/oneclickvirt/basics/system/gpu/stat"
. "github.com/oneclickvirt/defaultset"
)
var updateGPUStatus int32
var gpuStat uint64
// 获取设备数据的最大尝试次数
const maxDeviceDataFetchAttempts = 3
// 获取主机数据的尝试次数Key 为 Host 的属性名
var hostDataFetchAttempts = map[string]int{
"CPU": 0,
"GPU": 0,
}
// 获取状态数据的尝试次数Key 为 HostState 的属性名
var statDataFetchAttempts = map[string]int{
"CPU": 0,
"Load": 0,
"GPU": 0,
"Temperatures": 0,
}
func atomicStoreFloat64(x *uint64, v float64) {
atomic.StoreUint64(x, math.Float64bits(v))
}
func updateGPUStat(gpuStat *uint64, wg *sync.WaitGroup) {
if model.EnableLoger {
InitLogger()
defer Logger.Sync()
}
defer wg.Done()
if !atomic.CompareAndSwapInt32(&updateGPUStatus, 0, 1) {
return
}
defer atomic.StoreInt32(&updateGPUStatus, 0)
for statDataFetchAttempts["GPU"] < maxDeviceDataFetchAttempts {
gs, err := gpustat.GetGPUStat()
if err != nil {
statDataFetchAttempts["GPU"]++
if model.EnableLoger {
Logger.Info(fmt.Sprintf("gpustat.GetGPUStat error: %s, attempt: %d", err.Error(), statDataFetchAttempts["GPU"]))
}
time.Sleep(1 * time.Second) // 等待一段时间再重试
} else {
statDataFetchAttempts["GPU"] = 0
atomicStoreFloat64(gpuStat, gs)
break
}
}
}
func getGPUInfo(ret *model.SystemInfo) (*model.SystemInfo, error) {
gpuModels, err := gpu.GetGPUModel()
if len(gpuModels) > 0 {
if err != nil {
hostDataFetchAttempts["GPU"]++
return ret, fmt.Errorf("no gpu")
} else {
hostDataFetchAttempts["GPU"] = 0
}
ret.GpuModel = gpuModels[0]
var wg sync.WaitGroup
wg.Add(1)
go updateGPUStat(&gpuStat, &wg)
wg.Wait() // 等待 updateGPUStat 完成
ret.GpuStats = fmt.Sprintf("%f", math.Float64frombits(gpuStat))
return ret, nil
} else {
hostDataFetchAttempts["GPU"]++
return ret, fmt.Errorf("no gpu")
}
}

27
system/gpu/gpu.go Normal file
View File

@@ -0,0 +1,27 @@
//go:build !darwin
// +build !darwin
package gpu
import (
"errors"
"github.com/jaypipes/ghw"
)
func GetGPUModel() ([]string, error) {
var gpuModel []string
gi, err := ghw.GPU(ghw.WithDisableWarnings())
if err != nil {
return nil, err
}
for _, card := range gi.GraphicsCards {
if card.DeviceInfo == nil {
return nil, errors.New("Cannot find device info")
}
gpuModel = append(gpuModel, card.DeviceInfo.Product.Name)
}
return gpuModel, nil
}

53
system/gpu/gpu_darwin.go Normal file
View File

@@ -0,0 +1,53 @@
//go:build darwin && !cgo
package gpu
import (
"os/exec"
"regexp"
"strings"
)
func extractGPUInfo(cmd *exec.Cmd) ([]string, error) {
gi, err := cmd.CombinedOutput()
if err != nil {
return nil, err
}
re := regexp.MustCompile(`"model"\s*=\s*["<]?"([^">]+)"[">]?`)
matches := re.FindAllSubmatch(gi, -1)
var modelNames []string
for _, match := range matches {
if len(match) > 1 {
modelNames = append(modelNames, string(match[1]))
}
}
return modelNames, nil
}
func GetGPUModel() ([]string, error) {
vendorNames := []string{
"AMD", "Intel", "Nvidia", "Apple",
}
ioreg := exec.Command("ioreg", "-rd1", "-c", "IOAccelerator")
gi, err := extractGPUInfo(ioreg)
if err != nil || len(gi) == 0 {
ioreg = exec.Command("ioreg", "-rd1", "-c", "IOPCIDevice")
gi, err = extractGPUInfo(ioreg)
if err != nil {
return nil, err
}
}
var gpuModel []string
for _, model := range gi {
for _, vendor := range vendorNames {
if strings.Contains(model, vendor) {
gpuModel = append(gpuModel, model)
break
}
}
}
return gpuModel, nil
}

View File

@@ -0,0 +1,65 @@
//go:build darwin && cgo
package gpu
// #cgo LDFLAGS: -framework IOKit -framework CoreFoundation
// #include "stat/gpu_darwin.h"
import "C"
import (
"errors"
"strings"
"unsafe"
)
func GoStrings(argc C.int, argv **C.char) []string {
length := int(argc)
tmpslice := unsafe.Slice(argv, length)
gostrings := make([]string, length)
for i, s := range tmpslice {
gostrings[i] = C.GoString(s)
}
return gostrings
}
func extractGPUInfo(key *C.char) ([]string, error) {
devices := C.find_devices(key)
if devices != nil {
defer C.free(unsafe.Pointer(devices))
length := 0
for {
device := *(**C.char)(unsafe.Pointer(uintptr(unsafe.Pointer(devices)) + uintptr(length)*unsafe.Sizeof(*devices)))
if device == nil {
break
}
length++
}
gpu := GoStrings(C.int(length), devices)
return gpu, nil
}
return nil, errors.New("cannot find key")
}
func GetGPUModel() ([]string, error) {
vendorNames := []string{
"AMD", "Intel", "Nvidia", "Apple",
}
key := C.CString("model")
defer C.free(unsafe.Pointer(key))
gi, err := extractGPUInfo(key)
if err != nil {
return nil, err
}
var gpuModel []string
for _, model := range gi {
for _, vendor := range vendorNames {
if strings.Contains(model, vendor) {
gpuModel = append(gpuModel, model)
break
}
}
}
return gpuModel, nil
}

View File

@@ -0,0 +1,66 @@
package stat
// Modified from https://github.com/influxdata/telegraf/blob/master/plugins/inputs/amd_rocm_smi/amd_rocm_smi.go
// Original License: MIT
import (
"errors"
"os"
"os/exec"
"strconv"
jsoniter "github.com/json-iterator/go"
)
type ROCmSMI struct {
BinPath string
}
func (rsmi *ROCmSMI) Gather() ([]float64, error) {
data := rsmi.pollROCmSMI()
return gatherROCmSMI(data)
}
func (rsmi *ROCmSMI) Start() error {
if _, err := os.Stat(rsmi.BinPath); os.IsNotExist(err) {
binPath, err := exec.LookPath("rocm-smi")
if err != nil {
return errors.New("Didn't find the adequate tool to query GPU utilization")
}
rsmi.BinPath = binPath
}
return nil
}
func (rsmi *ROCmSMI) pollROCmSMI() []byte {
cmd := exec.Command(rsmi.BinPath,
"-u",
"--json",
)
gs, err := cmd.CombinedOutput()
if err != nil {
return nil
}
return gs
}
func gatherROCmSMI(ret []byte) ([]float64, error) {
var gpus map[string]GPU
var percentage []float64
Json := jsoniter.ConfigCompatibleWithStandardLibrary
err := Json.Unmarshal(ret, &gpus)
if err != nil {
return nil, err
}
for _, gpu := range gpus {
gp, _ := strconv.ParseFloat(gpu.GpuUsePercentage, 64)
percentage = append(percentage, gp)
}
return percentage, nil
}
type GPU struct {
GpuUsePercentage string `json:"GPU use (%)"`
}

View File

@@ -0,0 +1,144 @@
#include "gpu_darwin.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define IOSERVICE_GPU "IOAccelerator"
#define IOSERVICE_PCI "IOPCIDevice"
void *find_properties(io_registry_entry_t service, int depth, CFStringRef key,
CFStringRef dict_key) {
CFTypeRef properties = IORegistryEntrySearchCFProperty(
service, kIOServicePlane, key, kCFAllocatorDefault,
kIORegistryIterateRecursively);
if (properties) {
if (CFGetTypeID(properties) == CFStringGetTypeID()) {
CFStringRef cfStr = (CFStringRef)properties;
char buffer[1024];
CFStringGetCString(cfStr, buffer, sizeof(buffer), kCFStringEncodingUTF8);
CFRelease(properties);
return strdup(buffer);
} else if (CFGetTypeID(properties) == CFDictionaryGetTypeID()) {
CFDictionaryRef cfDict = (CFDictionaryRef)properties;
CFNumberRef cfValue = (CFNumberRef)CFDictionaryGetValue(cfDict, dict_key);
if (cfValue == NULL) {
return NULL;
}
int value;
if (!CFNumberGetValue(cfValue, kCFNumberIntType, &value)) {
return NULL;
}
return (void *)(intptr_t)value;
}
}
return NULL;
}
char **find_devices(char *key) {
io_service_t io_reg_err;
io_iterator_t iterator;
int capacity = 10;
char **cards = malloc(capacity * sizeof(char *));
if (!cards) {
fprintf(stderr, "Memory allocation failed\n");
return NULL;
}
io_reg_err = IOServiceGetMatchingServices(
kIOMainPortDefault, IOServiceMatching(IOSERVICE_GPU), &iterator);
if (io_reg_err != KERN_SUCCESS) {
printf("Error getting GPU entry\n");
return NULL;
}
io_object_t service;
int index = 0;
while ((service = IOIteratorNext(iterator)) != MACH_PORT_NULL) {
CFStringRef cfStr = CFStringCreateWithCString(kCFAllocatorDefault, key,
kCFStringEncodingUTF8);
char *result = find_properties(service, 0, cfStr, CFSTR(""));
CFRelease(cfStr);
IOObjectRelease(service);
if (result != NULL) {
if (index >= capacity) {
capacity += 1;
char **new_cards = (char **)realloc(cards, capacity * sizeof(char *));
if (!new_cards) {
fprintf(stderr, "Memory reallocation failed\n");
for (int i = 0; i < index; i++) {
free(cards[i]);
}
free(cards);
free(result);
return NULL;
}
cards = new_cards;
}
cards[index] = result;
index++;
}
if (result == NULL && strcmp(key, "model") == 0) {
IOObjectRelease(iterator);
io_reg_err = IOServiceGetMatchingServices(
kIOMainPortDefault, IOServiceMatching(IOSERVICE_PCI), &iterator);
if (io_reg_err != KERN_SUCCESS) {
printf("Error getting PCI entry\n");
return NULL;
}
}
}
IOObjectRelease(iterator);
char **result_cards = (char **)realloc(cards, sizeof(char *) * (index + 1));
if (!result_cards) {
fprintf(stderr, "Memory reallocation failed\n");
for (int i = 0; i < index; i++) {
free(cards[i]);
}
free(cards);
return NULL;
}
result_cards[index] = NULL;
return result_cards;
}
int find_utilization(char *key, char *dict_key) {
void *result_ptr;
io_service_t io_reg_err;
io_iterator_t iterator;
io_reg_err = IOServiceGetMatchingServices(
kIOMainPortDefault, IOServiceMatching(IOSERVICE_GPU), &iterator);
if (io_reg_err != KERN_SUCCESS) {
printf("Error getting GPU entry\n");
return 0;
}
io_object_t service = IOIteratorNext(iterator);
if (service != MACH_PORT_NULL) {
CFStringRef cfStr = CFStringCreateWithCString(kCFAllocatorDefault, key,
kCFStringEncodingUTF8);
CFStringRef cfDictStr = CFStringCreateWithCString(
kCFAllocatorDefault, dict_key, kCFStringEncodingUTF8);
result_ptr = find_properties(service, 0, cfStr, cfDictStr);
CFRelease(cfStr);
CFRelease(cfDictStr);
}
IOObjectRelease(service);
IOObjectRelease(iterator);
if (result_ptr == NULL) {
return 0;
}
return (int)(intptr_t)result_ptr;
}

View File

@@ -0,0 +1,15 @@
#ifndef __SMC_H__
#define __SMC_H__ 1
#include <IOKit/IOKitLib.h>
#include <CoreFoundation/CoreFoundation.h>
#if (defined __MAC_OS_X_VERSION_MIN_REQUIRED) && (__MAC_OS_X_VERSION_MIN_REQUIRED < 120000)
#define kIOMainPortDefault kIOMasterPortDefault
#endif
void *find_properties(io_registry_entry_t, int, CFStringRef, CFStringRef);
char **find_devices(char *);
int find_utilization(char *, char *);
#endif

View File

@@ -0,0 +1,85 @@
package stat
// Modified from https://github.com/influxdata/telegraf/blob/master/plugins/inputs/nvidia_smi/nvidia_smi.go
// Original License: MIT
import (
"encoding/xml"
"errors"
"os"
"os/exec"
"strconv"
"strings"
)
type NvidiaSMI struct {
BinPath string
}
func (smi *NvidiaSMI) Gather() ([]float64, error) {
data := smi.pollNvidiaSMI()
return smi.parse(data)
}
func (smi *NvidiaSMI) Start() error {
if _, err := os.Stat(smi.BinPath); os.IsNotExist(err) {
binPath, err := exec.LookPath("nvidia-smi")
if err != nil {
return errors.New("Didn't find the adequate tool to query GPU utilization")
}
smi.BinPath = binPath
}
return nil
}
func (smi *NvidiaSMI) pollNvidiaSMI() []byte {
cmd := exec.Command(smi.BinPath,
"-q",
"-x",
)
gs, err := cmd.CombinedOutput()
if err != nil {
return nil
}
return gs
}
func (smi *NvidiaSMI) parse(data []byte) ([]float64, error) {
var s smistat
var percentage []float64
err := xml.Unmarshal(data, &s)
if err != nil {
return nil, err
}
for _, gpu := range s.GPUs {
gp, _ := parsePercentage(gpu.Utilization.GpuUtil)
percentage = append(percentage, gp)
}
return percentage, nil
}
func parsePercentage(p string) (float64, error) {
per := strings.ReplaceAll(p, " ", "")
t := strings.TrimSuffix(per, "%")
value, err := strconv.ParseFloat(t, 64)
if err != nil {
return 0, err
}
return value, nil
}
type nGPU struct {
Utilization struct {
GpuUtil string `xml:"gpu_util"`
} `xml:"utilization"`
}
type smistat struct {
GPUs []nGPU `xml:"gpu"`
}

View File

@@ -0,0 +1,36 @@
//go:build darwin && !cgo
package stat
import (
"os/exec"
"regexp"
"strconv"
)
func extractGPUStat(cmd *exec.Cmd) ([]float64, error) {
gs, err := cmd.CombinedOutput()
if err != nil {
return nil, err
}
re := regexp.MustCompile(`"Device Utilization %"\s*=\s*(\d+)`)
matches := re.FindAllSubmatch(gs, -1)
var u []float64
for _, match := range matches {
if len(match) > 1 {
p, _ := strconv.ParseFloat(string(match[1]), 64)
u = append(u, p)
}
}
return u, nil
}
func GetGPUStat() (float64, error) {
ioreg := exec.Command("ioreg", "-rd1", "-c", "IOAccelerator")
gs, err := extractGPUStat(ioreg)
if err != nil || len(gs) == 0 {
return 0, err
}
return gs[0], nil
}

View File

@@ -0,0 +1,25 @@
//go:build darwin && cgo
package stat
// #cgo LDFLAGS: -framework IOKit -framework CoreFoundation
// #include "gpu_darwin.h"
import "C"
import (
"unsafe"
)
func extractGPUStat(key *C.char, dict_key *C.char) (int, error) {
utilization := C.find_utilization(key, dict_key)
return int(utilization), nil
}
func GetGPUStat() (float64, error) {
key := C.CString("PerformanceStatistics")
dict_key := C.CString("Device Utilization %")
defer C.free(unsafe.Pointer(key))
defer C.free(unsafe.Pointer(dict_key))
gs, _ := extractGPUStat(key, dict_key)
return float64(gs), nil
}

View File

@@ -0,0 +1,7 @@
//go:build freebsd
package stat
func GetGPUStat() (float64, error) {
return 0, nil
}

View File

@@ -0,0 +1,44 @@
//go:build linux
package stat
func getNvidiaStat() ([]float64, error) {
smi := &NvidiaSMI{
BinPath: "/usr/bin/nvidia-smi",
}
err1 := smi.Start()
if err1 != nil {
return nil, err1
}
data, err2 := smi.Gather()
if err2 != nil {
return nil, err2
}
return data, nil
}
func getAMDStat() ([]float64, error) {
rsmi := &ROCmSMI{
BinPath: "/opt/rocm/bin/rocm-smi",
}
err1 := rsmi.Start()
if err1 != nil {
return nil, err1
}
data, err2 := rsmi.Gather()
if err2 != nil {
return nil, err2
}
return data, nil
}
func GetGPUStat() (float64, error) {
gs, err := getNvidiaStat()
if err != nil {
gs, err = getAMDStat()
}
if err != nil || len(gs) == 0 {
return 0, err
}
return gs[0], nil
}

View File

@@ -0,0 +1,151 @@
//go:build windows
// Modified from https://github.com/shirou/gopsutil/blob/master/internal/common/common_windows.go
// Original License: BSD-3-Clause
package stat
import (
"errors"
"fmt"
"time"
"unsafe"
"golang.org/x/sys/windows"
)
const (
ERROR_SUCCESS = 0
PDH_FMT_DOUBLE = 0x00000200
PDH_MORE_DATA = 0x800007d2
PDH_VAILD_DATA = 0x00000000
PDH_NEW_DATA = 0x00000001
PDH_NO_DATA = 0x800007d5
)
var (
modPdh = windows.NewLazySystemDLL("pdh.dll")
pdhOpenQuery = modPdh.NewProc("PdhOpenQuery")
pdhCollectQueryData = modPdh.NewProc("PdhCollectQueryData")
pdhGetFormattedCounterArrayW = modPdh.NewProc("PdhGetFormattedCounterArrayW")
pdhAddEnglishCounterW = modPdh.NewProc("PdhAddEnglishCounterW")
)
type PDH_FMT_COUNTERVALUE_DOUBLE struct {
CStatus uint32
DoubleValue float64
}
type PDH_FMT_COUNTERVALUE_ITEM_DOUBLE struct {
SzName *uint16
FmtValue PDH_FMT_COUNTERVALUE_DOUBLE
}
// https://github.com/influxdata/telegraf/blob/master/plugins/inputs/win_perf_counters/performance_query.go
func getCounterArrayValue(initialBufSize uint32, counter *win32PerformanceCounter) ([]float64, error) {
for buflen := initialBufSize; buflen <= 100*1024*1024; buflen *= 2 {
time.Sleep(10 * time.Millisecond) // GPU 查询必须设置间隔,否则数据不准
s, _, err := pdhCollectQueryData.Call(uintptr(counter.Query))
if s != 0 && err != nil {
if s == PDH_NO_DATA {
return nil, fmt.Errorf("%w: this counter has not data", err)
}
return nil, err
}
buf := make([]byte, buflen)
size := buflen
var itemCount uint32
r, _, _ := pdhGetFormattedCounterArrayW.Call(uintptr(counter.Counter), PDH_FMT_DOUBLE, uintptr(unsafe.Pointer(&size)), uintptr(unsafe.Pointer(&itemCount)), uintptr(unsafe.Pointer(&buf[0])))
if r == ERROR_SUCCESS {
items := (*[1 << 20]PDH_FMT_COUNTERVALUE_ITEM_DOUBLE)(unsafe.Pointer(&buf[0]))[:itemCount:itemCount]
values := make([]float64, 0, itemCount)
for _, item := range items {
if item.FmtValue.CStatus == PDH_VAILD_DATA || item.FmtValue.CStatus == PDH_NEW_DATA {
val := item.FmtValue.DoubleValue
values = append(values, val)
}
}
return values, nil
}
if r != PDH_MORE_DATA {
return nil, fmt.Errorf("pdhGetFormattedCounterArrayW failed with status 0x%X", r)
}
}
return nil, errors.New("buffer limit reached")
}
func createQuery() (windows.Handle, error) {
var query windows.Handle
r, _, err := pdhOpenQuery.Call(0, 0, uintptr(unsafe.Pointer(&query)))
if r != ERROR_SUCCESS {
return 0, fmt.Errorf("pdhOpenQuery failed with status 0x%X: %v", r, err)
}
return query, nil
}
type win32PerformanceCounter struct {
PostName string
CounterName string
Query windows.Handle
Counter windows.Handle
}
func newWin32PerformanceCounter(postName, counterName string) (*win32PerformanceCounter, error) {
query, err := createQuery()
if err != nil {
return nil, err
}
counter := win32PerformanceCounter{
Query: query,
PostName: postName,
CounterName: counterName,
}
r, _, err := pdhAddEnglishCounterW.Call(
uintptr(counter.Query),
uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(counter.CounterName))),
0,
uintptr(unsafe.Pointer(&counter.Counter)),
)
if r != ERROR_SUCCESS {
return nil, fmt.Errorf("pdhAddEnglishCounterW failed with status 0x%X: %v", r, err)
}
return &counter, nil
}
func getValue(initialBufSize uint32, counter *win32PerformanceCounter) ([]float64, error) {
s, _, err := pdhCollectQueryData.Call(uintptr(counter.Query))
if s != 0 && err != nil {
if s == PDH_NO_DATA {
return nil, fmt.Errorf("%w: this counter has not data", err)
}
return nil, err
}
return getCounterArrayValue(initialBufSize, counter)
}
func GetGPUStat() (float64, error) {
counter, err := newWin32PerformanceCounter("gpu_utilization", "\\GPU Engine(*engtype_3D)\\Utilization Percentage")
if err != nil {
return 0, err
}
values, err := getValue(1024, counter)
if err != nil {
return 0, err
}
tot := sumArray(values)
if tot > 100 {
tot = 100
}
return tot, nil
}
func sumArray(arr []float64) float64 {
var sum float64
for _, value := range arr {
sum += value
}
return sum
}

View File

@@ -6,6 +6,7 @@ import (
"github.com/oneclickvirt/basics/model" "github.com/oneclickvirt/basics/model"
"github.com/oneclickvirt/basics/system/utils" "github.com/oneclickvirt/basics/system/utils"
. "github.com/oneclickvirt/defaultset"
) )
var ( var (
@@ -18,16 +19,35 @@ var (
// GetSystemInfo 获取主机硬件信息 // GetSystemInfo 获取主机硬件信息
func GetSystemInfo() *model.SystemInfo { func GetSystemInfo() *model.SystemInfo {
if model.EnableLoger {
InitLogger()
defer Logger.Sync()
}
var ret = &model.SystemInfo{} var ret = &model.SystemInfo{}
var err error
if runtime.GOOS == "darwin" { if runtime.GOOS == "darwin" {
getMacOSInfo() getMacOSInfo()
} }
// 系统信息查询 // 系统信息查询
cpuType, ret.Uptime, ret.Platform, ret.Kernel, ret.Arch, ret.VmType, ret.NatType, ret.TimeZone, _ = getHostInfo() cpuType, ret.Uptime, ret.Platform, ret.Kernel, ret.Arch, ret.VmType, ret.NatType, ret.TimeZone, err = getHostInfo()
if model.EnableLoger {
Logger.Info(err.Error())
}
// CPU信息查询 // CPU信息查询
ret, _ = getCpuInfo(ret, cpuType) ret, err = getCpuInfo(ret, cpuType)
if model.EnableLoger {
Logger.Info(err.Error())
}
// GPU信息查询
ret, err = getGPUInfo(ret)
if model.EnableLoger {
Logger.Info(err.Error())
}
// 硬盘信息查询 // 硬盘信息查询
ret.DiskTotal, ret.DiskUsage, ret.Percentage, ret.BootPath, _ = getDiskInfo() ret.DiskTotal, ret.DiskUsage, ret.Percentage, ret.BootPath, err = getDiskInfo()
if model.EnableLoger {
Logger.Info(err.Error())
}
// 内存信息查询 // 内存信息查询
ret.MemoryTotal, ret.MemoryUsage, ret.SwapTotal, ret.SwapUsage, ret.VirtioBalloon, ret.KSM = getMemoryInfo() ret.MemoryTotal, ret.MemoryUsage, ret.SwapTotal, ret.SwapUsage, ret.VirtioBalloon, ret.KSM = getMemoryInfo()
// 获取负载信息 // 获取负载信息
@@ -52,6 +72,12 @@ func CheckSystemInfo(language string) string {
if ret.CpuCache != "" { if ret.CpuCache != "" {
res += " CPU Cache : " + ret.CpuCache + "\n" res += " CPU Cache : " + ret.CpuCache + "\n"
} }
if ret.GpuModel != "" {
res += " GPU Model : " + ret.GpuModel + "\n"
if ret.GpuStats != "" && ret.GpuStats != "0" {
res += " GPU Stats : " + ret.GpuStats + "\n"
}
}
if runtime.GOOS != "windows" && runtime.GOOS != "macos" { if runtime.GOOS != "windows" && runtime.GOOS != "macos" {
res += " AES-NI : " + ret.CpuAesNi + "\n" res += " AES-NI : " + ret.CpuAesNi + "\n"
} }
@@ -95,6 +121,12 @@ func CheckSystemInfo(language string) string {
if ret.CpuCache != "" { if ret.CpuCache != "" {
res += " CPU 缓存 : " + ret.CpuCache + "\n" res += " CPU 缓存 : " + ret.CpuCache + "\n"
} }
if ret.GpuModel != "" {
res += " GPU 型号 : " + ret.GpuModel + "\n"
if ret.GpuStats != "" && ret.GpuStats != "0" {
res += " GPU 状态 : " + ret.GpuStats + "\n"
}
}
if runtime.GOOS != "windows" && runtime.GOOS != "macos" { if runtime.GOOS != "windows" && runtime.GOOS != "macos" {
res += " AES-NI : " + ret.CpuAesNi + "\n" res += " AES-NI : " + ret.CpuAesNi + "\n"
} }