Skip to content

Commit

Permalink
Merge pull request #48 from mysteriumnetwork/add-metrics-label-hostname
Browse files Browse the repository at this point in the history
Add normalized hostname into metrics labels
  • Loading branch information
soffokl authored Aug 27, 2024
2 parents 5eacf28 + 7bf4fb8 commit 37a43e1
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 22 deletions.
27 changes: 17 additions & 10 deletions metrics/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,14 @@ package metrics
import (
"time"

"github.com/mysteriumnetwork/openvpn-forwarder/proxy"
"github.com/prometheus/client_golang/prometheus"

"github.com/mysteriumnetwork/openvpn-forwarder/proxy"
)

type service struct {
proxyRequestDuration *prometheus.HistogramVec
proxyNumberOfLiveConnecions *prometheus.GaugeVec
proxyNumberOfLiveConnections *prometheus.GaugeVec
proxyNumberOfProcessedConnections *prometheus.CounterVec
}

Expand All @@ -35,7 +36,7 @@ func NewMetricsService() (*service, error) {
proxyRequestDuration := prometheus.NewHistogramVec(prometheus.HistogramOpts{
Name: "proxy_request_duration",
Help: "Proxy request duration in seconds",
}, []string{"request_type"})
}, []string{"request_type", "hostname"})

if err := prometheus.Register(proxyRequestDuration); err != nil {
return nil, err
Expand All @@ -44,7 +45,7 @@ func NewMetricsService() (*service, error) {
proxyNumberOfLiveConnections := prometheus.NewGaugeVec(prometheus.GaugeOpts{
Name: "proxy_number_of_live_connections",
Help: "Number of currently live connections",
}, []string{"request_type"})
}, []string{"request_type", "hostname"})

if err := prometheus.Register(proxyNumberOfLiveConnections); err != nil {
return nil, err
Expand All @@ -53,15 +54,15 @@ func NewMetricsService() (*service, error) {
proxyNumberOfProcessedConnections := prometheus.NewCounterVec(prometheus.CounterOpts{
Name: "proxy_number_of_processed_connections",
Help: "Number of incoming connections which were successfully assigned and processed",
}, []string{"request_type"})
}, []string{"request_type", "hostname"})

if err := prometheus.Register(proxyNumberOfProcessedConnections); err != nil {
return nil, err
}

