-
Notifications
You must be signed in to change notification settings - Fork 3
/
main.go
149 lines (127 loc) · 4.57 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
148
149
package main
import (
"encoding/json"
"fmt"
"net/http"
"github.com/flant/elasticsearch-oneday-exporter/collector"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/prometheus/common/version"
"github.com/sirupsen/logrus"
"gopkg.in/alecthomas/kingpin.v2"
)
// Same struct prometheus uses for their /version address.
// Separate copy to avoid pulling all of prometheus as a dependency
type prometheusVersion struct {
Version string `json:"version"`
Revision string `json:"revision"`
Branch string `json:"branch"`
BuildUser string `json:"buildUser"`
BuildDate string `json:"buildDate"`
GoVersion string `json:"goVersion"`
}
var (
log = logrus.New()
logLevel = kingpin.Flag("log.level",
"Only log messages with the given severity or above. Valid levels: [debug, info, warn, error, fatal]",
).Default("info").Enum("debug", "info", "warn", "error", "fatal")
logFormat = kingpin.Flag("log.format",
"Set the log format. Valid formats: [json, text]",
).Default("json").Enum("json", "text")
datePattern = kingpin.Flag("date.pattern", "Date pattern for selecting indices.").
Default("2006.01.02").String()
listenAddress = kingpin.Flag("telemetry.addr", "Listen on host:port.").
Default(":9101").String()
metricsPath = kingpin.Flag("telemetry.path", "URL path for surfacing collected metrics.").
Default("/metrics").String()
address = kingpin.Flag("address", "Elasticsearch node to use.").
Default("http://localhost:9200").String()
cacert = kingpin.Flag("ca-cert", "Path to PEM file that contains trusted Certificate Authorities for the Elasticsearch connection.").
Default("").String()
clientcert = kingpin.Flag("client-cert", "Path to PEM file that contains the corresponding cert for the private key to connect to Elasticsearch.").
Default("").String()
clientkey = kingpin.Flag("client-key", "Path to PEM file that contains the private key for client auth when connecting to Elasticsearch.").
Default("").String()
insecure = kingpin.Flag("insecure", "Skip SSL verification when connecting to Elasticsearch.").
Default("false").Bool()
projectName = kingpin.Flag("project", "Project name").String()
repoName = kingpin.Flag("repository", "Repository name").String()
)
func main() {
kingpin.Version(version.Print("es-oneday-exporter"))
kingpin.HelpFlag.Short('h')
kingpin.Parse()
if err := setLogLevel(*logLevel); err != nil {
log.Fatal(err)
}
if err := setLogFormat(*logFormat); err != nil {
log.Fatal(err)
}
http.Handle(*metricsPath, promhttp.Handler())
http.HandleFunc("/healthz", healthCheck)
http.HandleFunc("/version", func(w http.ResponseWriter, r *http.Request) {
// we can't use "version" directly as it is a package, and not an object that
// can be serialized.
err := json.NewEncoder(w).Encode(prometheusVersion{
Version: version.Version,
Revision: version.Revision,
Branch: version.Branch,
BuildUser: version.BuildUser,
BuildDate: version.BuildDate,
GoVersion: version.GoVersion,
})
if err != nil {
http.Error(w, fmt.Sprintf("error encoding JSON: %s", err), http.StatusInternalServerError)
}
})
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte(`<html>
<head><title>es-oneday-exporter</title></head>
<body>
<h1>es-oneday-exporter</h1>
<p><a href="` + *metricsPath + `">Metrics</a></p>
<p><i>` + version.Info() + `</i></p>
</body>
</html>`))
})
log.Info("Starting es-oneday-exporter", version.Info())
log.Info("Build context", version.BuildContext())
tlsClientConfig := createTLSConfig(*cacert, *clientcert, *clientkey, *insecure)
err := collector.NewCollector(log, *address, *projectName, *repoName, *datePattern, tlsClientConfig)
if err != nil {
log.Fatalf("error creating new collector instance: %v", err)
}
log.Info("Starting server on ", *listenAddress)
log.Fatal(http.ListenAndServe(*listenAddress, nil))
}
func healthCheck(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
_, err := fmt.Fprintln(w, `{"status":"ok"}`)
if err != nil {
log.Debugf("Failed to write to stream: %v", err)
}
}
func setLogLevel(level string) error {
lvl, err := logrus.ParseLevel(level)
if err != nil {
return err
}
log.SetLevel(lvl)
return nil
}
func setLogFormat(format string) error {
var formatter logrus.Formatter
switch format {
case "text":
formatter = &logrus.TextFormatter{
DisableColors: true,
FullTimestamp: true,
}
case "json":
formatter = &logrus.JSONFormatter{}
default:
return fmt.Errorf("invalid log format: %s", format)
}
log.SetFormatter(formatter)
log.SetReportCaller(true)
return nil
}