mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-09-15 21:00:27 +00:00
93 lines
2.0 KiB
Go
93 lines
2.0 KiB
Go
package powerreport
|
|
|
|
import (
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
func readSystemUsage() systemUsage {
|
|
var rusage unix.Rusage
|
|
err := unix.Getrusage(unix.RUSAGE_SELF, &rusage)
|
|
if err != nil {
|
|
return systemUsage{}
|
|
}
|
|
return systemUsage{
|
|
valid: true,
|
|
userTime: rusage.Utime.Nano(),
|
|
systemTime: rusage.Stime.Nano(),
|
|
diskBytesWritten: readWriteBytes(),
|
|
}
|
|
}
|
|
|
|
func readWriteBytes() uint64 {
|
|
content, err := os.ReadFile("/proc/self/io")
|
|
if err != nil {
|
|
return 0
|
|
}
|
|
for line := range strings.SplitSeq(string(content), "\n") {
|
|
value, found := strings.CutPrefix(line, "write_bytes: ")
|
|
if !found {
|
|
continue
|
|
}
|
|
parsed, parseErr := strconv.ParseUint(value, 10, 64)
|
|
if parseErr != nil {
|
|
return 0
|
|
}
|
|
return parsed
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func readClocks() (absoluteTime int64, continuousTime int64) {
|
|
var monotonicTime unix.Timespec
|
|
err := unix.ClockGettime(unix.CLOCK_MONOTONIC, &monotonicTime)
|
|
if err != nil {
|
|
return 0, 0
|
|
}
|
|
var bootTime unix.Timespec
|
|
err = unix.ClockGettime(unix.CLOCK_BOOTTIME, &bootTime)
|
|
if err != nil {
|
|
return 0, 0
|
|
}
|
|
return monotonicTime.Nano(), bootTime.Nano()
|
|
}
|
|
|
|
func readInterfaceCounters() map[string]interfaceCounters {
|
|
content, err := os.ReadFile("/proc/net/dev")
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
lines := strings.Split(string(content), "\n")
|
|
if len(lines) <= 2 {
|
|
return nil
|
|
}
|
|
result := make(map[string]interfaceCounters)
|
|
for _, line := range lines[2:] {
|
|
name, counters, found := strings.Cut(line, ":")
|
|
if !found {
|
|
continue
|
|
}
|
|
name = strings.TrimSpace(name)
|
|
if name == "lo" || strings.HasPrefix(name, "tun") || strings.HasPrefix(name, "utun") || strings.HasPrefix(name, "dummy") {
|
|
continue
|
|
}
|
|
fields := strings.Fields(counters)
|
|
if len(fields) < 10 {
|
|
continue
|
|
}
|
|
inPackets, inErr := strconv.ParseUint(fields[1], 10, 64)
|
|
outPackets, outErr := strconv.ParseUint(fields[9], 10, 64)
|
|
if inErr != nil || outErr != nil {
|
|
continue
|
|
}
|
|
result[name] = interfaceCounters{
|
|
inPackets: uint32(inPackets),
|
|
outPackets: uint32(outPackets),
|
|
}
|
|
}
|
|
return result
|
|
}
|