Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add normalized hostname into metrics labels #48

Merged
merged 2 commits into from
Aug 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading