--- /dev/null
+package main
+
+import (
+ "bufio"
+ "flag"
+ "fmt"
+ "log"
+ "os"
+ "os/exec"
+ "strconv"
+ "strings"
+ "time"
+)
+
+var (
+ MyPID string = strconv.Itoa(os.Getpid())
+ CPU string = "?"
+ Mem string = "?"
+ ARC string = "?"
+ Swap string = "?"
+ Flags string = "?"
+ IOs string = "?"
+ Net string = "?"
+ N string = "?"
+)
+
+func piper(c chan []string, name string, args ...string) error {
+ cmd := exec.Command(name, args...)
+ r, err := cmd.StdoutPipe()
+ if err != nil {
+ return err
+ }
+ err = cmd.Start()
+ if err != nil {
+ return err
+ }
+ scanner := bufio.NewScanner(r)
+ for scanner.Scan() {
+ cols := strings.Fields(scanner.Text())
+ if len(cols) > 0 {
+ c <- cols
+ }
+ }
+ if err = scanner.Err(); err != nil {
+ cmd.Process.Kill()
+ cmd.Wait()
+ return err
+ }
+ return nil
+}
+
+func bg(cmd string, args ...string) chan []string {
+ c := make(chan []string)
+ go func() {
+ for {
+ err := piper(c, cmd, args...)
+ if err != nil {
+ log.Println("error:", cmd, ":", err)
+ }
+ time.Sleep(time.Second)
+ }
+ }()
+ return c
+}
+
+func top() {
+ for cols := range bg("top", "-b", "-d", "infinity", "-p", MyPID, "-s", "5", "infinity") {
+ switch cols[0] {
+ case "CPU:":
+ CPU = strings.ReplaceAll(
+ strings.Join([]string{cols[1], cols[5], cols[7]}, " "),
+ "%", "",
+ )
+ case "Mem:":
+ Mem = strings.ReplaceAll(strings.Join(cols[1:], " "), ",", "")
+ case "ARC:":
+ ARC = cols[1]
+ case "Swap:":
+ if cols[4] == "Used," {
+ Swap = cols[3] + " "
+ } else {
+ Swap = ""
+ }
+ }
+ }
+}
+
+func iostat(devs ...string) {
+ stats := make([]string, len(devs)*4)
+ for i := 0; i < len(devs); i++ {
+ stats[i*4+1] = "/"
+ stats[i*4+3] = " "
+ }
+ stats = stats[:len(stats)-1]
+ for cols := range bg("iostat", append([]string{"-d", "-w", N, "-x"}, devs...)...) {
+ for i, dev := range devs {
+ if cols[0] == dev {
+ stats[i*4+0] = cols[1]
+ stats[i*4+2] = cols[2]
+ IOs = strings.Join(stats, "")
+ }
+ }
+ }
+}
+
+func netstat() {
+ stats := []string{"0", "0"}
+ for cols := range bg("netstat", "-n", N) {
+ if _, err := strconv.Atoi(cols[0]); err == nil {
+ stats[0] = cols[0]
+ stats[1] = cols[4]
+ Net = strings.Join(stats, "/")
+ }
+ }
+}
+
+func flagfiles() {
+ ents, err := os.ReadDir("/tmp/stargrave-flags")
+ if err != nil {
+ log.Println(err)
+ return
+ }
+ fs := make([]string, 0, len(ents))
+ for _, ent := range ents {
+ fs = append(fs, ent.Name())
+ }
+ Flags = strings.Join(fs, " ")
+}
+
+func main() {
+ xsetroot := flag.Bool("xsetroot", false, "Call xsetroot")
+ iodevs := flag.String("iodevs", "ada0 ada1", "iostat devices")
+ refresh := flag.Uint("refresh", 2, "Refresh interval")
+ flag.Parse()
+ N = strconv.Itoa(int(*refresh))
+ go func() {
+ for {
+ flagfiles()
+ time.Sleep(20 * time.Second)
+ }
+ }()
+ go top()
+ go iostat(strings.Split(*iodevs, " ")...)
+ go netstat()
+ var now time.Time
+ var status string
+ var cmd *exec.Cmd
+ for {
+ now = time.Now()
+ status = fmt.Sprintf(
+ "[IO %s] [Net %s] [CPU %s] [%sMem %s ARC %s] [%s] %s",
+ IOs, Net, CPU, Swap, Mem, ARC, Flags,
+ now.Format("2006-01-02 15:04:05"),
+ )
+ if *xsetroot {
+ cmd = exec.Command("xsetroot", "-name", status)
+ cmd.Run()
+ } else {
+ fmt.Println(status)
+ }
+ time.Sleep(time.Duration(*refresh) * time.Second)
+ }
+}