add more metrics that only appear when a print job is running
This commit is contained in:
		
							
								
								
									
										68
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								main.go
									
									
									
									
									
								
							@@ -7,6 +7,8 @@ import (
 | 
			
		||||
	"io"
 | 
			
		||||
	"log"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/prometheus/client_golang/prometheus"
 | 
			
		||||
@@ -20,6 +22,11 @@ type Metrics struct {
 | 
			
		||||
	ZPosition     float64 `json:"pos_z_mm"`
 | 
			
		||||
	PrintingSpeed int     `json:"printing_speed"`
 | 
			
		||||
	FlowFactor    int     `json:"flow_factor"`
 | 
			
		||||
	Progress      int     `json:"progress"`
 | 
			
		||||
	PrintDur      string  `json:"print_dur"`
 | 
			
		||||
	TimeEst       string  `json:"time_est"`
 | 
			
		||||
	TimeZone      string  `json:"time_zone"`
 | 
			
		||||
	ProjectName   string  `json:"project_name"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Config struct {
 | 
			
		||||
@@ -33,7 +40,7 @@ var (
 | 
			
		||||
	opsFlowFactor = prometheus.NewGauge(prometheus.GaugeOpts{
 | 
			
		||||
		Namespace: "prusa_connect",
 | 
			
		||||
		Name:      "flow_factor",
 | 
			
		||||
		Help:      "Current flow factor, as a percentage",
 | 
			
		||||
		Help:      "Current flow factor, as a unitless number",
 | 
			
		||||
	})
 | 
			
		||||
	opsPrintSpeed = prometheus.NewGauge(prometheus.GaugeOpts{
 | 
			
		||||
		Namespace: "prusa_connect",
 | 
			
		||||
@@ -43,7 +50,7 @@ var (
 | 
			
		||||
	opsZPosition = prometheus.NewGauge(prometheus.GaugeOpts{
 | 
			
		||||
		Namespace: "prusa_connect",
 | 
			
		||||
		Name:      "z_position",
 | 
			
		||||
		Help:      "Depth, in MM, of the Z head",
 | 
			
		||||
		Help:      "Vertical depth, in mm, of the Z head",
 | 
			
		||||
	})
 | 
			
		||||
	opsBed = prometheus.NewGauge(prometheus.GaugeOpts{
 | 
			
		||||
		Namespace: "prusa_connect",
 | 
			
		||||
@@ -55,6 +62,21 @@ var (
 | 
			
		||||
		Name:      "temp_nozzle",
 | 
			
		||||
		Help:      "Temperature, in celsius, of the print nozzle",
 | 
			
		||||
	})
 | 
			
		||||
	opsProgress = prometheus.NewGauge(prometheus.GaugeOpts{
 | 
			
		||||
		Namespace: "prusa_connect",
 | 
			
		||||
		Name:      "progress",
 | 
			
		||||
		Help:      "Current print completeness, as a percentage",
 | 
			
		||||
	})
 | 
			
		||||
	opsDuration = prometheus.NewGauge(prometheus.GaugeOpts{
 | 
			
		||||
		Namespace: "prusa_connect",
 | 
			
		||||
		Name:      "duration",
 | 
			
		||||
		Help:      "Duration of current print job, as seconds since start",
 | 
			
		||||
	})
 | 
			
		||||
	opsRemaining = prometheus.NewGauge(prometheus.GaugeOpts{
 | 
			
		||||
		Namespace: "prusa_connect",
 | 
			
		||||
		Name:      "remaining",
 | 
			
		||||
		Help:      "Estimated remaining time of current print job, as seconds",
 | 
			
		||||
	})
 | 
			
		||||
	errCount = 0
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -109,11 +131,50 @@ func recordMetrics(ctx context.Context, config Config) {
 | 
			
		||||
				opsZPosition.Set(t.ZPosition)
 | 
			
		||||
				opsBed.Set(float64(t.TempBed))
 | 
			
		||||
				opsNozzle.Set(float64(t.TempNozzle))
 | 
			
		||||
				opsProgress.Set(float64(t.Progress))
 | 
			
		||||
				opsDuration.Set(float64(parseDuration(t.PrintDur) / time.Second))
 | 
			
		||||
				estimatedTimeRemaining, err := strconv.ParseFloat(t.TimeEst, 64)
 | 
			
		||||
				if err == nil {
 | 
			
		||||
					opsRemaining.Set(float64(estimatedTimeRemaining))
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// taking a guess on proper parsing here...
 | 
			
		||||
func parseDuration(d string) time.Duration {
 | 
			
		||||
	dur := 0
 | 
			
		||||
	d = strings.TrimSpace(d)
 | 
			
		||||
	number := []rune{}
 | 
			
		||||
	for _, t := range d {
 | 
			
		||||
		switch t {
 | 
			
		||||
		case ' ':
 | 
			
		||||
			continue
 | 
			
		||||
		case '1', '2', '3', '4', '5', '6', '7', '8', '9', '0':
 | 
			
		||||
			number = append(number, t)
 | 
			
		||||
		case 's':
 | 
			
		||||
			i, _ := strconv.Atoi(string(number))
 | 
			
		||||
			dur += i * int(time.Second)
 | 
			
		||||
			number = []rune{}
 | 
			
		||||
		case 'm':
 | 
			
		||||
			i, _ := strconv.Atoi(string(number))
 | 
			
		||||
			dur += (i * int(time.Minute))
 | 
			
		||||
			number = []rune{}
 | 
			
		||||
		case 'h':
 | 
			
		||||
			i, _ := strconv.Atoi(string(number))
 | 
			
		||||
			dur += (i * int(time.Hour))
 | 
			
		||||
			number = []rune{}
 | 
			
		||||
		case 'd':
 | 
			
		||||
			i, _ := strconv.Atoi(string(number))
 | 
			
		||||
			dur += (i * int(time.Hour) * 24)
 | 
			
		||||
			number = []rune{}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	return time.Duration(dur)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	var hostname string
 | 
			
		||||
	flag.StringVar(&hostname, "hostname", "localhost", "Hostname the Prusa Connect API is available at (assumes http)")
 | 
			
		||||
@@ -142,6 +203,9 @@ func main() {
 | 
			
		||||
	r.MustRegister(opsZPosition)
 | 
			
		||||
	r.MustRegister(opsPrintSpeed)
 | 
			
		||||
	r.MustRegister(opsFlowFactor)
 | 
			
		||||
	r.MustRegister(opsProgress)
 | 
			
		||||
	r.MustRegister(opsDuration)
 | 
			
		||||
	r.MustRegister(opsRemaining)
 | 
			
		||||
 | 
			
		||||
	recordMetrics(context.Background(), config)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										24
									
								
								main_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								main_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"testing"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestParseDuration(t *testing.T) {
 | 
			
		||||
	d := parseDuration("     45s")
 | 
			
		||||
	if d != (45 * time.Second) {
 | 
			
		||||
		t.Log(d)
 | 
			
		||||
		t.Fail()
 | 
			
		||||
	}
 | 
			
		||||
	d = parseDuration("   10m 45s")
 | 
			
		||||
	if d != (45*time.Second)+(10*time.Minute) {
 | 
			
		||||
		t.Log(d)
 | 
			
		||||
		t.Fail()
 | 
			
		||||
	}
 | 
			
		||||
	d = parseDuration(" 12h 10m 45s")
 | 
			
		||||
	if d != (12*time.Hour)+(45*time.Second)+(10*time.Minute) {
 | 
			
		||||
		t.Log(d)
 | 
			
		||||
		t.Fail()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user