From 1444ebc1ee1e7cdb3881e3900c0e3fd09e59c8df Mon Sep 17 00:00:00 2001 From: ginuerzh Date: Tue, 5 Apr 2022 17:56:36 +0800 Subject: [PATCH] add metrics --- go.mod | 4 +- go.sum | 4 +- handler/auto/handler.go | 2 +- handler/forward/local/handler.go | 2 +- handler/forward/remote/handler.go | 2 +- handler/http/handler.go | 2 +- handler/http/udp.go | 4 +- handler/http2/handler.go | 2 +- handler/redirect/tcp/handler.go | 2 +- handler/redirect/udp/handler.go | 2 +- handler/relay/bind.go | 6 +- handler/relay/connect.go | 2 +- handler/relay/forward.go | 2 +- handler/sni/handler.go | 2 +- handler/socks/v4/handler.go | 2 +- handler/socks/v5/bind.go | 2 +- handler/socks/v5/connect.go | 2 +- handler/socks/v5/mbind.go | 2 +- handler/socks/v5/udp.go | 4 +- handler/socks/v5/udp_tun.go | 4 +- handler/ss/handler.go | 2 +- handler/sshd/handler.go | 2 +- internal/net/transport.go | 50 +++++++++++ internal/net/udp/relay.go | 126 ++++++++++++++++++++++++++++ metrics/metrics.go | 135 ++++++++++++++++++++++++++++++ metrics/service/service.go | 65 ++++++++++++++ 26 files changed, 405 insertions(+), 29 deletions(-) create mode 100644 internal/net/transport.go create mode 100644 internal/net/udp/relay.go create mode 100644 metrics/metrics.go create mode 100644 metrics/service/service.go diff --git a/go.mod b/go.mod index 727edd6..641c6e5 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/docker/libcontainer v2.2.1+incompatible github.com/gin-contrib/cors v1.3.1 github.com/gin-gonic/gin v1.7.7 - github.com/go-gost/core v0.0.0-20220404033031-04f6ed470873 + github.com/go-gost/core v0.0.0-20220405095520-c2f49e94443c github.com/go-gost/gosocks4 v0.0.1 github.com/go-gost/gosocks5 v0.3.1-0.20211109033403-d894d75b7f09 github.com/go-gost/relay v0.1.1-0.20211123134818-8ef7fd81ffd7 @@ -18,6 +18,7 @@ require ( github.com/lucas-clemente/quic-go v0.25.0 github.com/miekg/dns v1.1.47 github.com/milosgajdos/tenus v0.0.3 + github.com/prometheus/client_golang v1.12.1 github.com/rs/xid v1.3.0 github.com/shadowsocks/go-shadowsocks2 v0.1.5 github.com/shadowsocks/shadowsocks-go v0.0.0-20200409064450-3e585ff90601 @@ -69,7 +70,6 @@ require ( github.com/onsi/ginkgo v1.16.5 // indirect github.com/pelletier/go-toml v1.9.4 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_golang v1.12.1 // indirect github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.32.1 // indirect github.com/prometheus/procfs v0.7.3 // indirect diff --git a/go.sum b/go.sum index 6e2e6d8..6701e65 100644 --- a/go.sum +++ b/go.sum @@ -119,8 +119,8 @@ github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gost/core v0.0.0-20220404033031-04f6ed470873 h1:u+g28xvN00bW5ivbhb2GGo0R+JIBy5arxy5R+rKesqk= -github.com/go-gost/core v0.0.0-20220404033031-04f6ed470873/go.mod h1:/LzdiQ+0+3FMhyqw0phjFjXFdOa1fcQR5/bL/7ripCs= +github.com/go-gost/core v0.0.0-20220405095520-c2f49e94443c h1:TzDyqefjnUVgdT6piHZgeXrVKXevawsMs0kmSZZhDR4= +github.com/go-gost/core v0.0.0-20220405095520-c2f49e94443c/go.mod h1:/LzdiQ+0+3FMhyqw0phjFjXFdOa1fcQR5/bL/7ripCs= github.com/go-gost/gosocks4 v0.0.1 h1:+k1sec8HlELuQV7rWftIkmy8UijzUt2I6t+iMPlGB2s= github.com/go-gost/gosocks4 v0.0.1/go.mod h1:3B6L47HbU/qugDg4JnoFPHgJXE43Inz8Bah1QaN9qCc= github.com/go-gost/gosocks5 v0.3.1-0.20211109033403-d894d75b7f09 h1:A95M6UWcfZgOuJkQ7QLfG0Hs5peWIUSysCDNz4pfe04= diff --git a/handler/auto/handler.go b/handler/auto/handler.go index 573a705..828b18e 100644 --- a/handler/auto/handler.go +++ b/handler/auto/handler.go @@ -6,11 +6,11 @@ import ( "net" "time" - netpkg "github.com/go-gost/core/common/net" "github.com/go-gost/core/handler" md "github.com/go-gost/core/metadata" "github.com/go-gost/gosocks4" "github.com/go-gost/gosocks5" + netpkg "github.com/go-gost/x/internal/net" "github.com/go-gost/x/registry" ) diff --git a/handler/forward/local/handler.go b/handler/forward/local/handler.go index 47d8ba8..c84823a 100644 --- a/handler/forward/local/handler.go +++ b/handler/forward/local/handler.go @@ -8,9 +8,9 @@ import ( "time" "github.com/go-gost/core/chain" - netpkg "github.com/go-gost/core/common/net" "github.com/go-gost/core/handler" md "github.com/go-gost/core/metadata" + netpkg "github.com/go-gost/x/internal/net" "github.com/go-gost/x/registry" ) diff --git a/handler/forward/remote/handler.go b/handler/forward/remote/handler.go index 14d2760..776acf8 100644 --- a/handler/forward/remote/handler.go +++ b/handler/forward/remote/handler.go @@ -8,9 +8,9 @@ import ( "time" "github.com/go-gost/core/chain" - netpkg "github.com/go-gost/core/common/net" "github.com/go-gost/core/handler" md "github.com/go-gost/core/metadata" + netpkg "github.com/go-gost/x/internal/net" "github.com/go-gost/x/registry" ) diff --git a/handler/http/handler.go b/handler/http/handler.go index 2745e5a..88ca5c4 100644 --- a/handler/http/handler.go +++ b/handler/http/handler.go @@ -17,10 +17,10 @@ import ( "github.com/asaskevich/govalidator" "github.com/go-gost/core/chain" - netpkg "github.com/go-gost/core/common/net" "github.com/go-gost/core/handler" "github.com/go-gost/core/logger" md "github.com/go-gost/core/metadata" + netpkg "github.com/go-gost/x/internal/net" "github.com/go-gost/x/registry" ) diff --git a/handler/http/udp.go b/handler/http/udp.go index d02413c..5dbc10b 100644 --- a/handler/http/udp.go +++ b/handler/http/udp.go @@ -8,8 +8,8 @@ import ( "net/http/httputil" "time" - "github.com/go-gost/core/common/net/relay" "github.com/go-gost/core/logger" + "github.com/go-gost/x/internal/net/udp" "github.com/go-gost/x/internal/util/socks" ) @@ -65,7 +65,7 @@ func (h *httpHandler) handleUDP(ctx context.Context, conn net.Conn, log logger.L return err } - relay := relay.NewUDPRelay(socks.UDPTunServerConn(conn), pc). + relay := udp.NewRelay(socks.UDPTunServerConn(conn), pc). WithBypass(h.options.Bypass). WithLogger(log) diff --git a/handler/http2/handler.go b/handler/http2/handler.go index 11dc348..e775468 100644 --- a/handler/http2/handler.go +++ b/handler/http2/handler.go @@ -19,10 +19,10 @@ import ( "time" "github.com/go-gost/core/chain" - netpkg "github.com/go-gost/core/common/net" "github.com/go-gost/core/handler" "github.com/go-gost/core/logger" md "github.com/go-gost/core/metadata" + netpkg "github.com/go-gost/x/internal/net" "github.com/go-gost/x/registry" ) diff --git a/handler/redirect/tcp/handler.go b/handler/redirect/tcp/handler.go index 2cabbc5..55285c2 100644 --- a/handler/redirect/tcp/handler.go +++ b/handler/redirect/tcp/handler.go @@ -14,11 +14,11 @@ import ( "time" "github.com/go-gost/core/chain" - netpkg "github.com/go-gost/core/common/net" "github.com/go-gost/core/handler" "github.com/go-gost/core/logger" md "github.com/go-gost/core/metadata" dissector "github.com/go-gost/tls-dissector" + netpkg "github.com/go-gost/x/internal/net" "github.com/go-gost/x/registry" ) diff --git a/handler/redirect/udp/handler.go b/handler/redirect/udp/handler.go index f9fe7b5..782acdc 100644 --- a/handler/redirect/udp/handler.go +++ b/handler/redirect/udp/handler.go @@ -7,9 +7,9 @@ import ( "time" "github.com/go-gost/core/chain" - netpkg "github.com/go-gost/core/common/net" "github.com/go-gost/core/handler" md "github.com/go-gost/core/metadata" + netpkg "github.com/go-gost/x/internal/net" "github.com/go-gost/x/registry" ) diff --git a/handler/relay/bind.go b/handler/relay/bind.go index 0f79b2b..87f406a 100644 --- a/handler/relay/bind.go +++ b/handler/relay/bind.go @@ -6,10 +6,10 @@ import ( "net" "time" - netpkg "github.com/go-gost/core/common/net" - net_relay "github.com/go-gost/core/common/net/relay" "github.com/go-gost/core/logger" "github.com/go-gost/relay" + netpkg "github.com/go-gost/x/internal/net" + "github.com/go-gost/x/internal/net/udp" "github.com/go-gost/x/internal/util/mux" relay_util "github.com/go-gost/x/internal/util/relay" ) @@ -113,7 +113,7 @@ func (h *relayHandler) bindUDP(ctx context.Context, conn net.Conn, network, addr }) log.Debugf("bind on %s OK", pc.LocalAddr()) - r := net_relay.NewUDPRelay(relay_util.UDPTunServerConn(conn), pc). + r := udp.NewRelay(relay_util.UDPTunServerConn(conn), pc). WithBypass(h.options.Bypass). WithLogger(log) r.SetBufferSize(h.md.udpBufferSize) diff --git a/handler/relay/connect.go b/handler/relay/connect.go index cd326aa..4492bcb 100644 --- a/handler/relay/connect.go +++ b/handler/relay/connect.go @@ -7,9 +7,9 @@ import ( "net" "time" - netpkg "github.com/go-gost/core/common/net" "github.com/go-gost/core/logger" "github.com/go-gost/relay" + netpkg "github.com/go-gost/x/internal/net" ) func (h *relayHandler) handleConnect(ctx context.Context, conn net.Conn, network, address string, log logger.Logger) error { diff --git a/handler/relay/forward.go b/handler/relay/forward.go index 03bd91f..55a88a8 100644 --- a/handler/relay/forward.go +++ b/handler/relay/forward.go @@ -7,9 +7,9 @@ import ( "net" "time" - netpkg "github.com/go-gost/core/common/net" "github.com/go-gost/core/logger" "github.com/go-gost/relay" + netpkg "github.com/go-gost/x/internal/net" ) func (h *relayHandler) handleForward(ctx context.Context, conn net.Conn, network string, log logger.Logger) error { diff --git a/handler/sni/handler.go b/handler/sni/handler.go index da1c2e9..918b49e 100644 --- a/handler/sni/handler.go +++ b/handler/sni/handler.go @@ -13,10 +13,10 @@ import ( "github.com/go-gost/core/chain" "github.com/go-gost/core/common/bufpool" - netpkg "github.com/go-gost/core/common/net" "github.com/go-gost/core/handler" md "github.com/go-gost/core/metadata" dissector "github.com/go-gost/tls-dissector" + netpkg "github.com/go-gost/x/internal/net" "github.com/go-gost/x/registry" ) diff --git a/handler/socks/v4/handler.go b/handler/socks/v4/handler.go index e9be353..9a88a9d 100644 --- a/handler/socks/v4/handler.go +++ b/handler/socks/v4/handler.go @@ -7,11 +7,11 @@ import ( "time" "github.com/go-gost/core/chain" - netpkg "github.com/go-gost/core/common/net" "github.com/go-gost/core/handler" "github.com/go-gost/core/logger" md "github.com/go-gost/core/metadata" "github.com/go-gost/gosocks4" + netpkg "github.com/go-gost/x/internal/net" "github.com/go-gost/x/registry" ) diff --git a/handler/socks/v5/bind.go b/handler/socks/v5/bind.go index 89299fc..f566f8b 100644 --- a/handler/socks/v5/bind.go +++ b/handler/socks/v5/bind.go @@ -6,9 +6,9 @@ import ( "net" "time" - netpkg "github.com/go-gost/core/common/net" "github.com/go-gost/core/logger" "github.com/go-gost/gosocks5" + netpkg "github.com/go-gost/x/internal/net" ) func (h *socks5Handler) handleBind(ctx context.Context, conn net.Conn, network, address string, log logger.Logger) error { diff --git a/handler/socks/v5/connect.go b/handler/socks/v5/connect.go index 88a8deb..528d7bf 100644 --- a/handler/socks/v5/connect.go +++ b/handler/socks/v5/connect.go @@ -6,9 +6,9 @@ import ( "net" "time" - netpkg "github.com/go-gost/core/common/net" "github.com/go-gost/core/logger" "github.com/go-gost/gosocks5" + netpkg "github.com/go-gost/x/internal/net" ) func (h *socks5Handler) handleConnect(ctx context.Context, conn net.Conn, network, address string, log logger.Logger) error { diff --git a/handler/socks/v5/mbind.go b/handler/socks/v5/mbind.go index 5a99259..15cef00 100644 --- a/handler/socks/v5/mbind.go +++ b/handler/socks/v5/mbind.go @@ -6,9 +6,9 @@ import ( "net" "time" - netpkg "github.com/go-gost/core/common/net" "github.com/go-gost/core/logger" "github.com/go-gost/gosocks5" + netpkg "github.com/go-gost/x/internal/net" "github.com/go-gost/x/internal/util/mux" ) diff --git a/handler/socks/v5/udp.go b/handler/socks/v5/udp.go index d56b4e3..8d52af3 100644 --- a/handler/socks/v5/udp.go +++ b/handler/socks/v5/udp.go @@ -9,9 +9,9 @@ import ( "net" "time" - "github.com/go-gost/core/common/net/relay" "github.com/go-gost/core/logger" "github.com/go-gost/gosocks5" + "github.com/go-gost/x/internal/net/udp" "github.com/go-gost/x/internal/util/socks" ) @@ -68,7 +68,7 @@ func (h *socks5Handler) handleUDP(ctx context.Context, conn net.Conn, log logger return err } - r := relay.NewUDPRelay(socks.UDPConn(cc, h.md.udpBufferSize), pc). + r := udp.NewRelay(socks.UDPConn(cc, h.md.udpBufferSize), pc). WithBypass(h.options.Bypass). WithLogger(log) r.SetBufferSize(h.md.udpBufferSize) diff --git a/handler/socks/v5/udp_tun.go b/handler/socks/v5/udp_tun.go index deb4028..34a12fa 100644 --- a/handler/socks/v5/udp_tun.go +++ b/handler/socks/v5/udp_tun.go @@ -5,9 +5,9 @@ import ( "net" "time" - "github.com/go-gost/core/common/net/relay" "github.com/go-gost/core/logger" "github.com/go-gost/gosocks5" + "github.com/go-gost/x/internal/net/udp" "github.com/go-gost/x/internal/util/socks" ) @@ -56,7 +56,7 @@ func (h *socks5Handler) handleUDPTun(ctx context.Context, conn net.Conn, network log.Debug(reply) log.Debugf("bind on %s OK", pc.LocalAddr()) - r := relay.NewUDPRelay(socks.UDPTunServerConn(conn), pc). + r := udp.NewRelay(socks.UDPTunServerConn(conn), pc). WithBypass(h.options.Bypass). WithLogger(log) r.SetBufferSize(h.md.udpBufferSize) diff --git a/handler/ss/handler.go b/handler/ss/handler.go index df7bb52..1094dcb 100644 --- a/handler/ss/handler.go +++ b/handler/ss/handler.go @@ -8,10 +8,10 @@ import ( "time" "github.com/go-gost/core/chain" - netpkg "github.com/go-gost/core/common/net" "github.com/go-gost/core/handler" md "github.com/go-gost/core/metadata" "github.com/go-gost/gosocks5" + netpkg "github.com/go-gost/x/internal/net" "github.com/go-gost/x/internal/util/ss" "github.com/go-gost/x/registry" "github.com/shadowsocks/go-shadowsocks2/core" diff --git a/handler/sshd/handler.go b/handler/sshd/handler.go index c55ca2f..62cf5bc 100644 --- a/handler/sshd/handler.go +++ b/handler/sshd/handler.go @@ -10,10 +10,10 @@ import ( "time" "github.com/go-gost/core/chain" - netpkg "github.com/go-gost/core/common/net" "github.com/go-gost/core/handler" "github.com/go-gost/core/logger" md "github.com/go-gost/core/metadata" + netpkg "github.com/go-gost/x/internal/net" sshd_util "github.com/go-gost/x/internal/util/sshd" "github.com/go-gost/x/registry" "golang.org/x/crypto/ssh" diff --git a/internal/net/transport.go b/internal/net/transport.go new file mode 100644 index 0000000..006a360 --- /dev/null +++ b/internal/net/transport.go @@ -0,0 +1,50 @@ +package net + +import ( + "bufio" + "io" + "net" + + "github.com/go-gost/core/common/bufpool" +) + +func Transport(rw1, rw2 io.ReadWriter) error { + errc := make(chan error, 1) + go func() { + errc <- copyBuffer(rw1, rw2) + }() + + go func() { + errc <- copyBuffer(rw2, rw1) + }() + + err := <-errc + if err != nil && err == io.EOF { + err = nil + } + return err +} + +func copyBuffer(dst io.Writer, src io.Reader) error { + buf := bufpool.Get(32 * 1024) + defer bufpool.Put(buf) + + _, err := io.CopyBuffer(dst, src, *buf) + return err +} + +type bufferReaderConn struct { + net.Conn + br *bufio.Reader +} + +func NewBufferReaderConn(conn net.Conn, br *bufio.Reader) net.Conn { + return &bufferReaderConn{ + Conn: conn, + br: br, + } +} + +func (c *bufferReaderConn) Read(b []byte) (int, error) { + return c.br.Read(b) +} diff --git a/internal/net/udp/relay.go b/internal/net/udp/relay.go new file mode 100644 index 0000000..e41798e --- /dev/null +++ b/internal/net/udp/relay.go @@ -0,0 +1,126 @@ +package udp + +import ( + "net" + + "github.com/go-gost/core/bypass" + "github.com/go-gost/core/common/bufpool" + "github.com/go-gost/core/logger" +) + +type Relay struct { + pc1 net.PacketConn + pc2 net.PacketConn + + bypass bypass.Bypass + bufferSize int + logger logger.Logger +} + +func NewRelay(pc1, pc2 net.PacketConn) *Relay { + return &Relay{ + pc1: pc1, + pc2: pc2, + } +} + +func (r *Relay) WithBypass(bp bypass.Bypass) *Relay { + r.bypass = bp + return r +} + +func (r *Relay) WithLogger(logger logger.Logger) *Relay { + r.logger = logger + return r +} + +func (r *Relay) SetBufferSize(n int) { + r.bufferSize = n +} + +func (r *Relay) Run() (err error) { + bufSize := r.bufferSize + if bufSize <= 0 { + bufSize = 1500 + } + + errc := make(chan error, 2) + + go func() { + for { + err := func() error { + b := bufpool.Get(bufSize) + defer bufpool.Put(b) + + n, raddr, err := r.pc1.ReadFrom(*b) + if err != nil { + return err + } + + if r.bypass != nil && r.bypass.Contains(raddr.String()) { + if r.logger != nil { + r.logger.Warn("bypass: ", raddr) + } + return nil + } + + if _, err := r.pc2.WriteTo((*b)[:n], raddr); err != nil { + return err + } + + if r.logger != nil { + r.logger.Debugf("%s >>> %s data: %d", + r.pc2.LocalAddr(), raddr, n) + + } + + return nil + }() + + if err != nil { + errc <- err + return + } + } + }() + + go func() { + for { + err := func() error { + b := bufpool.Get(bufSize) + defer bufpool.Put(b) + + n, raddr, err := r.pc2.ReadFrom(*b) + if err != nil { + return err + } + + if r.bypass != nil && r.bypass.Contains(raddr.String()) { + if r.logger != nil { + r.logger.Warn("bypass: ", raddr) + } + return nil + } + + if _, err := r.pc1.WriteTo((*b)[:n], raddr); err != nil { + return err + } + + if r.logger != nil { + r.logger.Debugf("%s <<< %s data: %d", + r.pc2.LocalAddr(), raddr, n) + + } + + return nil + }() + + if err != nil { + errc <- err + return + } + } + }() + + return <-errc +} diff --git a/metrics/metrics.go b/metrics/metrics.go new file mode 100644 index 0000000..c9f0ad7 --- /dev/null +++ b/metrics/metrics.go @@ -0,0 +1,135 @@ +package metrics + +import ( + "os" + + "github.com/go-gost/core/metrics" + "github.com/prometheus/client_golang/prometheus" +) + +type promMetrics struct { + host string + gauges map[metrics.MetricName]*prometheus.GaugeVec + counters map[metrics.MetricName]*prometheus.CounterVec + histograms map[metrics.MetricName]*prometheus.HistogramVec +} + +func NewMetrics() metrics.Metrics { + host, _ := os.Hostname() + m := &promMetrics{ + host: host, + gauges: map[metrics.MetricName]*prometheus.GaugeVec{ + metrics.MetricServicesGauge: prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: string(metrics.MetricServicesGauge), + Help: "Current number of services", + }, + []string{"host"}), + metrics.MetricServiceRequestsInFlightGauge: prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Name: string(metrics.MetricServiceRequestsInFlightGauge), + Help: "Current in-flight requests", + }, + []string{"host", "service"}), + }, + counters: map[metrics.MetricName]*prometheus.CounterVec{ + metrics.MetricServiceRequestsCounter: prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: string(metrics.MetricServiceRequestsCounter), + Help: "Total number of requests", + }, + []string{"host", "service"}), + metrics.MetricServiceTransferInputBytesCounter: prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: string(metrics.MetricServiceTransferInputBytesCounter), + Help: "Total service input data transfer size in bytes", + }, + []string{"host", "service"}), + metrics.MetricServiceTransferOutputBytesCounter: prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: string(metrics.MetricServiceTransferOutputBytesCounter), + Help: "Total service output data transfer size in bytes", + }, + []string{"host", "service"}), + metrics.MetricServiceHandlerErrorsCounter: prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: string(metrics.MetricServiceHandlerErrorsCounter), + Help: "Total service handler errors", + }, + []string{"host", "service"}), + metrics.MetricChainErrorsCounter: prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: string(metrics.MetricChainErrorsCounter), + Help: "Total chain errors", + }, + []string{"host", "chain"}), + }, + histograms: map[metrics.MetricName]*prometheus.HistogramVec{ + metrics.MetricServiceRequestsDurationObserver: prometheus.NewHistogramVec( + prometheus.HistogramOpts{ + Name: string(metrics.MetricServiceRequestsDurationObserver), + Help: "Distribution of request latencies", + Buckets: []float64{ + .005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10, 15, 30, 60, + }, + }, + []string{"host", "service"}), + metrics.MetricNodeConnectDurationObserver: prometheus.NewHistogramVec( + prometheus.HistogramOpts{ + Name: string(metrics.MetricNodeConnectDurationObserver), + Help: "Distribution of chain node connect latencies", + Buckets: []float64{ + .01, .05, .1, .25, .5, 1, 1.5, 2, 5, 10, 15, 30, 60, + }, + }, + []string{"host", "chain", "node"}), + }, + } + for k := range m.gauges { + prometheus.MustRegister(m.gauges[k]) + } + for k := range m.counters { + prometheus.MustRegister(m.counters[k]) + } + for k := range m.histograms { + prometheus.MustRegister(m.histograms[k]) + } + + return m +} + +func (m *promMetrics) Gauge(name metrics.MetricName, labels metrics.Labels) metrics.Gauge { + v, ok := m.gauges[name] + if !ok { + return nil + } + if labels == nil { + labels = metrics.Labels{} + } + labels["host"] = m.host + return v.With(prometheus.Labels(labels)) +} + +func (m *promMetrics) Counter(name metrics.MetricName, labels metrics.Labels) metrics.Counter { + v, ok := m.counters[name] + if !ok { + return nil + } + if labels == nil { + labels = metrics.Labels{} + } + labels["host"] = m.host + return v.With(prometheus.Labels(labels)) +} + +func (m *promMetrics) Observer(name metrics.MetricName, labels metrics.Labels) metrics.Observer { + v, ok := m.histograms[name] + if !ok { + return nil + } + if labels == nil { + labels = metrics.Labels{} + } + labels["host"] = m.host + return v.With(prometheus.Labels(labels)) +} diff --git a/metrics/service/service.go b/metrics/service/service.go new file mode 100644 index 0000000..5eba0bb --- /dev/null +++ b/metrics/service/service.go @@ -0,0 +1,65 @@ +package service + +import ( + "net" + "net/http" + + "github.com/prometheus/client_golang/prometheus/promhttp" +) + +const ( + DefaultPath = "/metrics" +) + +type options struct { + path string +} + +type Option func(*options) + +func PathOption(path string) Option { + return func(o *options) { + o.path = path + } +} + +type Service struct { + s *http.Server + ln net.Listener +} + +func NewService(addr string, opts ...Option) (*Service, error) { + ln, err := net.Listen("tcp", addr) + if err != nil { + return nil, err + } + + var options options + for _, opt := range opts { + opt(&options) + } + if options.path == "" { + options.path = DefaultPath + } + + mux := http.NewServeMux() + mux.Handle(options.path, promhttp.Handler()) + return &Service{ + s: &http.Server{ + Handler: mux, + }, + ln: ln, + }, nil +} + +func (s *Service) Serve() error { + return s.s.Serve(s.ln) +} + +func (s *Service) Addr() net.Addr { + return s.ln.Addr() +} + +func (s *Service) Close() error { + return s.s.Close() +}