ping-monitoring

A prometheus exporter to monitor matrix federation with using the existing pingbot infra.
git clone git://archive.git.mtrnord.blog/MTRNord/ping-monitoring.git
Log | Files | Refs | LICENSE

commit 4ceac52b5bd117c006c1dc34a285d70f6d019875
parent ff1d9978ce68a0005a77c160797920a13ebc1b7d
Author: MTRNord <mtrnord1@gmail.com>
Date:   Thu, 15 Feb 2024 16:22:05 +0100

feat: Add initial codebase
Diffstat:
M.gitignore | 4+++-
Aconfig.go | 101+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ago.mod | 27+++++++++++++++++++++++++++
Ago.sum | 48++++++++++++++++++++++++++++++++++++++++++++++++
Amain.go | 32++++++++++++++++++++++++++++++++
Aping_json.go | 26++++++++++++++++++++++++++
Aping_manager.go | 1+
7 files changed, 238 insertions(+), 1 deletion(-)

diff --git a/.gitignore b/.gitignore @@ -15,7 +15,8 @@ *.out # Dependency directories (remove the comment below to include it) -# vendor/ +vendor/ # Go workspace file go.work +config.yaml +\ No newline at end of file diff --git a/config.go b/config.go @@ -0,0 +1,101 @@ +package main + +import ( + "os" + + "github.com/goccy/go-yaml" + log "github.com/sirupsen/logrus" +) + +type MatrixConfig struct { + Homeserver string `yaml:"homeserver"` + Username string `yaml:"username"` + Password string `yaml:"password"` +} + +type Config struct { + Address string `yaml:"address"` + OwnHomeserver MatrixConfig `yaml:"own_homeserver"` + RemoteHomeservers []MatrixConfig `yaml:"remote_homeservers"` + PingRoom string `yaml:"ping_room"` + PingRateSeconds int `yaml:"ping_rate_seconds"` + PingThresholdSeconds int `yaml:"ping_threshold_seconds"` + PingJsonURL string `yaml:"ping_json_url"` + BlacklistedHomeservers []string `yaml:"blacklisted_homeservers"` +} + +func ReadConfig() Config { + var err error + var b []byte + var config Config + if b, err = os.ReadFile("config.yaml"); err != nil { + log.Errorf("Failed to read config file: %s", err) + os.Exit(1) + } + + // Load yaml + if err := yaml.Unmarshal(b, &config); err != nil { + log.Errorf("Failed to load config: %s", err) + os.Exit(1) + } + + // Ensure we have a PingRoom + if config.PingRoom == "" { + log.Errorln("No ping room defined") + os.Exit(1) + } + + // Ensure we have a PingJsonURL + if config.PingJsonURL == "" { + log.Errorln("No ping json url defined") + os.Exit(1) + } + + // Ensure we have a PingRateSeconds + if config.PingRateSeconds == 0 { + config.PingRateSeconds = 60 + } + + // Ensure we have a PingThresholdSeconds + if config.PingThresholdSeconds == 0 { + config.PingThresholdSeconds = 240 + } + + // Ensure the matrix homeserver values are not empty + if config.OwnHomeserver.Homeserver == "" { + log.Errorln("No own homeserver defined") + os.Exit(1) + } + if config.OwnHomeserver.Username == "" { + log.Errorln("No own homeserver username defined") + os.Exit(1) + } + if config.OwnHomeserver.Password == "" { + log.Errorln("No own homeserver password defined") + os.Exit(1) + } + + // Ensure we have at least one Remote Homeserver + if len(config.RemoteHomeservers) == 0 { + log.Errorln("No remote homeservers defined") + os.Exit(1) + } + + // Ensure the remote homeserver values are not empty + for n, remoteHomeserver := range config.RemoteHomeservers { + if remoteHomeserver.Homeserver == "" { + log.Errorf("No remote homeserver defined for homeserver %d", n) + os.Exit(1) + } + if remoteHomeserver.Username == "" { + log.Errorf("No remote homeserver username defined for homeserver %s", remoteHomeserver.Homeserver) + os.Exit(1) + } + if remoteHomeserver.Password == "" { + log.Errorf("No remote homeserver password defined for homeserver %s", remoteHomeserver.Homeserver) + os.Exit(1) + } + } + + return config +} diff --git a/go.mod b/go.mod @@ -0,0 +1,27 @@ +module github.com/MTRNord/ping-monitoring + +go 1.21.5 + +require github.com/prometheus/client_golang v1.18.0 + +require ( + github.com/fatih/color v1.10.0 // indirect + github.com/mattn/go-colorable v0.1.8 // indirect + github.com/mattn/go-isatty v0.0.12 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect +) + +require ( + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/ghodss/yaml v1.0.0 + github.com/goccy/go-yaml v1.11.3 + github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect + github.com/prometheus/client_model v0.5.0 // indirect + github.com/prometheus/common v0.45.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect + github.com/sirupsen/logrus v1.9.3 + golang.org/x/sys v0.15.0 // indirect + google.golang.org/protobuf v1.31.0 // indirect +) diff --git a/go.sum b/go.sum @@ -0,0 +1,48 @@ +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= +github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/goccy/go-yaml v1.11.3 h1:B3W9IdWbvrUu2OYQGwvU1nZtvMQJPBKgBUuweJjLj6I= +github.com/goccy/go-yaml v1.11.3/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= +github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= +github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go @@ -0,0 +1,32 @@ +package main + +import ( + "flag" + "net/http" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promhttp" + "github.com/prometheus/common/version" + log "github.com/sirupsen/logrus" +) + +func main() { + var config = ReadConfig() + var address = config.Address + flag.StringVar(&address, "address", "0.0.0.0:8080", "Address to listen on") + flag.Parse() + + prometheus.Register(version.NewCollector("matrix_ping_exporter")) + + http.HandleFunc("/metrics", func(w http.ResponseWriter, r *http.Request) { + h := promhttp.HandlerFor(prometheus.Gatherers{ + prometheus.DefaultGatherer, + }, promhttp.HandlerOpts{}) + h.ServeHTTP(w, r) + }) + + log.Infof("Starting http server - %s", address) + if err := http.ListenAndServe(address, nil); err != nil { + log.Errorf("Failed to start http server: %s", err) + } +} diff --git a/ping_json.go b/ping_json.go @@ -0,0 +1,26 @@ +package main + +type Ping struct { + Diffs map[string]int `json:"diffs"` + Mean float64 `json:"mean"` + Median float64 `json:"median"` + GMean float64 `json:"gmean"` +} + +type Pings map[string]Ping + +type Pong struct { + Pings []string `json:"pings"` + Mean float64 `json:"mean"` + Median float64 `json:"median"` + GMean float64 `json:"gmean"` +} + +type PongServers []string + +type Data struct { + Disclaimer string `json:"disclaimer"` + Pings Pings `json:"pings"` + Mean float64 `json:"mean"` + PongServers PongServers `json:"pongservers"` +} diff --git a/ping_manager.go b/ping_manager.go @@ -0,0 +1 @@ +package main