Skip to content

Commit

Permalink
feat(attributes): add proc status and mem info for linux (#25)
Browse files Browse the repository at this point in the history
During report creation, we need to generate information about current
process state - for example: memory information

On Linux - we have a really nice way to get those attributes. We should
read /proc/meminfo and /proc/self/status to get information about the
process. Next we need to convert data from the file into attributes
  • Loading branch information
MateuszKepczynskiSauce authored Nov 28, 2024
1 parent 7771f60 commit 1164657
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 3 deletions.
10 changes: 7 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 '\"'"}
)

Expand Down Expand Up @@ -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.
Expand Down
108 changes: 108 additions & 0 deletions procmeminfo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package bt

import (
"bufio"
"fmt"
"io"
"log"
"os"
"strconv"
"strings"
)

const (
memPath = "/proc/meminfo"
procPath = "/proc/self/status"
)

var (
paths = []string{memPath, procPath}
mapper = 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",
"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() {
for _, path := range paths {
readFile(path)
}
}

func readFile(path string) {
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 {
if attr, exists := mapper[values[0]]; exists {
value, err := getValue(values[1])
if err != nil {
continue
}
Options.Attributes[attr] = value
}
}
}
}

func getValue(value string) (string, error) {
value = strings.TrimSpace(value)
if strings.HasSuffix(value, "kB") {
value = strings.TrimSuffix(value, " kB")

atoi, err := strconv.ParseInt(value, 10, 64)
if err != nil && Options.DebugBacktrace {
log.Printf("readFile err: %v", err)
return "", err
}
atoi *= 1024
return fmt.Sprintf("%d", atoi), err
}

return value, nil
}

0 comments on commit 1164657

Please sign in to comment.