return &service{
proxyRequestDuration: proxyRequestDuration,
proxyNumberOfLiveConnecions: proxyNumberOfLiveConnections,
proxyNumberOfLiveConnections: proxyNumberOfLiveConnections,
proxyNumberOfProcessedConnections: proxyNumberOfProcessedConnections,
}, nil
}
Expand All @@ -70,22 +71,28 @@ func (s *service) ProxyHandlerMiddleware(next func(c *proxy.Context)) func(c *pr
return func(c *proxy.Context) {
startTime := time.Now()

s.proxyNumberOfLiveConnecions.With(prometheus.Labels{
"request_type": c.RequestType(),
}).Inc()
go func() {
s.proxyNumberOfLiveConnections.With(prometheus.Labels{
"request_type": c.RequestType(),
"hostname": c.WaitHostname(),
}).Inc()
}()

next(c)

s.proxyNumberOfLiveConnecions.With(prometheus.Labels{
s.proxyNumberOfLiveConnections.With(prometheus.Labels{
"request_type": c.RequestType(),
"hostname": c.Hostname(),
}).Dec()

s.proxyRequestDuration.With(prometheus.Labels{
"request_type": c.RequestType(),
"hostname": c.Hostname(),
}).Observe(time.Since(startTime).Seconds())

s.proxyNumberOfProcessedConnections.With(prometheus.Labels{
"request_type": c.RequestType(),
"hostname": c.Hostname(),
}).Inc()
}
}
20 changes: 13 additions & 7 deletions proxy/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ var (
proxyRequestData = prometheus.NewCounterVec(prometheus.CounterOpts{
Name: "proxy_request_data",
Help: "Proxy request data in bytes",
}, []string{"request_type", "direction"})
}, []string{"request_type", "direction", "hostname"})

proxyNumberOfIncommingConnections = prometheus.NewCounterVec(prometheus.CounterOpts{
Name: "proxy_number_of_incomming_connections",
Expand Down Expand Up @@ -60,9 +60,12 @@ type Conn struct {
func (c Conn) Read(b []byte) (n int, err error) {
count, err := c.Conn.Read(b)

proxyRequestData.MustCurryWith(prometheus.Labels{
"request_type": c.Context.RequestType(),
}).WithLabelValues("received").Add(float64(count))
go func() {
proxyRequestData.MustCurryWith(prometheus.Labels{
"request_type": c.Context.RequestType(),
"hostname": c.Context.WaitHostname(),
}).WithLabelValues("received").Add(float64(count))
}()

return count, err
}
Expand All @@ -71,9 +74,12 @@ func (c Conn) Read(b []byte) (n int, err error) {
func (c Conn) Write(b []byte) (n int, err error) {
count, err := c.Conn.Write(b)

proxyRequestData.MustCurryWith(prometheus.Labels{
"request_type": c.Context.RequestType(),
}).WithLabelValues("sent").Add(float64(count))
go func() {
proxyRequestData.MustCurryWith(prometheus.Labels{
"request_type": c.Context.RequestType(),
"hostname": c.Context.WaitHostname(),
}).WithLabelValues("sent").Add(float64(count))
}()

return count, err
}
Expand Down
26 changes: 25 additions & 1 deletion proxy/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ package proxy

import (
"net"
"regexp"
"strings"
)

// Context is the Proxy context, contains useful information about every request.
Expand All @@ -27,11 +29,33 @@ type Context struct {
conn net.Conn
connOriginalDst *net.TCPAddr

hostnameSet chan struct{}
destinationHost string
destinationAddress string
}

// RequestType HTTP or HTTPS.
func (c Context) RequestType() string {
func (c *Context) RequestType() string {
return c.scheme
}

func (c *Context) setHost(host string) {
c.destinationHost = host
close(c.hostnameSet)
}

// WaitHostname waits for hostname to be set and returns it.
func (c *Context) WaitHostname() string {
<-c.hostnameSet

hostname := hostname.FindString(strings.ToLower(c.destinationHost))

return hostname
}

// Hostname returns hostname.
func (c *Context) Hostname() string {
return hostname.FindString(strings.ToLower(c.destinationHost))
}

var hostname = regexp.MustCompile(`\w+\.\w+$`)
8 changes: 4 additions & 4 deletions proxy/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func (s *proxyServer) handler(l net.Listener, f func(c *Context), scheme string)

for {
conn, err := l.Accept()
c := Context{}
c := Context{hostnameSet: make(chan struct{})}
c.scheme = scheme
c.conn = NewConn(conn, &c)

Expand Down Expand Up @@ -166,7 +166,7 @@ func (s *proxyServer) serveHTTP(c *Context) {
return
}

c.destinationHost = req.Host
c.setHost(req.Host)
c.destinationAddress = s.authorityAddr("http", c.destinationHost)
s.logAccess("HTTP request", c)

Expand Down Expand Up @@ -227,10 +227,10 @@ func (s *proxyServer) serveTLS(c *Context) {
return
}

c.destinationHost = tlsConn.Host() + ":" + port
c.setHost(tlsConn.Host() + ":" + port)
c.destinationAddress = s.authorityAddr("https", c.destinationHost)
} else if c.connOriginalDst != nil {
c.destinationHost = ""
c.setHost("")
c.destinationAddress = c.connOriginalDst.String()
s.logWarn("Cannon parse SNI in TLS request", c)
} else {
Expand Down

0 comments on commit 37a43e1

Please sign in to comment.