131 lines
3.4 KiB
Go
131 lines
3.4 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"flag"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
|
)
|
|
|
|
type Metrics struct {
|
|
TempNozzle int `json:"temp_nozzle"`
|
|
TempBed int `json:"temp_bed"`
|
|
Material string `json:"material"`
|
|
ZPosition float64 `json:"pos_z_mm"`
|
|
PrintingSpeed int `json:"printing_speed"`
|
|
FlowFactor int `json:"flow_factor"`
|
|
}
|
|
|
|
type Config struct {
|
|
QueryHostname string
|
|
QueryInterval int
|
|
Port string
|
|
Path string
|
|
}
|
|
|
|
var (
|
|
opsFlowFactor = prometheus.NewGauge(prometheus.GaugeOpts{
|
|
Namespace: "prusa_connect",
|
|
Name: "flow_factor",
|
|
Help: "Current flow factor, as a percentage",
|
|
})
|
|
opsPrintSpeed = prometheus.NewGauge(prometheus.GaugeOpts{
|
|
Namespace: "prusa_connect",
|
|
Name: "printing_speed",
|
|
Help: "Current print speed, as a percentage",
|
|
})
|
|
opsZPosition = prometheus.NewGauge(prometheus.GaugeOpts{
|
|
Namespace: "prusa_connect",
|
|
Name: "z_position",
|
|
Help: "Depth, in MM, of the Z head",
|
|
})
|
|
opsBed = prometheus.NewGauge(prometheus.GaugeOpts{
|
|
Namespace: "prusa_connect",
|
|
Name: "temp_bed",
|
|
Help: "Temperature, in celsius, of the print bed",
|
|
})
|
|
opsNozzle = prometheus.NewGauge(prometheus.GaugeOpts{
|
|
Namespace: "prusa_connect",
|
|
Name: "temp_nozzle",
|
|
Help: "Temperature, in celsius, of the print nozzle",
|
|
})
|
|
)
|
|
|
|
func recordMetrics(ctx context.Context, config Config) {
|
|
go func() {
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
log.Print("exiting!")
|
|
return
|
|
default:
|
|
time.Sleep(time.Second * time.Duration(config.QueryInterval))
|
|
res, err := http.Get(config.QueryHostname + "/api/telemetry")
|
|
if err != nil {
|
|
log.Printf("error retrieving telemetry: %v", err)
|
|
break
|
|
}
|
|
b, err := io.ReadAll(res.Body)
|
|
if err != nil {
|
|
log.Printf("error retrieving telemetry: %v", err)
|
|
break
|
|
}
|
|
t := &Metrics{}
|
|
err = json.Unmarshal(b, t)
|
|
if err != nil {
|
|
log.Printf("error parsing telemetry: %v", err)
|
|
break
|
|
}
|
|
opsFlowFactor.Set(float64(t.FlowFactor))
|
|
opsPrintSpeed.Set(float64(t.PrintingSpeed))
|
|
opsZPosition.Set(t.ZPosition)
|
|
opsBed.Set(float64(t.TempBed))
|
|
opsNozzle.Set(float64(t.TempNozzle))
|
|
}
|
|
}
|
|
}()
|
|
}
|
|
|
|
func main() {
|
|
var hostname string
|
|
flag.StringVar(&hostname, "hostname", "localhost", "Hostname the Prusa Connect API is available at (assumes http)")
|
|
var queryInterval int
|
|
flag.IntVar(&queryInterval, "interval", 2, "How often, in seconds, to query the API")
|
|
var port string
|
|
flag.StringVar(&port, "port", "2112", "Local port to export metrics on")
|
|
var path string
|
|
flag.StringVar(&path, "path", "metrics", "Local path to export metrics on")
|
|
flag.Parse()
|
|
|
|
if queryInterval < 1 {
|
|
log.Fatalf("query interval must be greater than 0; %d received", queryInterval)
|
|
}
|
|
|
|
config := Config{
|
|
QueryHostname: "http://" + hostname,
|
|
QueryInterval: queryInterval,
|
|
Port: port,
|
|
Path: path,
|
|
}
|
|
|
|
r := prometheus.NewRegistry()
|
|
r.MustRegister(opsNozzle)
|
|
r.MustRegister(opsBed)
|
|
r.MustRegister(opsZPosition)
|
|
r.MustRegister(opsPrintSpeed)
|
|
r.MustRegister(opsFlowFactor)
|
|
|
|
recordMetrics(context.Background(), config)
|
|
|
|
log.Printf("starting exporter on :%v", config.Port)
|
|
|
|
http.Handle("/"+config.Path, promhttp.HandlerFor(r, promhttp.HandlerOpts{}))
|
|
http.ListenAndServe(":"+config.Port, nil)
|
|
}
|