dnsd: serve prometheus metrics on port 8053
This commit is contained in:
parent
0e6add220c
commit
24e2d5de00
@ -6,15 +6,33 @@ import (
|
||||
"flag"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/gokrazy/gokrazy"
|
||||
|
||||
"router7/internal/dhcp4d"
|
||||
"router7/internal/dns"
|
||||
"router7/internal/multilisten"
|
||||
"router7/internal/netconfig"
|
||||
|
||||
_ "net/http/pprof"
|
||||
)
|
||||
|
||||
func updateListeners() error {
|
||||
hosts, err := gokrazy.PrivateInterfaceAddrs()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if net1, err := multilisten.IPv6Net1("/perm"); err == nil {
|
||||
hosts = append(hosts, net1)
|
||||
}
|
||||
|
||||
return multilisten.ListenAndServe(hosts, "8053", http.DefaultServeMux)
|
||||
}
|
||||
|
||||
func logic() error {
|
||||
// TODO: set correct upstream DNS resolver(s)
|
||||
ip, err := netconfig.LinkAddress("/perm", "lan0")
|
||||
@ -37,10 +55,15 @@ func logic() error {
|
||||
if err := readLeases(); err != nil {
|
||||
log.Printf("cannot resolve DHCP hostnames: %v", err)
|
||||
}
|
||||
http.Handle("/metrics", srv.PrometheusHandler())
|
||||
updateListeners()
|
||||
ch := make(chan os.Signal, 1)
|
||||
signal.Notify(ch, syscall.SIGUSR1)
|
||||
go func() {
|
||||
for range ch {
|
||||
if err := updateListeners(); err != nil {
|
||||
log.Printf("updateListeners: %v", err)
|
||||
}
|
||||
if err := readLeases(); err != nil {
|
||||
log.Printf("readLeases: %v", err)
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package dns
|
||||
import (
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
@ -10,9 +11,10 @@ import (
|
||||
|
||||
"router7/internal/dhcp4d"
|
||||
|
||||
"golang.org/x/time/rate"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"golang.org/x/time/rate"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
@ -21,6 +23,10 @@ type Server struct {
|
||||
domain string
|
||||
upstream string
|
||||
sometimes *rate.Limiter
|
||||
prom struct {
|
||||
registry *prometheus.Registry
|
||||
queries prometheus.Counter
|
||||
}
|
||||
|
||||
mu sync.Mutex
|
||||
hostname, ip string
|
||||
@ -40,6 +46,13 @@ func NewServer(addr, domain string) *Server {
|
||||
hostname: hostname,
|
||||
ip: ip,
|
||||
}
|
||||
server.prom.registry = prometheus.NewRegistry()
|
||||
server.prom.queries = prometheus.NewCounter(prometheus.CounterOpts{
|
||||
Name: "dns_queries",
|
||||
Help: "Number of DNS queries received",
|
||||
})
|
||||
server.prom.registry.MustRegister(server.prom.queries)
|
||||
server.prom.registry.MustRegister(prometheus.NewGoCollector())
|
||||
server.initHostsLocked()
|
||||
dns.HandleFunc(".", server.handleRequest)
|
||||
return server
|
||||
@ -68,6 +81,10 @@ func (s *Server) hostByIP(n string) (string, bool) {
|
||||
return r, ok
|
||||
}
|
||||
|
||||
func (s *Server) PrometheusHandler() http.Handler {
|
||||
return promhttp.HandlerFor(s.prom.registry, promhttp.HandlerOpts{})
|
||||
}
|
||||
|
||||
func (s *Server) SetLeases(leases []dhcp4d.Lease) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
@ -126,6 +143,7 @@ func isLocalInAddrArpa(q string) bool {
|
||||
|
||||
// TODO: require search domains to be present, then use HandleFunc("lan.", internalName)
|
||||
func (s *Server) handleRequest(w dns.ResponseWriter, r *dns.Msg) {
|
||||
s.prom.queries.Inc()
|
||||
if len(r.Question) == 1 { // TODO: answer all questions we can answer
|
||||
q := r.Question[0]
|
||||
if q.Qtype == dns.TypeA && q.Qclass == dns.ClassINET {
|
||||
|
@ -547,8 +547,13 @@ func Apply(dir, root string) error {
|
||||
}
|
||||
}
|
||||
|
||||
if err := notify.Process("/user/dyndns", syscall.SIGUSR1); err != nil {
|
||||
log.Printf("notifying dyndns: %v", err)
|
||||
for _, process := range []string{
|
||||
"dyndns", // depends on the public IPv4 address
|
||||
"dnsd", // listens on private IPv4/IPv6 and public IPv6Net1
|
||||
} {
|
||||
if err := notify.Process("/user/"+process, syscall.SIGUSR1); err != nil {
|
||||
log.Printf("notifying %s: %v", process, err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := applySysctl(); err != nil {
|
||||
|
Loading…
x
Reference in New Issue
Block a user