Skip to content
This repository has been archived by the owner on May 26, 2022. It is now read-only.

Commit

Permalink
add bandwidth-related metrics (for Linux and OSX)
Browse files Browse the repository at this point in the history
  • Loading branch information
marten-seemann committed Apr 12, 2021
1 parent d3fdb0f commit 586c623
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 0 deletions.
54 changes: 54 additions & 0 deletions metrics.go
Expand Up @@ -49,6 +49,10 @@ type aggregatingCollector struct {
conns map[uint64] /* id */ *tracingConn
rtts prometheus.Histogram
connDurations prometheus.Histogram
segsSentDesc *prometheus.Desc
segsRcvdDesc *prometheus.Desc
bytesSentDesc *prometheus.Desc
bytesRcvdDesc *prometheus.Desc
}

var _ prometheus.Collector = &aggregatingCollector{}
Expand All @@ -66,6 +70,10 @@ func newAggregatingCollector() *aggregatingCollector {
Help: "TCP Connection Duration",
Buckets: prometheus.ExponentialBuckets(1, 1.5, 40), // 1s to ~12 weeks
}),
segsSentDesc: prometheus.NewDesc("tcp_sent_segments_total", "TCP segments sent", nil, nil),
segsRcvdDesc: prometheus.NewDesc("tcp_rcvd_segments_total", "TCP segments received", nil, nil),
bytesSentDesc: prometheus.NewDesc("tcp_sent_bytes", "TCP bytes sent", nil, nil),
bytesRcvdDesc: prometheus.NewDesc("tcp_rcvd_bytes", "TCP bytes received", nil, nil),
}
}

Expand All @@ -84,11 +92,21 @@ func (c *aggregatingCollector) removeConn(id uint64) {
func (c *aggregatingCollector) Describe(descs chan<- *prometheus.Desc) {
descs <- c.rtts.Desc()
descs <- c.connDurations.Desc()
if hasSegmentCounter {
descs <- c.segsSentDesc
descs <- c.segsRcvdDesc
}
if hasByteCounter {
descs <- c.bytesSentDesc
descs <- c.bytesRcvdDesc
}
}

func (c *aggregatingCollector) Collect(metrics chan<- prometheus.Metric) {
now := time.Now()
c.mutex.Lock()
var segsSent, segsRcvd uint64
var bytesSent, bytesRcvd uint64
for _, conn := range c.conns {
info, err := conn.getTCPInfo()
if err != nil {
Expand All @@ -99,6 +117,14 @@ func (c *aggregatingCollector) Collect(metrics chan<- prometheus.Metric) {
log.Errorf("Failed to get TCP info: %s", err)
continue
}
if hasSegmentCounter {
segsSent += getSegmentsSent(info)
segsRcvd += getSegmentsRcvd(info)
}
if hasByteCounter {
bytesSent += getBytesSent(info)
bytesRcvd += getBytesRcvd(info)
}
c.rtts.Observe(info.RTT.Seconds())
c.connDurations.Observe(now.Sub(conn.startTime).Seconds())
if info.State == tcpinfo.Closed {
Expand All @@ -108,6 +134,34 @@ func (c *aggregatingCollector) Collect(metrics chan<- prometheus.Metric) {
c.mutex.Unlock()
metrics <- c.rtts
metrics <- c.connDurations
if hasSegmentCounter {
segsSentMetric, err := prometheus.NewConstMetric(c.segsSentDesc, prometheus.CounterValue, float64(segsSent))
if err != nil {
log.Errorf("creating tcp_sent_segments_total metric failed: %v", err)
return
}
segsRcvdMetric, err := prometheus.NewConstMetric(c.segsRcvdDesc, prometheus.CounterValue, float64(segsRcvd))
if err != nil {
log.Errorf("creating tcp_rcvd_segments_total metric failed: %v", err)
return
}
metrics <- segsSentMetric
metrics <- segsRcvdMetric
}
if hasByteCounter {
bytesSentMetric, err := prometheus.NewConstMetric(c.bytesSentDesc, prometheus.CounterValue, float64(bytesSent))
if err != nil {
log.Errorf("creating tcp_sent_bytes metric failed: %v", err)
return
}
bytesRcvdMetric, err := prometheus.NewConstMetric(c.bytesRcvdDesc, prometheus.CounterValue, float64(bytesRcvd))
if err != nil {
log.Errorf("creating tcp_rcvd_segments_total metric failed: %v", err)
return
}
metrics <- bytesSentMetric
metrics <- bytesRcvdMetric
}
}

func (c *aggregatingCollector) closedConn(conn *tracingConn) {
Expand Down
15 changes: 15 additions & 0 deletions metrics_darwin.go
@@ -0,0 +1,15 @@
//+build darwin

package tcp

import "github.com/mikioh/tcpinfo"

const (
hasSegmentCounter = true
hasByteCounter = true
)

func getSegmentsSent(info *tcpinfo.Info) uint64 { return info.Sys.SegsSent }
func getSegmentsRcvd(info *tcpinfo.Info) uint64 { return info.Sys.SegsReceived }
func getBytesSent(info *tcpinfo.Info) uint64 { return info.Sys.BytesSent }
func getBytesRcvd(info *tcpinfo.Info) uint64 { return info.Sys.BytesReceived }
15 changes: 15 additions & 0 deletions metrics_general.go
@@ -0,0 +1,15 @@
//+build !linux,!darwin

package tcp

import "github.com/mikioh/tcpinfo"

const (
hasSegmentCounter = false
hasByteCounter = false
)

func getSegmentsSent(info *tcpinfo.Info) uint64 { return 0 }
func getSegmentsRcvd(info *tcpinfo.Info) uint64 { return 0 }
func getBytesSent(info *tcpinfo.Info) uint64 { return 0 }
func getBytesRcvd(info *tcpinfo.Info) uint64 { return 0 }
15 changes: 15 additions & 0 deletions metrics_linux.go
@@ -0,0 +1,15 @@
//+build linux

package tcp

import "github.com/mikioh/tcpinfo"

const (
hasSegmentCounter = true
hasByteCounter = false
)

func getSegmentsSent(info *tcpinfo.Info) uint64 { return uint64(info.Sys.SegsOut) }
func getSegmentsRcvd(info *tcpinfo.Info) uint64 { return uint64(info.Sys.SegsIn) }
func getBytesSent(info *tcpinfo.Info) uint64 { return 0 }
func getBytesRcvd(info *tcpinfo.Info) uint64 { return 0 }

0 comments on commit 586c623

Please sign in to comment.