summaryrefslogtreecommitdiff
path: root/att script/4(v6 DDoS)/code/辅助权威服务器/plugin/prometheus/metrics.go
diff options
context:
space:
mode:
Diffstat (limited to 'att script/4(v6 DDoS)/code/辅助权威服务器/plugin/prometheus/metrics.go')
-rw-r--r--att script/4(v6 DDoS)/code/辅助权威服务器/plugin/prometheus/metrics.go170
1 files changed, 170 insertions, 0 deletions
diff --git a/att script/4(v6 DDoS)/code/辅助权威服务器/plugin/prometheus/metrics.go b/att script/4(v6 DDoS)/code/辅助权威服务器/plugin/prometheus/metrics.go
new file mode 100644
index 0000000..ce58cbc
--- /dev/null
+++ b/att script/4(v6 DDoS)/code/辅助权威服务器/plugin/prometheus/metrics.go
@@ -0,0 +1,170 @@
+package prometheus
+
+import (
+ "context"
+ "net"
+ "net/http"
+ "ohmydns2/plugin"
+ "ohmydns2/plugin/pkg/reuseport"
+ "sync"
+ "time"
+
+ "github.com/coredns/caddy"
+ "github.com/prometheus/client_golang/prometheus"
+ "github.com/prometheus/client_golang/prometheus/promauto"
+ "github.com/prometheus/client_golang/prometheus/promhttp"
+)
+
+// Metrics holds the prometheus configuration. The metrics' path is fixed to be /metrics .
+type Metrics struct {
+ Next plugin.Handler
+ Addr string
+ Reg *prometheus.Registry
+
+ ln net.Listener
+ lnSetup bool
+
+ mux *http.ServeMux
+ srv *http.Server
+
+ zoneNames []string
+ zoneMap map[string]struct{}
+ zoneMu sync.RWMutex
+
+ plugins map[string]struct{} // all available plugins, used to determine which plugin made the client write
+}
+
+// New returns a new instance of Metrics with the given address.
+func New(addr string) *Metrics {
+ met := &Metrics{
+ Addr: addr,
+ Reg: prometheus.DefaultRegisterer.(*prometheus.Registry),
+ zoneMap: make(map[string]struct{}),
+ plugins: pluginList(caddy.ListPlugins()),
+ }
+
+ return met
+}
+
+// MustRegister wraps m.Reg.MustRegister.
+func (m *Metrics) MustRegister(c prometheus.Collector) {
+ err := m.Reg.Register(c)
+ if err != nil {
+ // ignore any duplicate error, but fatal on any other kind of error
+ if _, ok := err.(prometheus.AlreadyRegisteredError); !ok {
+ log.Fatalf("Cannot register metrics collector: %s", err)
+ }
+ }
+}
+
+// AddZone adds zone z to m.
+func (m *Metrics) AddZone(z string) {
+ m.zoneMu.Lock()
+ m.zoneMap[z] = struct{}{}
+ m.zoneNames = keys(m.zoneMap)
+ m.zoneMu.Unlock()
+}
+
+// RemoveZone remove zone z from m.
+func (m *Metrics) RemoveZone(z string) {
+ m.zoneMu.Lock()
+ delete(m.zoneMap, z)
+ m.zoneNames = keys(m.zoneMap)
+ m.zoneMu.Unlock()
+}
+
+// ZoneNames returns the zones of m.
+func (m *Metrics) ZoneNames() []string {
+ m.zoneMu.RLock()
+ s := m.zoneNames
+ m.zoneMu.RUnlock()
+ return s
+}
+
+// OnStartup sets up the metrics on startup.
+func (m *Metrics) OnStartup() error {
+ ln, err := reuseport.Listen("tcp", m.Addr)
+ if err != nil {
+ log.Errorf("Failed to start metrics handler: %s", err)
+ return err
+ }
+
+ m.ln = ln
+ m.lnSetup = true
+
+ m.mux = http.NewServeMux()
+ m.mux.Handle("/metrics", promhttp.HandlerFor(m.Reg, promhttp.HandlerOpts{}))
+
+ // creating some helper variables to avoid data races on m.srv and m.ln
+ server := &http.Server{Handler: m.mux}
+ m.srv = server
+
+ go func() {
+ server.Serve(ln)
+ }()
+
+ ListenAddr = ln.Addr().String() // For tests.
+ return nil
+}
+
+// OnRestart stops the listener on reload.
+func (m *Metrics) OnRestart() error {
+ if !m.lnSetup {
+ return nil
+ }
+ u.Unset(m.Addr)
+ return m.stopServer()
+}
+
+func (m *Metrics) stopServer() error {
+ if !m.lnSetup {
+ return nil
+ }
+ ctx, cancel := context.WithTimeout(context.Background(), shutdownTimeout)
+ defer cancel()
+ if err := m.srv.Shutdown(ctx); err != nil {
+ log.Infof("Failed to stop prometheus http server: %s", err)
+ return err
+ }
+ m.lnSetup = false
+ m.ln.Close()
+ return nil
+}
+
+// OnFinalShutdown tears down the metrics listener on shutdown and restart.
+func (m *Metrics) OnFinalShutdown() error { return m.stopServer() }
+
+func keys(m map[string]struct{}) []string {
+ sx := []string{}
+ for k := range m {
+ sx = append(sx, k)
+ }
+ return sx
+}
+
+// pluginList iterates over the returned plugin map from caddy and removes the "dns." prefix from them.
+func pluginList(m map[string][]string) map[string]struct{} {
+ pm := map[string]struct{}{}
+ for _, p := range m["others"] {
+ // only add 'dns.' plugins
+ if len(p) > 3 {
+ pm[p[4:]] = struct{}{}
+ continue
+ }
+ }
+ return pm
+}
+
+// ListenAddr is assigned the address of the prometheus listener. Its use is mainly in tests where
+// we listen on "localhost:0" and need to retrieve the actual address.
+var ListenAddr string
+
+// shutdownTimeout is the maximum amount of time the metrics plugin will wait
+// before erroring when it tries to close the metrics server
+const shutdownTimeout time.Duration = time.Second * 5
+
+var buildInfo = promauto.NewGaugeVec(prometheus.GaugeOpts{
+ Namespace: plugin.Namespace,
+ Name: "build_info",
+ Help: "A metric with a constant '1' value labeled by version, revision, and goversion from which OhmyDNS was built.",
+}, []string{"version", "revision", "goversion"})