main.go (2046B)
1 package main 2 3 import ( 4 "bufio" 5 "flag" 6 "fmt" 7 "log" 8 "net/http" 9 "os" 10 "os/exec" 11 "strconv" 12 "strings" 13 ) 14 15 type metric struct { 16 name string 17 value float64 18 } 19 20 var ( 21 Version string 22 Build string 23 ups *string 24 ) 25 26 func getMetrics(w http.ResponseWriter, r *http.Request) { 27 var message string 28 29 cmd := exec.Command("upsc", *ups) 30 stdout, err := cmd.StdoutPipe() 31 if err != nil { 32 message = "error piping stdout" 33 log.Println(message) 34 http.Error(w, message, http.StatusInternalServerError) 35 return 36 } 37 if err := cmd.Start(); err != nil { 38 message = "error executing command" 39 log.Println(message) 40 http.Error(w, message, http.StatusInternalServerError) 41 return 42 } 43 44 metrics := []metric{} 45 scanner := bufio.NewScanner(stdout) 46 for scanner.Scan() { 47 parts := strings.Split(scanner.Text(), ": ") 48 var value float64 = -1 49 50 // if we can conver to float assign a value 51 // if not, just check for ups status (OL || OB) 52 i, err := strconv.ParseFloat(parts[1], 64) 53 if err != nil { 54 if parts[1] == "OL" { 55 value = 0 56 } 57 if parts[1] == "OB" { 58 value = 1 59 } 60 } else { 61 value = i 62 } 63 64 // discard everything else (also, do not need driver info). 65 if value >= 0 && !strings.HasPrefix(parts[0], "driver") { 66 metrics = append(metrics, metric{name: parts[0], value: value}) 67 } 68 } 69 if err := scanner.Err(); err != nil { 70 message = "error scanning command output" 71 log.Println(message) 72 http.Error(w, message, http.StatusInternalServerError) 73 return 74 } 75 76 for _, m := range metrics { 77 fmt.Fprintf(w, "upsc_%s %.2f\n", strings.ReplaceAll(m.name, ".", "_"), m.value) 78 } 79 cmd.Wait() // needed to close the pipe and release the child process 80 } 81 82 func main() { 83 ups = flag.String("ups", "ups@localhost", "ups to get info from") 84 ver := flag.Bool("v", false, "Shows version and exists") 85 port := flag.Int("p", 8081, "Port to listen to") 86 flag.Parse() 87 88 if *ver { 89 fmt.Printf("%s (%s)\n", Version, Build) 90 os.Exit(0) 91 } 92 93 http.HandleFunc("/metrics", getMetrics) 94 log.Fatal(http.ListenAndServe(":"+strconv.Itoa(*port), nil)) 95 }