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

[network] use netstat for windows network monitoring #2759

Closed
wants to merge 1 commit into from
Closed
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
53 changes: 53 additions & 0 deletions checks.d/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,19 @@ class Network(AgentCheck):
"LAST_ACK": "closing",
"LISTEN": "listening",
"CLOSING": "closing",
},
"windows": {
"ESTABLISHED": "established",
"SYN_SEND": "opening",
"SYN_RECEIVED": "opening",
"FIN_WAIT_1": "closing",
"FIN_WAIT_2": "closing",
"TIME_WAIT": "time_wait",
"CLOSED": "closing",
"CLOSE_WAIT": "closing",
"LAST_ACK": "closing",
"LISTENING": "listening",
"CLOSING": "closing",
}
}

Expand Down Expand Up @@ -101,6 +114,8 @@ def check(self, instance):
self._check_bsd(instance)
elif Platform.is_solaris():
self._check_solaris(instance)
elif Platform.is_win32():
self._check_win32(instance)

def _submit_devicemetrics(self, iface, vals_by_metric):
if iface in self._excluded_ifaces or (self._exclude_iface_re and self._exclude_iface_re.match(iface)):
Expand Down Expand Up @@ -515,3 +530,41 @@ def _parse_solaris_netstat(self, netstat_output):
metrics_by_interface[iface] = metrics

return metrics_by_interface

def _check_win32(self, instance):
try:
netstat, _, _ = get_subprocess_output(["netstat", "-a", "-n"], self.log)
# Here's an example of the netstat output:
#
# Active Connections
# Proto Local Address Foreign Address State
# TCP 46.105.75.4:80 79.220.227.193:2032 SYN_RECV
# TCP 46.105.75.4:143 90.56.111.177:56867 ESTABLISHED
# TCP 46.105.75.4:50468 107.20.207.175:443 TIME_WAIT
# TCP 46.105.75.4:80 93.15.237.188:58038 FIN_WAIT2
# TCP 46.105.75.4:80 79.220.227.193:2029 ESTABLISHED
# UDP 0.0.0.0:123 0.0.0.0:*
# UDP :::41458 :::*

lines = netstat.split("\r\n")

metrics = dict.fromkeys(self.CX_STATE_GAUGE.values(), 0)
for l in lines[4:-1]:
cols = l.split()
# 0 1 2 3
# TCP 46.105.75.4:143 90.56.111.177:56867 ESTABLISHED
# tcp4 only right now
if cols[0].startswith("TCP"):
protocol = ("tcp4", "tcp6")[cols[0] == "tcp6"]
if cols[3] in self.TCP_STATES['windows']:
metric = self.CX_STATE_GAUGE[protocol, self.TCP_STATES['windows'][cols[3]]]
metrics[metric] += 1
elif cols[0].startswith("UDP"):
protocol = ("udp4", "udp6")[cols[0] == "udp6"]
metric = self.CX_STATE_GAUGE[protocol, 'connections']
metrics[metric] += 1

for metric, value in metrics.iteritems():
self.gauge(metric, value)
except SubprocessOutputEmptyError:
self.log.exception("Error collecting connection stats.")