]> go.fuhry.dev Git - runtime.git/commitdiff
add prometheus_http_discovery program
authorDan Fuhry <dan@fuhry.com>
Sat, 22 Mar 2025 03:07:41 +0000 (23:07 -0400)
committerDan Fuhry <dan@fuhry.com>
Sat, 22 Mar 2025 03:07:41 +0000 (23:07 -0400)
.gitignore
metrics/prometheus_http_discovery/Makefile [new file with mode: 0644]
metrics/prometheus_http_discovery/main.go [new file with mode: 0644]
metrics/prometheus_http_discovery/systemd/prometheus-http-discovery.service [new file with mode: 0644]

index de7cd732be648641e24a36fa633c990e4836c4e1..50a6a0ba82e9eacd5068d995779ea578d780803c 100644 (file)
@@ -53,6 +53,7 @@ http/samlproxy/samlproxy
 automation/bryston_ctl/cli/cli
 automation/bryston_ctl/client/client
 automation/bryston_ctl/server/server
+metrics/prometheus_http_discovery/prometheus_http_discovery
 
 /vendor/
 
diff --git a/metrics/prometheus_http_discovery/Makefile b/metrics/prometheus_http_discovery/Makefile
new file mode 100644 (file)
index 0000000..bfab546
--- /dev/null
@@ -0,0 +1,14 @@
+GOSRC = $(wildcard *.go)
+GOEXE = $(shell basename `pwd`)
+GOBUILDFLAGS := -buildmode=pie -trimpath
+
+all: $(GOEXE)
+
+clean:
+       rm -fv $(GOEXE)
+
+.PHONY: all clean
+
+$(GOEXE): %: $(GOSRC)
+       go build $(GOBUILDFLAGS) -o $@ $<
+
diff --git a/metrics/prometheus_http_discovery/main.go b/metrics/prometheus_http_discovery/main.go
new file mode 100644 (file)
index 0000000..7e6462a
--- /dev/null
@@ -0,0 +1,115 @@
+package main
+
+import (
+       "context"
+       "encoding/json"
+       "flag"
+       "fmt"
+       "net/http"
+       "os/signal"
+       "sync"
+       "syscall"
+       "time"
+
+       "github.com/coreos/go-systemd/daemon"
+
+       "go.fuhry.dev/runtime/constants"
+       "go.fuhry.dev/runtime/mtls"
+       "go.fuhry.dev/runtime/sd"
+       "go.fuhry.dev/runtime/utils/log"
+)
+
+type endpoint struct {
+       Targets []string          `json:"targets"`
+       Labels  map[string]string `json:"labels"`
+}
+
+func main() {
+       mtls.SetDefaultIdentity("node-exporter")
+       ctx, _ := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
+       serverCtx, cancel := context.WithCancel(context.Background())
+       defer cancel()
+
+       port := flag.Uint("port", 9102, "port to listen on")
+
+       flag.Parse()
+
+       id := mtls.DefaultIdentity()
+       tlsConfig, err := id.TlsConfig(serverCtx)
+       if err != nil {
+               log.Panic(err)
+       }
+       pv := mtls.NewPeerNameVerifier()
+       pv.AllowFrom(mtls.Service, "prometheus")
+       pv.AllowFrom(mtls.Service, "healthcheck")
+       err = pv.ConfigureServer(tlsConfig)
+       if err != nil {
+               log.Panic(err)
+       }
+
+       mux := http.NewServeMux()
+       loggingMiddleware := log.NewLoggingMiddleware(mux)
+       sdWatchers := make(map[string]*sd.SDWatcher, 0)
+       sdLock := sync.Mutex{}
+       mux.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
+               w.WriteHeader(http.StatusOK)
+               w.Write([]byte(fmt.Sprintf("<h1>%s Prometheus HTTP discovery servicer</h1>", constants.OrgName)))
+       })
+       mux.HandleFunc("/endpoints/{service}", func(w http.ResponseWriter, r *http.Request) {
+               service := r.PathValue("service")
+               sdLock.Lock()
+               if _, ok := sdWatchers[service]; !ok {
+                       sdWatchers[service] = &sd.SDWatcher{
+                               Service:  service,
+                               Protocol: sd.ProtocolTCP,
+                       }
+               }
+               watcher := sdWatchers[service]
+               sdLock.Unlock()
+
+               endpoints, err := watcher.GetAddrs(serverCtx)
+               if err != nil {
+                       w.WriteHeader(http.StatusInternalServerError)
+                       w.Write([]byte(err.Error()))
+                       return
+               }
+
+               targets := make([]*endpoint, 0)
+               for _, ep := range endpoints {
+                       targets = append(targets, &endpoint{
+                               Targets: []string{
+                                       fmt.Sprintf("%s:%d", ep.Hostname, ep.Port),
+                               },
+                               Labels: map[string]string{
+                                       "shard": ep.Shard,
+                                       "host":  ep.Hostname,
+                               },
+                       })
+               }
+
+               out, err := json.MarshalIndent(targets, "", "    ")
+               if err != nil {
+                       w.WriteHeader(http.StatusInternalServerError)
+                       w.Write([]byte(err.Error()))
+                       return
+               }
+               w.Header().Set("content-type", "application/json")
+
+               w.Write(out)
+       })
+       server := &http.Server{
+               Addr:      fmt.Sprintf("[::1]:%d", *port),
+               TLSConfig: tlsConfig,
+               Handler:   loggingMiddleware.HandlerFunc(),
+       }
+
+       go server.ListenAndServeTLS("", "")
+
+       daemon.SdNotify(false, daemon.SdNotifyReady)
+
+       <-ctx.Done()
+       cancel()
+
+       shutdownCtx, _ := context.WithTimeout(context.Background(), 5*time.Second)
+       server.Shutdown(shutdownCtx)
+}
diff --git a/metrics/prometheus_http_discovery/systemd/prometheus-http-discovery.service b/metrics/prometheus_http_discovery/systemd/prometheus-http-discovery.service
new file mode 100644 (file)
index 0000000..9b63216
--- /dev/null
@@ -0,0 +1,10 @@
+[Unit]
+Description=Prometheus HTTP endpoint discoverer monitors service discovery entries and returns Prometheus http_sd_config JSON
+
+[Service]
+Type=notify
+User=nobody
+ExecStart=/usr/bin/prometheus-http-discovery
+
+[Install]
+WantedBy=default.target