From bf1af83e3e3369c8ad1495ca24d150a0299513b4 Mon Sep 17 00:00:00 2001 From: Caleb Bassi Date: Tue, 28 May 2019 11:42:40 -0700 Subject: [PATCH 1/3] Fix process localization issues on FreeBSD --- src/utils/conversions.go | 13 +++++++++++++ src/widgets/proc_freebsd.go | 8 ++++---- 2 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 src/utils/conversions.go diff --git a/src/utils/conversions.go b/src/utils/conversions.go new file mode 100644 index 00000000..5d86ac41 --- /dev/null +++ b/src/utils/conversions.go @@ -0,0 +1,13 @@ +package utils + +import ( + "strings" +) + +func ConvertLocalizedString(s string) string { + if strings.ContainsAny(s, ",") { + return strings.Replace(s, ",", ".", 1) + } else { + return s + } +} diff --git a/src/widgets/proc_freebsd.go b/src/widgets/proc_freebsd.go index 96c88331..dc4399bc 100644 --- a/src/widgets/proc_freebsd.go +++ b/src/widgets/proc_freebsd.go @@ -1,5 +1,3 @@ -// +build freebsd - package widgets import ( @@ -9,6 +7,8 @@ import ( "os/exec" "strconv" "strings" + + "github.com/cjbassi/gotop/src/utils" ) type processList struct { @@ -44,11 +44,11 @@ func getProcs() ([]Proc, error) { if err != nil { log.Printf("failed to convert first field to int: %v. split: %v", err, process) } - cpu, err := strconv.ParseFloat(process.Cpu, 64) + cpu, err := strconv.ParseFloat(utils.ConvertLocalizedString(process.Cpu), 32) if err != nil { log.Printf("failed to convert third field to float: %v. split: %v", err, process) } - mem, err := strconv.ParseFloat(process.Mem, 64) + mem, err := strconv.ParseFloat(utils.ConvertLocalizedString(process.Mem), 32) if err != nil { log.Printf("failed to convert fourth field to float: %v. split: %v", err, process) } From 112426c0b2af5d12dde4e093ee21dd3c713df8f3 Mon Sep 17 00:00:00 2001 From: Caleb Bassi Date: Tue, 28 May 2019 11:43:29 -0700 Subject: [PATCH 2/3] Fix issues with swap memory on FreeBSD --- src/widgets/mem.go | 72 +++++++++++++++++++------------------- src/widgets/mem_freebsd.go | 61 ++++++++++++++++++++++++++++++++ src/widgets/mem_other.go | 22 ++++++++++++ 3 files changed, 119 insertions(+), 36 deletions(-) create mode 100644 src/widgets/mem_freebsd.go create mode 100644 src/widgets/mem_other.go diff --git a/src/widgets/mem.go b/src/widgets/mem.go index 03da0d7c..2b5074ca 100644 --- a/src/widgets/mem.go +++ b/src/widgets/mem.go @@ -16,6 +16,38 @@ type MemWidget struct { updateInterval time.Duration } +type MemoryInfo struct { + Total uint64 + Used uint64 + UsedPercent float64 +} + +func (self *MemWidget) renderMemInfo(line string, memoryInfo MemoryInfo) { + self.Data[line] = append(self.Data[line], memoryInfo.UsedPercent) + memoryTotalBytes, memoryTotalMagnitude := utils.ConvertBytes(memoryInfo.Total) + memoryUsedBytes, memoryUsedMagnitude := utils.ConvertBytes(memoryInfo.Used) + self.Labels[line] = fmt.Sprintf("%3.0f%% %5.1f%s/%.0f%s", + memoryInfo.UsedPercent, + memoryUsedBytes, + memoryUsedMagnitude, + memoryTotalBytes, + memoryTotalMagnitude, + ) +} + +func (self *MemWidget) updateMainMemory() { + mainMemory, err := psMem.VirtualMemory() + if err != nil { + log.Printf("failed to get main memory info from gopsutil: %v", err) + } else { + self.renderMemInfo("Main", MemoryInfo{ + Total: mainMemory.Total, + Used: mainMemory.Used, + UsedPercent: mainMemory.UsedPercent, + }) + } +} + func NewMemWidget(updateInterval time.Duration, horizontalScale int) *MemWidget { self := &MemWidget{ LineGraph: ui.NewLineGraph(), @@ -26,49 +58,17 @@ func NewMemWidget(updateInterval time.Duration, horizontalScale int) *MemWidget self.Data["Main"] = []float64{0} self.Data["Swap"] = []float64{0} - self.update() + self.updateMainMemory() + self.updateSwapMemory() go func() { for range time.NewTicker(self.updateInterval).C { self.Lock() - self.update() + self.updateMainMemory() + self.updateSwapMemory() self.Unlock() } }() return self } - -func (self *MemWidget) update() { - mainMemory, err := psMem.VirtualMemory() - if err != nil { - log.Printf("failed to get main memory info from gopsutil: %v", err) - } else { - self.Data["Main"] = append(self.Data["Main"], mainMemory.UsedPercent) - mainMemoryTotalBytes, mainMemoryTotalMagnitude := utils.ConvertBytes(mainMemory.Total) - mainMemoryUsedBytes, mainMemoryUsedMagnitude := utils.ConvertBytes(mainMemory.Used) - self.Labels["Main"] = fmt.Sprintf("%3.0f%% %5.1f%s/%.0f%s", - mainMemory.UsedPercent, - mainMemoryUsedBytes, - mainMemoryUsedMagnitude, - mainMemoryTotalBytes, - mainMemoryTotalMagnitude, - ) - } - - swapMemory, err := psMem.SwapMemory() - if err != nil { - log.Printf("failed to get swap memory info from gopsutil: %v", err) - } else { - self.Data["Swap"] = append(self.Data["Swap"], swapMemory.UsedPercent) - swapMemoryTotalBytes, swapMemoryTotalMagnitude := utils.ConvertBytes(swapMemory.Total) - swapMemoryUsedBytes, swapMemoryUsedMagnitude := utils.ConvertBytes(swapMemory.Used) - self.Labels["Swap"] = fmt.Sprintf("%3.0f%% %5.1f%s/%.0f%s", - swapMemory.UsedPercent, - swapMemoryUsedBytes, - swapMemoryUsedMagnitude, - swapMemoryTotalBytes, - swapMemoryTotalMagnitude, - ) - } -} diff --git a/src/widgets/mem_freebsd.go b/src/widgets/mem_freebsd.go new file mode 100644 index 00000000..b3773c9e --- /dev/null +++ b/src/widgets/mem_freebsd.go @@ -0,0 +1,61 @@ +package widgets + +import ( + "fmt" + "log" + "os/exec" + "strconv" + "strings" + + "github.com/cjbassi/gotop/src/utils" +) + +func convert(s []string) (MemoryInfo, error) { + total, err := strconv.ParseUint(s[0], 10, 64) + if err != nil { + return MemoryInfo{}, fmt.Errorf("int converion failed %v", err) + } + + used, err := strconv.ParseUint(s[1], 10, 64) + if err != nil { + return MemoryInfo{}, fmt.Errorf("int converion failed %v", err) + } + + percentage, err := strconv.ParseFloat(strings.TrimSuffix(s[2], "%"), 64) + if err != nil { + return MemoryInfo{}, fmt.Errorf("float converion failed %v", err) + } + + return MemoryInfo{ + Total: total * utils.KB, + Used: used * utils.KB, + UsedPercent: percentage, + }, nil +} + +func gatherSwapInfo() (MemoryInfo, error) { + cmd := "swapinfo -k|sed -n '1!p'|awk '{print $2,$3,$5}'" + output, err := exec.Command("sh", "-c", cmd).Output() + if err != nil { + if err != nil { + return MemoryInfo{}, fmt.Errorf("command failed %v", err) + } + } + + ss := strings.Split(strings.TrimSuffix(string(output), "\n"), " ") + + return convert(ss) +} + +func (self *MemWidget) updateSwapMemory() { + swapMemory, err := gatherSwapInfo() + if err != nil { + log.Printf("failed to get swap memory info from gopsutil: %v", err) + } else { + self.renderMemInfo("Swap", MemoryInfo{ + Total: swapMemory.Total, + Used: swapMemory.Used, + UsedPercent: swapMemory.UsedPercent, + }) + } +} diff --git a/src/widgets/mem_other.go b/src/widgets/mem_other.go new file mode 100644 index 00000000..6b78acb5 --- /dev/null +++ b/src/widgets/mem_other.go @@ -0,0 +1,22 @@ +// +build !freebsd + +package widgets + +import ( + "log" + + psMem "github.com/shirou/gopsutil/mem" +) + +func (self *MemWidget) updateSwapMemory() { + swapMemory, err := psMem.SwapMemory() + if err != nil { + log.Printf("failed to get swap memory info from gopsutil: %v", err) + } else { + self.renderMemInfo("Swap", MemoryInfo{ + Total: swapMemory.Total, + Used: swapMemory.Used, + UsedPercent: swapMemory.UsedPercent, + }) + } +} From cfd277c33a6ae804ff94fde34bc9985100949b43 Mon Sep 17 00:00:00 2001 From: Caleb Bassi Date: Tue, 28 May 2019 11:43:47 -0700 Subject: [PATCH 3/3] Fix temperatures on FreeBSD --- src/widgets/temp_freebsd.go | 71 ++++++++++++++++++++ src/widgets/{temp_other.go => temp_linux.go} | 2 - 2 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 src/widgets/temp_freebsd.go rename src/widgets/{temp_other.go => temp_linux.go} (96%) diff --git a/src/widgets/temp_freebsd.go b/src/widgets/temp_freebsd.go new file mode 100644 index 00000000..29901236 --- /dev/null +++ b/src/widgets/temp_freebsd.go @@ -0,0 +1,71 @@ +package widgets + +import ( + "fmt" + "log" + "os/exec" + "strconv" + "strings" + + "github.com/cjbassi/gotop/src/utils" +) + +var sensorOIDS = map[string]string{ + "dev.cpu.0.temperature": "CPU 0 ", + "hw.acpi.thermal.tz0.temperature": "Thermal zone 0", +} + +type sensorMeasurement struct { + name string + temperature float64 +} + +func removeUnusedChars(s string) string { + s1 := strings.Replace(s, "C", "", 1) + s2 := strings.TrimSuffix(s1, "\n") + return s2 +} + +func refineOutput(output []byte) (float64, error) { + convertedOutput := utils.ConvertLocalizedString(removeUnusedChars(string(output))) + value, err := strconv.ParseFloat(convertedOutput, 64) + if err != nil { + return 0, err + } + return value, nil +} + +func collectSensors() ([]sensorMeasurement, error) { + var measurements []sensorMeasurement + for k, v := range sensorOIDS { + output, err := exec.Command("sysctl", "-n", k).Output() + if err != nil { + return nil, fmt.Errorf("failed to execute 'sysctl' command: %v", err) + } + + value, err := refineOutput(output) + if err != nil { + return nil, fmt.Errorf("failed to execute 'sysctl' command: %v", err) + } + + measurements = append(measurements, sensorMeasurement{v, value}) + + } + return measurements, nil + +} + +func (self *TempWidget) update() { + sensors, err := collectSensors() + if err != nil { + log.Printf("error recieved from gopsutil: %v", err) + } + for _, sensor := range sensors { + switch self.TempScale { + case Fahrenheit: + self.Data[sensor.name] = utils.CelsiusToFahrenheit(int(sensor.temperature)) + case Celcius: + self.Data[sensor.name] = int(sensor.temperature) + } + } +} diff --git a/src/widgets/temp_other.go b/src/widgets/temp_linux.go similarity index 96% rename from src/widgets/temp_other.go rename to src/widgets/temp_linux.go index 47b37cfa..6901b6bc 100644 --- a/src/widgets/temp_other.go +++ b/src/widgets/temp_linux.go @@ -1,5 +1,3 @@ -// +build linux freebsd - package widgets import (