forked from rivosinc/prometheus-slurm-exporter
-
Notifications
You must be signed in to change notification settings - Fork 0
/
license.go
110 lines (101 loc) · 3.16 KB
/
license.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// SPDX-FileCopyrightText: 2023 Rivos Inc.
//
// SPDX-License-Identifier: Apache-2.0
package main
import (
"encoding/json"
"fmt"
"github.com/prometheus/client_golang/prometheus"
"golang.org/x/exp/slog"
)
type LicenseMetric struct {
LicenseName string `json:"LicenseName"`
Total int `json:"Total"`
Used int `json:"Used"`
Free int `json:"Free"`
Remote bool `json:"Remote"`
Reserved int `json:"Reserved"`
}
type scontrolLicResponse struct {
Meta struct {
SlurmVersion struct {
Version struct {
Major int `json:"major"`
Micro int `json:"micro"`
Minor int `json:"minor"`
} `json:"version"`
Release string `json:"release"`
} `json:"Slurm"`
} `json:"meta"`
Licenses []LicenseMetric `json:"licenses"`
}
func parseLicenseMetrics(licList []byte) ([]LicenseMetric, error) {
lic := new(scontrolLicResponse)
if err := json.Unmarshal(licList, lic); err != nil {
slog.Error(fmt.Sprintf("Unmarshaling license metrics %q", err))
return nil, err
}
return lic.Licenses, nil
}
type LicCollector struct {
fetcher SlurmFetcher
licTotal *prometheus.Desc
licUsed *prometheus.Desc
licFree *prometheus.Desc
licReserved *prometheus.Desc
licScrapeError prometheus.Counter
}
func NewLicCollector(config *Config) *LicCollector {
cliOpts := config.cliOpts
fetcher := NewCliFetcher(cliOpts.lic...)
fetcher.cache = NewAtomicThrottledCache(config.pollLimit)
return &LicCollector{
fetcher: fetcher,
licTotal: prometheus.NewDesc("slurm_lic_total", "slurm license total", []string{"name"}, nil),
licUsed: prometheus.NewDesc("slurm_lic_used", "slurm license used", []string{"name"}, nil),
licFree: prometheus.NewDesc("slurm_lic_free", "slurm license free", []string{"name"}, nil),
licReserved: prometheus.NewDesc("slurm_lic_reserved", "slurm license reserved", []string{"name"}, nil),
licScrapeError: prometheus.NewCounter(prometheus.CounterOpts{
Name: "slurm_lic_scrape_error",
Help: "slurm license scrape error",
}),
}
}
func (lc *LicCollector) Describe(ch chan<- *prometheus.Desc) {
ch <- lc.licTotal
ch <- lc.licUsed
ch <- lc.licFree
ch <- lc.licReserved
ch <- lc.licScrapeError.Desc()
}
func (lc *LicCollector) Collect(ch chan<- prometheus.Metric) {
defer func() {
ch <- lc.licScrapeError
}()
licBytes, err := lc.fetcher.Fetch()
if err != nil {
slog.Error(fmt.Sprintf("fetch error %q", err))
lc.licScrapeError.Inc()
return
}
licMetrics, err := parseLicenseMetrics(licBytes)
if err != nil {
lc.licScrapeError.Inc()
slog.Error(fmt.Sprintf("lic parse error %q", err))
return
}
for _, lic := range licMetrics {
if lic.Total > 0 {
ch <- prometheus.MustNewConstMetric(lc.licTotal, prometheus.GaugeValue, float64(lic.Total), lic.LicenseName)
}
if lic.Free > 0 {
ch <- prometheus.MustNewConstMetric(lc.licFree, prometheus.GaugeValue, float64(lic.Free), lic.LicenseName)
}
if lic.Used > 0 {
ch <- prometheus.MustNewConstMetric(lc.licUsed, prometheus.GaugeValue, float64(lic.Used), lic.LicenseName)
}
if lic.Reserved > 0 {
ch <- prometheus.MustNewConstMetric(lc.licReserved, prometheus.GaugeValue, float64(lic.Reserved), lic.LicenseName)
}
}
}