Files
2023-10-25 15:31:18 +02:00

83 lines
1.9 KiB
Go

package main
import (
"flag"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"gopkg.in/yaml.v2"
"io/ioutil"
"log"
"fmt"
"net"
"net/http"
)
type Service struct {
Name string `yaml:"name"`
Host string `yaml:"host"`
Port string `yaml:"port"`
}
type Config struct {
Services []Service `yaml:"services"`
}
var (
latency = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "service_latency_seconds",
Help: "Latency of services.",
},
[]string{"service"},
)
addr = flag.String("a", "0.0.0.0", "address to use")
port = flag.String("p", "9062", "port to run on")
conf = flag.String("c", "config.yml", "configuration file to use")
inter = flag.Int("i", 30, "time interval in seconds between two checks")
)
func init() {
prometheus.MustRegister(latency)
}
func main() {
flag.Parse()
http.Handle("/metrics", promhttp.Handler())
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
fmt.Fprintln(w, "Prometheus Latency Exporter: <a href='/metrics'>Metrics</a>")
})
go func() {
for {
checkLatency()
time.Sleep(time.Duration(*inter) * time.Second)
}
}()
log.Fatal(http.ListenAndServe(net.JoinHostPort(*addr, *port), nil))
}
func checkLatency() {
var config Config
source, err := ioutil.ReadFile(*conf)
if err != nil {
log.Fatalf("error: %v", err)
}
err = yaml.Unmarshal(source, &config)
if err != nil {
log.Fatalf("error: %v", err)
}
for _, service := range config.Services {
start := time.Now()
conn, err := net.Dial("tcp", net.JoinHostPort(service.Host, service.Port))
if err != nil {
log.Printf("Failed to check service: %s, error: %s", service.Name, err)
continue
}
conn.Close()
duration := time.Since(start)
latency.With(prometheus.Labels{"service": service.Name}).Set(duration.Seconds())
}
}