mirror of
https://github.com/prometheus/node_exporter.git
synced 2024-12-03 15:31:05 +01:00
Add collector for /proc/net/tcp
This commit is contained in:
parent
aaf01e52e2
commit
e4da771b21
@ -46,6 +46,7 @@ lastlogin | Exposes the last time there was a login.
|
|||||||
megacli | Exposes RAID statistics from MegaCLI.
|
megacli | Exposes RAID statistics from MegaCLI.
|
||||||
ntp | Exposes time drift from an NTP server.
|
ntp | Exposes time drift from an NTP server.
|
||||||
runit | Exposes service status from [runit](http://smarden.org/runit/).
|
runit | Exposes service status from [runit](http://smarden.org/runit/).
|
||||||
|
tcpstat | Exposes TCP connection status information from /proc/net/tcp and /proc/net/tcp6. (Warning: the current version has potential performance issues in high load situations.)
|
||||||
|
|
||||||
## Textfile Collector
|
## Textfile Collector
|
||||||
|
|
||||||
|
3
collector/fixtures/tcpstat
Normal file
3
collector/fixtures/tcpstat
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
|
||||||
|
0: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 2740 1 ffff88003d3af3c0 100 0 0 10 0
|
||||||
|
1: 0F02000A:0016 0202000A:8B6B 01 00000000:00000000 02:000AC99B 00000000 0 0 3652 4 ffff88003d3ae040 21 4 31 47 46
|
150
collector/tcpstat.go
Normal file
150
collector/tcpstat.go
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
// +build !notcpstat
|
||||||
|
|
||||||
|
package collector
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
procTCPStat = "/proc/net/tcp"
|
||||||
|
procTCP6Stat = "/proc/net/tcp6"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TCPConnectionState int
|
||||||
|
|
||||||
|
const (
|
||||||
|
TCP_ESTABLISHED TCPConnectionState = iota + 1
|
||||||
|
TCP_SYN_SENT
|
||||||
|
TCP_SYN_RECV
|
||||||
|
TCP_FIN_WAIT1
|
||||||
|
TCP_FIN_WAIT2
|
||||||
|
TCP_TIME_WAIT
|
||||||
|
TCP_CLOSE
|
||||||
|
TCP_CLOSE_WAIT
|
||||||
|
TCP_LAST_ACK
|
||||||
|
TCP_LISTEN
|
||||||
|
TCP_CLOSING
|
||||||
|
)
|
||||||
|
|
||||||
|
type tcpStatCollector struct {
|
||||||
|
config Config
|
||||||
|
metric *prometheus.GaugeVec
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Factories["tcpstat"] = NewTCPStatCollector
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTCPStatCollector takes a config struct and returns
|
||||||
|
// a new Collector exposing network stats.
|
||||||
|
func NewTCPStatCollector(config Config) (Collector, error) {
|
||||||
|
return &tcpStatCollector{
|
||||||
|
config: config,
|
||||||
|
metric: prometheus.NewGaugeVec(
|
||||||
|
prometheus.GaugeOpts{
|
||||||
|
Namespace: Namespace,
|
||||||
|
Name: "tcp_connection_states",
|
||||||
|
Help: "Number of connection states.",
|
||||||
|
},
|
||||||
|
[]string{"state"},
|
||||||
|
),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *tcpStatCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
||||||
|
tcpStats, err := getTCPStats(procTCPStat)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("couldn't get tcpstats: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// if enabled ipv6 system
|
||||||
|
if _, hasIPv6 := os.Stat(procTCP6Stat); hasIPv6 == nil {
|
||||||
|
tcp6Stats, err := getTCPStats(procTCP6Stat)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("couldn't get tcp6stats: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for st, value := range tcp6Stats {
|
||||||
|
tcpStats[st] += value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for st, value := range tcpStats {
|
||||||
|
c.metric.WithLabelValues(st.String()).Set(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.metric.Collect(ch)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTCPStats(statsFile string) (map[TCPConnectionState]float64, error) {
|
||||||
|
file, err := os.Open(statsFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
return parseTCPStats(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseTCPStats(r io.Reader) (map[TCPConnectionState]float64, error) {
|
||||||
|
var (
|
||||||
|
tcpStats = map[TCPConnectionState]float64{}
|
||||||
|
scanner = bufio.NewScanner(r)
|
||||||
|
)
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
parts := strings.Fields(scanner.Text())
|
||||||
|
if len(parts) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(parts[0], "sl") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
st, err := strconv.ParseInt(parts[3], 16, 8)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tcpStats[TCPConnectionState(st)]++
|
||||||
|
}
|
||||||
|
|
||||||
|
return tcpStats, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (st TCPConnectionState) String() string {
|
||||||
|
switch st {
|
||||||
|
case TCP_ESTABLISHED:
|
||||||
|
return "established"
|
||||||
|
case TCP_SYN_SENT:
|
||||||
|
return "syn_sent"
|
||||||
|
case TCP_SYN_RECV:
|
||||||
|
return "syn_recv"
|
||||||
|
case TCP_FIN_WAIT1:
|
||||||
|
return "fin_wait1"
|
||||||
|
case TCP_FIN_WAIT2:
|
||||||
|
return "fin_wait2"
|
||||||
|
case TCP_TIME_WAIT:
|
||||||
|
return "time_wait"
|
||||||
|
case TCP_CLOSE:
|
||||||
|
return "close"
|
||||||
|
case TCP_CLOSE_WAIT:
|
||||||
|
return "close_wait"
|
||||||
|
case TCP_LAST_ACK:
|
||||||
|
return "last_ack"
|
||||||
|
case TCP_LISTEN:
|
||||||
|
return "listen"
|
||||||
|
case TCP_CLOSING:
|
||||||
|
return "closing"
|
||||||
|
default:
|
||||||
|
return "unknown"
|
||||||
|
}
|
||||||
|
}
|
27
collector/tcpstat_test.go
Normal file
27
collector/tcpstat_test.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package collector
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTCPStat(t *testing.T) {
|
||||||
|
file, err := os.Open("fixtures/tcpstat")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
tcpStats, err := parseTCPStats(file)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if want, got := 1, int(tcpStats[TCP_ESTABLISHED]); want != got {
|
||||||
|
t.Errorf("want tcpstat number of established state %d, got %d", want, got)
|
||||||
|
}
|
||||||
|
|
||||||
|
if want, got := 1, int(tcpStats[TCP_LISTEN]); want != got {
|
||||||
|
t.Errorf("want tcpstat number of listen state %d, got %d", want, got)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user