-
Notifications
You must be signed in to change notification settings - Fork 12
/
main.go
147 lines (123 loc) · 3.91 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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package main
import (
"flag"
"fmt"
"log"
"net/http"
"os"
"github.com/j6s/mailcow-exporter/mailcowApi"
"github.com/j6s/mailcow-exporter/provider"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var (
defaultHost string
defaultApiKey string
listen string
)
// A Provider is the common abstraction over collection of metrics in this
// exporter. It can provide one or more prometheus collectors (e.g. gauges,
// histograms, ...) that are updated every time the `Update` method is called.
// Be sure to keep a copy of the collectors returned by `GetCollectors`
// in your provider in order to update that same instance.
type Provider interface {
Provide(mailcowApi.MailcowApiClient) ([]prometheus.Collector, error)
}
// Provider setup. Every provider in this array will be used for gathering metrics.
var (
providers = []Provider{
provider.Mailq{},
provider.Mailbox{},
provider.Quarantine{},
provider.Container{},
provider.Rspamd{},
provider.Domain{},
}
)
func parseFlagsAndEnv() {
envHost, _ := os.LookupEnv("MAILCOW_EXPORTER_HOST")
envApiKey, _ := os.LookupEnv("MAILCOW_EXPORTER_API_KEY")
defaultListen, _ := os.LookupEnv("MAILCOW_EXPORTER_LISTEN")
if defaultListen == "" {
defaultListen = ":9099"
}
flag.StringVar(&defaultHost, "defaultHost", envHost, "The defaultHost to connect to. Defaults to the MAILCOW_EXPORTER_HOST environment variable")
flag.StringVar(&defaultApiKey, "apikey", envApiKey, "The API key to use for connection. Defaults to the MAILCOW_EXPORTER_API_KEY environment variable")
flag.StringVar(&listen, "listen", defaultListen, "Host and port to listen on. Defaults to the MAILCOW_EXPORTER_LISTEN environment variable or ':9099' otherwise")
flag.Parse()
}
func collectMetrics(scheme string, host string, apiKey string) *prometheus.Registry {
apiClient := mailcowApi.NewMailcowApiClient(scheme, host, apiKey)
success := prometheus.NewGaugeVec(prometheus.GaugeOpts{
Name: "mailcow_exporter_success",
ConstLabels: map[string]string{"host": host},
}, []string{"provider"})
registry := prometheus.NewRegistry()
registry.Register(success)
for _, provider := range providers {
providerSuccess := true
collectors, err := provider.Provide(apiClient)
if err != nil {
providerSuccess = false
log.Printf(
"Error while updating metrics of %T:\n%s",
provider,
err.Error(),
)
}
for _, collector := range collectors {
err = registry.Register(collector)
if err != nil {
providerSuccess = false
log.Printf(
"Error while updating metrics of %T:\n%s",
provider,
err.Error(),
)
}
}
if providerSuccess {
success.WithLabelValues(fmt.Sprintf("%T", provider)).Set(1.0)
} else {
success.WithLabelValues(fmt.Sprintf("%T", provider)).Set(0.0)
}
}
for _, collector := range apiClient.Provide() {
registry.Register(collector)
}
return registry
}
func main() {
parseFlagsAndEnv()
http.HandleFunc("/metrics", func(response http.ResponseWriter, request *http.Request) {
host := request.URL.Query().Get("host")
apiKey := request.URL.Query().Get("apiKey")
scheme := request.URL.Query().Get("scheme")
if host == "" {
host = defaultHost
}
if apiKey == "" {
apiKey = defaultApiKey
}
if scheme == "" {
scheme = "https"
}
if host == "" {
response.WriteHeader(http.StatusBadRequest)
response.Write([]byte("Query parameter `host` is required, since it is not defined by flags or environment"))
return
}
if apiKey == "" {
response.WriteHeader(http.StatusUnauthorized)
response.Write([]byte("Query parameter `apiKey` is required, since it is not defined by flags or environment"))
return
}
registry := collectMetrics(scheme, host, apiKey)
promhttp.HandlerFor(
registry,
promhttp.HandlerOpts{},
).ServeHTTP(response, request)
})
log.Printf("Starting to listen on %s", listen)
log.Fatal(http.ListenAndServe(listen, nil))
}