-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathmain.go
101 lines (86 loc) · 3.33 KB
/
main.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
package main
import (
"flag"
"fmt"
"log"
"net/http"
"os"
"strings"
"time"
"github.com/hetznercloud/hcloud-go/v2/hcloud"
"github.com/jangraefen/hcloud-pricing-exporter/fetcher"
"github.com/jtaczanowski/go-scheduler"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
const (
defaultPort = 8080
defaultFetchInterval = 1 * time.Minute
)
var (
hcloudAPIToken string
port uint
fetchInterval time.Duration
additionalLabelsFlag string
additionalLabels []string
)
func handleFlags() {
flag.StringVar(&hcloudAPIToken, "hcloud-token", "", "the token to authenticate against the HCloud API")
flag.UintVar(&port, "port", defaultPort, "the port that the exporter exposes its data on")
flag.DurationVar(&fetchInterval, "fetch-interval", defaultFetchInterval, "the interval between data fetching cycles")
flag.StringVar(&additionalLabelsFlag, "additional-labels", "", "comma separated additional labels to parse for all metrics, e.g: 'service,environment,owner'")
flag.Parse()
if hcloudAPIToken == "" {
if envHCloudAPIToken, present := os.LookupEnv("HCLOUD_TOKEN"); present {
hcloudAPIToken = envHCloudAPIToken
}
}
if hcloudAPIToken == "" {
panic(fmt.Errorf("no API token for HCloud specified, but required"))
}
if strings.HasPrefix(hcloudAPIToken, "file:") {
hcloudAPITokenBytes, err := os.ReadFile(strings.TrimPrefix(hcloudAPIToken, "file:"))
if err != nil {
panic(fmt.Errorf("failed to read HCLOUD_TOKEN from file: %s", err.Error()))
}
hcloudAPIToken = strings.TrimSpace(string(hcloudAPITokenBytes))
}
if len(hcloudAPIToken) != 64 {
panic(fmt.Errorf("invalid API token for HCloud specified, must be 64 characters long"))
}
additionalLabelsFlag = strings.TrimSpace(strings.ReplaceAll(additionalLabelsFlag, " ", ""))
additionalLabelsSlice := strings.Split(additionalLabelsFlag, ",")
if len(additionalLabelsSlice) > 0 && additionalLabelsSlice[0] != "" {
additionalLabels = additionalLabelsSlice
}
}
func main() {
handleFlags()
client := hcloud.NewClient(hcloud.WithToken(hcloudAPIToken))
priceRepository := &fetcher.PriceProvider{Client: client}
fetchers := fetcher.Fetchers{
fetcher.NewFloatingIP(priceRepository, additionalLabels...),
fetcher.NewPrimaryIP(priceRepository, additionalLabels...),
fetcher.NewLoadbalancer(priceRepository, additionalLabels...),
fetcher.NewLoadbalancerTraffic(priceRepository, additionalLabels...),
fetcher.NewServer(priceRepository, additionalLabels...),
fetcher.NewServerBackup(priceRepository, additionalLabels...),
fetcher.NewServerTraffic(priceRepository, additionalLabels...),
fetcher.NewSnapshot(priceRepository, additionalLabels...),
fetcher.NewVolume(priceRepository, additionalLabels...),
}
fetchers.MustRun(client)
scheduler.RunTaskAtInterval(func() { fetchers.MustRun(client) }, fetchInterval, 0)
scheduler.RunTaskAtInterval(priceRepository.Sync, 10*fetchInterval, 10*fetchInterval)
registry := prometheus.NewRegistry()
fetchers.RegisterCollectors(registry)
http.Handle("/metrics", promhttp.HandlerFor(registry, promhttp.HandlerOpts{}))
log.Printf("Listening on: http://0.0.0.0:%d\n", port)
server := &http.Server{
Addr: fmt.Sprintf(":%d", port),
ReadHeaderTimeout: 10 * time.Second,
}
if err := server.ListenAndServe(); err != nil {
panic(err)
}
}