forked from RobustPerception/azure_metrics_exporter
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
114 lines (99 loc) · 3.47 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
102
103
104
105
106
107
108
109
110
111
112
113
114
package main
import (
"log"
"net/http"
"os"
"strings"
"github.com/conorbro/azure-metrics-exporter/config"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/prometheus/common/version"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
var (
sc = &config.SafeConfig{
C: &config.Config{},
}
ac = NewAzureClient()
configFile = kingpin.Flag("config.file", "Azure exporter configuration file.").Default("azure.yml").String()
listenAddress = kingpin.Flag("web.listen-address", "The address to listen on for HTTP requests.").Default(":9276").String()
listMetricDefinitions = kingpin.Flag("list.definitions", "Whether or not to list available metric definitions for the given resources.").Bool()
)
func init() {
prometheus.MustRegister(version.NewCollector("azure_exporter"))
}
// Collector generic collector type
type Collector struct{}
// Describe implemented with dummy data to satisfy interface.
func (c *Collector) Describe(ch chan<- *prometheus.Desc) {
ch <- prometheus.NewDesc("dummy", "dummy", nil, nil)
}
// Collect - collect results from Azure Montior API and create Prometheus metrics.
func (c *Collector) Collect(ch chan<- prometheus.Metric) {
// Get metric values for all defined metrics
var metricValueData AzureMetricValueResponse
for _, target := range sc.C.Targets {
for _, metric := range target.Metrics {
metricValueData = ac.getMetricValue(metric.Name, target.Resource)
if metricValueData.Value == nil {
log.Printf("Metric %v not found at target %v\n", metric.Name, target.Resource)
continue
}
if len(metricValueData.Value[0].Data) == 0 {
log.Printf("No metric data returned for metric %v at target %v\n", metric.Name, target.Resource)
continue
}
metricName := metricValueData.Value[0].Name.Value
metricValue := metricValueData.Value[0].Data[len(metricValueData.Value[0].Data)-1]
labels := CreateResourceLabels(metricValueData.Value[0].ID)
ch <- prometheus.MustNewConstMetric(
prometheus.NewDesc(metricName, "", nil, labels),
prometheus.GaugeValue,
metricValue.Total,
)
}
}
}
func handler(w http.ResponseWriter, r *http.Request) {
registry := prometheus.NewRegistry()
collector := &Collector{}
registry.MustRegister(collector)
h := promhttp.HandlerFor(registry, promhttp.HandlerOpts{})
h.ServeHTTP(w, r)
}
func main() {
kingpin.HelpFlag.Short('h')
kingpin.Parse()
log.Printf("azure_metrics_exporter listening on port %v", *listenAddress)
if err := sc.ReloadConfig(*configFile); err != nil {
log.Fatalf("Error loading config: %v", err)
os.Exit(1)
}
ac.getAccessToken()
// Print list of available metric definitions for each resource to console if specified.
if *listMetricDefinitions {
results := ac.getMetricDefinitions()
for k, v := range results {
log.Printf("Resource: %s\n\nAvailable Metrics:\n", strings.Split(k, "/")[6])
for _, r := range v.MetricDefinitionResponses {
log.Printf("- %s\n", r.Name.Value)
}
}
}
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(`<html>
<head>
<title>Azure Exporter</title>
</head>
<body>
<h1>Azure Exporter</h1>
<p><a href="/metrics">Metrics</a></p>
</body>
</html>`))
})
http.HandleFunc("/metrics", handler)
if err := http.ListenAndServe(*listenAddress, nil); err != nil {
log.Fatalf("Error starting HTTP server: %v", err)
os.Exit(1)
}
}