From d47eedd8015741fb2cad83001a21c9db18d2edfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20K=C4=99pczy=C5=84ski?= Date: Thu, 28 Nov 2024 10:54:30 +0100 Subject: [PATCH] feat(attributes): add proc status and mem info for linux --- main.go | 10 +++-- procmeminfo.go | 104 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 procmeminfo.go diff --git a/main.go b/main.go index 2b76324..ff52ad5 100644 --- a/main.go +++ b/main.go @@ -32,15 +32,15 @@ var ( windowsGUIDCommand = []string{"reg", "query", "\"HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Cryptography\"", "/v", "MachineGuid"} linuxGUIDCommand = []string{"sh", "-c", "( cat /var/lib/dbus/machine-id /etc/machine-id 2> /dev/null || hostname ) | head -n 1 || :"} freebsdGUIDCommand = []string{"sh", "-c", "kenv -q smbios.system.uuid || sysctl -n kern.hostuuid"} - darwinGUIDCommand = []string{"sh", "-c", "ioreg -rd1 -c IOPlatformExpertDevice | grep IOPlatformUUID | awk -F'= \"' '{print $2}' | tr -d '\"'"} + darwinGUIDCommand = []string{"sh", "-c", "ioreg -rd1 -c IOPlatformExpertDevice | grep IOPlatformUUID | awk -F'= \"' '{print $2}' | tr -d '\"' | tr -d '\n'"} windowsCPUCommand = []string{"wmic", "CPU", "get", "NAME"} linuxCPUCommand = []string{"sh", "-c", "lscpu | grep \"Model name\" | awk -F':' '{print $2}' | sed 's/^[[:space:]]*//'"} - darwinCPUCommand = []string{"sh", "-c", "sysctl -n machdep.cpu.brand_string"} + darwinCPUCommand = []string{"sh", "-c", "sysctl -n machdep.cpu.brand_string | tr -d '\n'"} freebsdCPUCommand = []string{"sh", "-c", "sysctl -n hw.model"} linuxOSVersionCommand = []string{"sh", "-c", "cat /etc/os-release | grep VERSION= | awk -F'=\"' '{print $2}' | tr -d '\"'"} - darwinOSVersionCommand = []string{"sh", "-c", "sw_vers | grep ProductVersion | awk -F':' '{print $2}' | tr -d '\t'"} + darwinOSVersionCommand = []string{"sh", "-c", "sw_vers | grep ProductVersion | awk -F':' '{print $2}' | tr -d '\t' | tr -d '\n'"} freebsdOSVersionCommand = []string{"sh", "-c", "cat /etc/os-release | grep VERSION= | awk -F'=\"' '{print $2}' | tr -d '\"'"} ) @@ -370,6 +370,10 @@ func processAndSend(payload *reportPayload) { report["sourceCode"] = sourceCode report["classifiers"] = []string{payload.classifier} + if runtime.GOOS == "linux" { + readMemProcInfo() + } + fullUrl := Options.Endpoint if len(Options.Token) != 0 { // if token is set that means its old URL. diff --git a/procmeminfo.go b/procmeminfo.go new file mode 100644 index 0000000..22dd52f --- /dev/null +++ b/procmeminfo.go @@ -0,0 +1,104 @@ +package bt + +import ( + "bufio" + "io" + "log" + "os" + "strings" +) + +const ( + memPath = "/proc/meminfo" + procPath = "/proc/self/status" +) + +var ( + paths = []string{memPath, procPath} + memMap = map[string]string{ + "MemTotal": "system.memory.total", + "MemFree": "system.memory.free", + "MemAvailable": "system.memory.available", + "Buffers": "system.memory.buffers", + "Cached": "system.memory.cached", + "SwapCached": "system.memory.swap.cached", + "Active": "system.memory.active", + "Inactive": "system.memory.inactive", + "SwapTotal": "system.memory.swap.total", + "SwapFree": "system.memory.swap.free", + "Dirty": "system.memory.dirty", + "Writeback": "system.memory.writeback", + "Slab": "system.memory.slab", + "VmallocTotal": "system.memory.vmalloc.total", + "VmallocUsed": "system.memory.vmalloc.used", + "VmallocChunk": "system.memory.vmalloc.chunk", + } + + procMap = map[string]string{ + "nonvoluntary_ctxt_switches": " sched.cs.involuntary", + "voluntary_ctxt_switches": "sched.cs.voluntary", + "FDSize": "descriptor.count", + "VmData": "vm.data.size", + "VmLck": "vm.locked.size", + "VmPTE": "vm.pte.size", + "VmHWM": "vm.rss.peak", + "VmRSS": "vm.rss.size", + "VmLib": "vm.shared.size", + "VmStk": "vm.stack.size", + "VmSwap": "vm.swap.size", + "VmPeak": "vm.vma.peak", + "VmSize": "vm.vma.size", + } +) + +func readMemProcInfo() { + done := make(chan bool, 2) + for _, path := range paths { + go readFile(path, done) + } + + // wait for readFile to finish + for i := 0; i < 2; i++ { + <-done + } +} + +func readFile(path string, done chan bool) { + file, err := os.Open(path) + if err != nil { + log.Fatal(err) + } + defer file.Close() + + reader := bufio.NewReader(file) + for { + l, _, err := reader.ReadLine() + if err != nil { + if err == io.EOF { + break + } else { + if Options.DebugBacktrace { + log.Printf("readFile err: %v", err) + } + break + } + } + + values := strings.Split(string(l), ":") + if len(values) == 2 { + trimmedValue := strings.TrimSpace(values[1]) + if path == memPath { + mapValues(values[0], trimmedValue, memMap) + } else { + mapValues(values[0], trimmedValue, procMap) + } + } + } + done <- true +} + +func mapValues(key string, value string, mapper map[string]string) { + if attr, exists := mapper[key]; exists { + Options.Attributes[attr] = value + } +}