mirror of
https://github.com/nikdoof/aaisp-chaos.git
synced 2025-12-13 14:52:17 +00:00
Switch to a custom FlagSet and add a nicer usage message. Check for the required CHAOS_CONTROL_LOGIN and CHAOS_CONTROL_PASSWORD environment variables and exit with an error if neither is set. The usage string also mentions that both must be set.
188 lines
4.6 KiB
Go
188 lines
4.6 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"net"
|
|
"net/http"
|
|
"os"
|
|
"strconv"
|
|
|
|
chaos "github.com/jamesog/aaisp-chaos"
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
|
"github.com/rs/zerolog"
|
|
)
|
|
|
|
var (
|
|
broadbandQuotaRemainingDesc = prometheus.NewDesc(
|
|
"aaisp_broadband_quota_remaining",
|
|
"Quota remaining in bytes",
|
|
[]string{"line_id"},
|
|
nil,
|
|
)
|
|
broadbandQuotaTotalDesc = prometheus.NewDesc(
|
|
"aaisp_broadband_quota_total",
|
|
"Quota total in bytes",
|
|
[]string{"line_id"},
|
|
nil,
|
|
)
|
|
broadbandTXRateDesc = prometheus.NewDesc(
|
|
"aaisp_broadband_tx_rate",
|
|
"Line transmit rate in bits per second",
|
|
[]string{"line_id"},
|
|
nil,
|
|
)
|
|
broadbandRXRateDesc = prometheus.NewDesc(
|
|
"aaisp_broadband_rx_rate",
|
|
"Line receive rate in bits per second",
|
|
[]string{"line_id"},
|
|
nil,
|
|
)
|
|
scrapeSuccessGauge = prometheus.NewGauge(prometheus.GaugeOpts{
|
|
Name: "aaisp_scrape_success",
|
|
Help: "Displays whether or not the AAISP API scrape was a success",
|
|
})
|
|
)
|
|
|
|
type broadbandCollector struct {
|
|
*chaos.API
|
|
log zerolog.Logger
|
|
}
|
|
|
|
func (bc broadbandCollector) Describe(ch chan<- *prometheus.Desc) {
|
|
prometheus.DescribeByCollect(bc, ch)
|
|
}
|
|
|
|
func (bc broadbandCollector) Collect(ch chan<- prometheus.Metric) {
|
|
lines, err := bc.BroadbandInfo()
|
|
if err != nil {
|
|
bc.log.Debug().Err(err).Msg("error getting broadband info")
|
|
scrapeSuccessGauge.Set(0)
|
|
return
|
|
}
|
|
scrapeSuccessGauge.Set(1)
|
|
for _, line := range lines {
|
|
ch <- prometheus.MustNewConstMetric(
|
|
broadbandQuotaRemainingDesc,
|
|
prometheus.GaugeValue,
|
|
float64(line.QuotaRemaining),
|
|
strconv.Itoa(line.ID),
|
|
)
|
|
ch <- prometheus.MustNewConstMetric(
|
|
broadbandQuotaTotalDesc,
|
|
prometheus.CounterValue,
|
|
float64(line.QuotaMonthly),
|
|
strconv.Itoa(line.ID),
|
|
)
|
|
ch <- prometheus.MustNewConstMetric(
|
|
broadbandTXRateDesc,
|
|
prometheus.GaugeValue,
|
|
float64(line.TXRate),
|
|
strconv.Itoa(line.ID),
|
|
)
|
|
ch <- prometheus.MustNewConstMetric(
|
|
broadbandRXRateDesc,
|
|
prometheus.GaugeValue,
|
|
float64(line.RXRate),
|
|
strconv.Itoa(line.ID),
|
|
)
|
|
}
|
|
}
|
|
|
|
func loggingMiddleware(log zerolog.Logger) func(next http.Handler) http.Handler {
|
|
return func(next http.Handler) http.Handler {
|
|
fn := func(w http.ResponseWriter, r *http.Request) {
|
|
remoteHost, _, err := net.SplitHostPort(r.RemoteAddr)
|
|
if err != nil {
|
|
remoteHost = r.RemoteAddr
|
|
}
|
|
log.Log().
|
|
Str("proto", r.Proto).
|
|
Str("method", r.Method).
|
|
Str("path", r.URL.Path).
|
|
Str("remote_addr", remoteHost).
|
|
Str("user_agent", r.Header.Get("User-Agent")).
|
|
Send()
|
|
next.ServeHTTP(w, r)
|
|
}
|
|
return http.HandlerFunc(fn)
|
|
}
|
|
}
|
|
|
|
func usage(fs *flag.FlagSet) func() {
|
|
return func() {
|
|
o := fs.Output()
|
|
fmt.Fprintf(o, "Usage:\n %s ", os.Args[0])
|
|
fs.VisitAll(func(f *flag.Flag) {
|
|
s := fmt.Sprintf(" [-%s", f.Name)
|
|
if arg, _ := flag.UnquoteUsage(f); len(arg) > 0 {
|
|
s += " " + arg
|
|
}
|
|
s += "]"
|
|
fmt.Fprint(o, s)
|
|
})
|
|
fmt.Fprint(o, "\n\nOptions:\n")
|
|
fs.PrintDefaults()
|
|
fmt.Fprint(o, "\nThe environment variables CHAOS_CONTROL_LOGIN and CHAOS_CONTROL_PASSWORD must be set.\n")
|
|
}
|
|
}
|
|
|
|
func setupLogger(level, output string) zerolog.Logger {
|
|
ll, err := zerolog.ParseLevel(level)
|
|
if err != nil {
|
|
ll = zerolog.InfoLevel
|
|
}
|
|
|
|
log := zerolog.New(os.Stderr).Level(ll).With().Timestamp().Logger()
|
|
|
|
switch output {
|
|
case "console":
|
|
log = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
|
|
}
|
|
|
|
return log
|
|
}
|
|
|
|
func main() {
|
|
fs := flag.NewFlagSet(os.Args[0], flag.ExitOnError)
|
|
fs.Usage = usage(fs)
|
|
var (
|
|
listen = fs.String("listen", ":8080", "listen `address`")
|
|
logLevel = fs.String("log.level", "info", "log `level`")
|
|
logOutput = fs.String("log.output", "json", "log output `style` (json, console)")
|
|
)
|
|
fs.Parse(os.Args[1:])
|
|
|
|
log := setupLogger(*logLevel, *logOutput)
|
|
|
|
var (
|
|
controlLogin = os.Getenv("CHAOS_CONTROL_LOGIN")
|
|
controlPassword = os.Getenv("CHAOS_CONTROL_PASSWORD")
|
|
)
|
|
switch {
|
|
case controlLogin == "" && controlPassword == "":
|
|
log.Fatal().Msg("CHAOS_CONTROL_LOGIN and CHAOS_CONTROL_PASSWORD must be set in the environment")
|
|
case controlLogin == "":
|
|
log.Fatal().Msg("CHAOS_CONTROL_LOGIN is not set")
|
|
case controlPassword == "":
|
|
log.Fatal().Msg("CHAOS_CONTROL_PASSWORD is not set")
|
|
}
|
|
|
|
collector := broadbandCollector{
|
|
API: chaos.New(chaos.Auth{
|
|
ControlLogin: controlLogin,
|
|
ControlPassword: controlPassword,
|
|
}),
|
|
log: log,
|
|
}
|
|
|
|
loggedHandler := loggingMiddleware(log)
|
|
|
|
prometheus.MustRegister(collector)
|
|
prometheus.MustRegister(scrapeSuccessGauge)
|
|
http.Handle("/metrics", loggedHandler(promhttp.Handler()))
|
|
log.Info().Msgf("Listening on %s", *listen)
|
|
log.Fatal().Err(http.ListenAndServe(*listen, nil)).Send()
|
|
}
|