Skip to content

Instantly share code, notes, and snippets.

@BobBurns
Created February 23, 2021 19:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BobBurns/7569e34ed090b459a569c54e58b2a4ee to your computer and use it in GitHub Desktop.
Save BobBurns/7569e34ed090b459a569c54e58b2a4ee to your computer and use it in GitHub Desktop.
prometheus-disk-usage-exporter
package main
import (
"fmt"
"log"
"os/exec"
"bufio"
"strings"
"strconv"
"net/http"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var (
diskSize = prometheus.NewGauge(prometheus.GaugeOpts{
Name: "disk_size_devadap1",
Help: "disk size first partition",
ConstLabels: prometheus.Labels{"version": "1234"},
})
diskAvail = prometheus.NewGauge(prometheus.GaugeOpts{
Name: "disk_avail_devadap1",
Help: "disk avail first partition",
ConstLabels: prometheus.Labels{"version": "1234"},
})
diskUsed = prometheus.NewGauge(prometheus.GaugeOpts{
Name: "disk_used_devadap1",
Help: "disk used first partition",
ConstLabels: prometheus.Labels{"version": "1234"},
})
diskCap = prometheus.NewGauge(prometheus.GaugeOpts{
Name: "disk_cap_devadap1",
Help: "disk capacity first partition",
ConstLabels: prometheus.Labels{"version": "1234"},
})
)
const (
gb = 1024.0 * 1024
debug = 0
)
func init() {
prometheus.MustRegister(diskSize)
prometheus.MustRegister(diskAvail)
prometheus.MustRegister(diskUsed)
prometheus.MustRegister(diskCap)
}
type Disk struct {
FileSystem string
Size float64
Used float64
Available float64
Capacity float64
MountedOn string
}
func checkerr(err error) {
if err != nil {
log.Fatal(err)
}
}
func getDiskMetrics() (disks []Disk) {
disks = make([]Disk, 10)
cmd := exec.Command("df", "-k")
// cmd.Stdin = strings.NewReader("some input")
// var out bytes.Buffer
// cmd.Stdout = &out
out, err := cmd.StdoutPipe()
if err != nil {
panic(err)
}
err = cmd.Start()
if err != nil {
log.Fatal(err)
}
scanner := bufio.NewScanner(out)
entry :=0
for scanner.Scan() {
fields := strings.Fields(scanner.Text())
fmt.Println(fields)
if entry==0 && fields[1] != "1024-blocks" {
log.Fatal("wrong Size field")
} else if entry>0 {
s, err := strconv.ParseFloat(fields[1], 64)
checkerr(err)
u, err := strconv.ParseFloat(fields[2], 64)
checkerr(err)
a, err := strconv.ParseFloat(fields[3], 64)
checkerr(err)
disks[entry] = Disk{
FileSystem: fields[0],
Size: s,
Used: u,
Available: a,
Capacity: (u/(a+u)),
MountedOn: fields[5],
}
}
entry++
}
err = cmd.Wait()
if err != nil {
panic(err)
}
if debug == 1 {
for i:=1;i<entry;i++ {
fmt.Printf("Filesystem: %s Size: %4.2f Used: %4.2f Avail: %4.2f Cap: %4.2f%%\n", disks[i].FileSystem, disks[i].Size/gb, disks[i].Used/gb, disks[1].Available/gb, disks[i].Capacity*100)
}
}
return
}
/*
Filesystem Size Used Avail Capacity Mounted on
/dev/da0s1a 46G 7.8G 34G 19% /
devfs 1.0K 1.0K 0B 100% /dev
*/
func main() {
go func() {
for {
d := getDiskMetrics()
diskSize.Set(d[1].Size/gb)
diskUsed.Set(d[1].Used/gb)
diskAvail.Set(d[1].Available/gb)
diskCap.Set(d[1].Capacity*100)
time.Sleep(30 * time.Second)
}
}()
http.Handle("/metrics", promhttp.Handler())
http.ListenAndServe(":8080", nil)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment