-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathtwitch_exporter.go
112 lines (95 loc) · 3.31 KB
/
twitch_exporter.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
// Copyright 2020 Damien PLÉNARD.
// Licensed under the MIT License
package main
import (
"fmt"
"log/slog"
"net/http"
"os"
kingpin "github.com/alecthomas/kingpin/v2"
"github.com/damoun/twitch_exporter/collector"
"github.com/nicklaw5/helix/v2"
"github.com/prometheus/client_golang/prometheus"
versioncollector "github.com/prometheus/client_golang/prometheus/collectors/version"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/prometheus/common/promslog"
"github.com/prometheus/common/promslog/flag"
"github.com/prometheus/common/version"
"github.com/prometheus/exporter-toolkit/web"
webflag "github.com/prometheus/exporter-toolkit/web/kingpinflag"
)
var (
metricsPath = kingpin.Flag("web.telemetry-path",
"Path under which to expose metrics.").
Default("/metrics").String()
twitchClientID = kingpin.Flag("twitch.client-id",
"Client ID for the Twitch Helix API.").Required().String()
twitchChannel = Channels(kingpin.Flag("twitch.channel",
"Name of a Twitch Channel to request metrics."))
twitchAccessToken = kingpin.Flag("twitch.access-token",
"Access Token for the Twitch Helix API.").Required().String()
)
type promHTTPLogger struct {
logger *slog.Logger
}
func (l promHTTPLogger) Println(v ...interface{}) {
l.logger.Error("msg", fmt.Sprint(v...))
}
// Channels creates a collection of Channels from a kingpin command line argument.
func Channels(s kingpin.Settings) (target *collector.ChannelNames) {
target = &collector.ChannelNames{}
s.SetValue(target)
return target
}
func init() {
prometheus.MustRegister(versioncollector.NewCollector("twitch_exporter"))
}
func main() {
promslogConfig := &promslog.Config{}
flag.AddFlags(kingpin.CommandLine, promslogConfig)
var webConfig = webflag.AddFlags(kingpin.CommandLine, ":9184")
kingpin.Version(version.Print("twitch_exporter"))
kingpin.HelpFlag.Short('h')
kingpin.Parse()
logger := promslog.New(promslogConfig)
logger.Info("msg", "Starting twitch_exporter", "version", version.Info())
logger.Info("build_context", version.BuildContext())
client, err := helix.NewClient(&helix.Options{
ClientID: *twitchClientID,
UserAccessToken: *twitchAccessToken,
})
if err != nil {
logger.Error("msg", "could not initialise twitch client", "err", err)
return
}
exporter, err := collector.NewExporter(logger, client, *twitchChannel)
if err != nil {
logger.Error("msg", "Error creating the exporter", "err", err)
os.Exit(1)
}
r := prometheus.NewRegistry()
r.MustRegister(exporter)
http.Handle(*metricsPath, promhttp.HandlerFor(r, promhttp.HandlerOpts{
ErrorLog: promHTTPLogger{logger: logger},
ErrorHandling: promhttp.ContinueOnError,
}))
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
_, err := w.Write([]byte(`<html>
<head><title>Twitch Exporter</title></head>
<body>
<h1>Twitch Exporter</h1>
<p><a href='` + *metricsPath + `'>Metrics</a></p>
<h2>Build</h2>
<pre>` + version.Info() + ` ` + version.BuildContext() + `</pre>
</body>
</html>`))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
})
srv := &http.Server{}
if err := web.ListenAndServe(srv, webConfig, logger); err != nil {
logger.Error("msg", "Error starting HTTP server", "err", err)
os.Exit(1)
}
}