52 from diagnostic_msgs.msg
import DiagnosticArray, DiagnosticStatus, KeyValue
54 stat_dict = {0:
'OK', 1:
'Warning', 2:
'Error'}
59 rospy.init_node(
"net_monitor")
71 self.
_diag_pub = rospy.Publisher(
'/diagnostics', DiagnosticArray, queue_size=1)
83 return fh.readline().strip()
87 return 0, self.
read_sysinfo(
'/sys/class/net/%s/statistics/%s' % (iface, sys))
93 return 0, self.
read_sysinfo(
'/sys/class/net/%s/%s' % (iface, sys))
98 level = DiagnosticStatus.OK
102 p = subprocess.Popen(
'ifstat -q -S 1 1',
103 stdout=subprocess.PIPE,
104 stderr=subprocess.PIPE, shell=
True)
105 stdout, stderr = p.communicate()
106 ret_code = p.returncode
108 stdout = stdout.decode()
109 except (UnicodeDecodeError, AttributeError):
113 values.append(KeyValue(key=
"\"ifstat -q -S 1 1\" Call Error",
114 value=str(ret_code)))
115 return DiagnosticStatus.ERROR,
'Call Error', values
116 rows = stdout.split(
'\n')
117 data = rows[0].split()
119 for i
in range(0, len(data)):
120 ifaces.append(data[i])
121 data = rows[2].split()
124 for i
in range(0, len(data), 2):
125 kb_in.append(data[i])
126 kb_out.append(data[i + 1])
127 level = DiagnosticStatus.OK
128 for i
in range(0, len(ifaces)):
129 values.append(KeyValue(key=str(i), value=
"======================="))
130 values.append(KeyValue(key=
'Interface Name',
132 (ret_code, cmd_out) = self.
get_sys_net(ifaces[i],
'operstate')
134 values.append(KeyValue(key=
'State', value=cmd_out))
135 ifacematch = re.match(
'eth[0-9]+', ifaces[i])
or re.match(
'eno[0-9]+', ifaces[i])
136 if ifacematch
and (cmd_out ==
'down' or cmd_out ==
'dormant'):
137 level = DiagnosticStatus.ERROR
138 net_msg =
'Network Down'
139 values.append(KeyValue(key=
'Input Traffic',
140 value=str(float(kb_in[i]) / 1024) +
" (MB/s)"))
if kb_in[i] !=
'n/a' else 0
141 values.append(KeyValue(key=
'Output Traffic',
142 value=str(float(kb_out[i]) / 1024) +
" (MB/s)"))
if kb_out[i] !=
'n/a' else 0
143 net_usage_in = float(kb_in[i]) / 1024 / self.
_net_capacity if kb_in[i] !=
'n/a' else 0
144 net_usage_out = float(kb_out[i]) / 1024 / self.
_net_capacity if kb_out[i] !=
'n/a' else 0
147 level = DiagnosticStatus.WARN
148 net_msg =
'High Network Usage (net_usage_in: {}, net_usage_out: {}, threshold: {})'.format(net_usage_in, net_usage_out, self.
_net_level_warn)
149 (ret_code, cmd_out) = self.
get_sys_net(ifaces[i],
'mtu')
151 values.append(KeyValue(key=
'MTU', value=cmd_out))
155 values.append(KeyValue(key=
'Total received MB',
156 value=str(float(cmd_out) / 1024 / 1024)))
159 values.append(KeyValue(key=
'Total transmitted MB',
160 value=str(float(cmd_out) / 1024 / 1024)))
163 values.append(KeyValue(key=
'collisions', value=cmd_out))
166 values.append(KeyValue(key=
'rx_errors', value=cmd_out))
169 values.append(KeyValue(key=
'rx_crc_errors', value=cmd_out))
172 values.append(KeyValue(key=
'rx_dropped', value=cmd_out))
175 values.append(KeyValue(key=
'rx_fifo_errors', value=cmd_out))
178 values.append(KeyValue(key=
'rx_frame_errors', value=cmd_out))
181 values.append(KeyValue(key=
'rx_length_errors', value=cmd_out))
184 values.append(KeyValue(key=
'rx_missed_errors', value=cmd_out))
187 values.append(KeyValue(key=
'rx_over_errors', value=cmd_out))
190 values.append(KeyValue(key=
'rx_packets', value=cmd_out))
193 values.append(KeyValue(key=
'tx_errors', value=cmd_out))
196 values.append(KeyValue(key=
'tx_aborted_errors', value=cmd_out))
199 values.append(KeyValue(key=
'tx_carrier_errors', value=cmd_out))
202 values.append(KeyValue(key=
'tx_fifo_errors', value=cmd_out))
203 (ret_code, cmd_out) = self.
get_sys_net_stat(ifaces[i],
'tx_heartbeat_errors')
205 values.append(KeyValue(key=
'tx_heartbeat_errors', value=cmd_out))
208 values.append(KeyValue(key=
'tx_window_errors', value=cmd_out))
211 values.append(KeyValue(key=
'tx_dropped', value=cmd_out))
214 values.append(KeyValue(key=
'tx_packets', value=cmd_out))
216 (ret_code, cmd_out) = self.
get_sys_net(ifaces[i],
'addr_assign_type')
219 tmp_dict = {
'0':
'permanent address',
'1':
'randomly generated',
220 '2':
'stolen from another device',
'3':
'set using dev_set_mac_address'}
221 values.append(KeyValue(key=
'addr_assign_type', value=tmp_dict[cmd_out]))
223 values.append(KeyValue(key=
'addr_assign_type', value=cmd_out))
224 (ret_code, cmd_out) = self.
get_sys_net(ifaces[i],
'address')
226 values.append(KeyValue(key=
'address', value=cmd_out))
227 (ret_code, cmd_out) = self.
get_sys_net(ifaces[i],
'carrier')
230 tmp_dict = {
'0':
'physical link is down',
'1':
'physical link is up'}
231 values.append(KeyValue(key=
'carrier', value=tmp_dict[cmd_out]))
233 values.append(KeyValue(key=
'carrier', value=cmd_out))
234 (ret_code, cmd_out) = self.
get_sys_net(ifaces[i],
'carrier_changes')
236 values.append(KeyValue(key=
'carrier_changes', value=cmd_out))
238 level = DiagnosticStatus.WARN
240 (ret_code, cmd_out) = self.
get_sys_net(ifaces[i],
'carrier_up_count')
242 values.append(KeyValue(key=
'carrier_up_count', value=cmd_out))
243 (ret_code, cmd_out) = self.
get_sys_net(ifaces[i],
'carrier_down_count')
245 values.append(KeyValue(key=
'carrier_down_count', value=cmd_out))
246 (ret_code, cmd_out) = self.
get_sys_net(ifaces[i],
'speed')
248 values.append(KeyValue(key=
'speed', value=cmd_out))
249 (ret_code, cmd_out) = self.
get_sys_net(ifaces[i],
'tx_queue_len')
251 values.append(KeyValue(key=
'tx_queue_len', value=cmd_out))
252 except Exception
as e:
253 rospy.logerr(traceback.format_exc())
254 net_msg =
'Network Usage Check Error'
255 values.append(KeyValue(key=net_msg, value=str(e)))
256 values.append(KeyValue(key=
'Traceback', value=str(traceback.format_exc())))
257 level = DiagnosticStatus.ERROR
258 return level, net_msg, values
261 diag_level = DiagnosticStatus.OK
265 diag_vals.extend(net_vals)
266 if net_level > DiagnosticStatus.OK:
267 diag_msgs.append(net_msg)
268 diag_level = max(diag_level, net_level)
269 if diag_msgs
and diag_level > DiagnosticStatus.OK:
270 usage_msg =
', '.join(set(diag_msgs))
272 usage_msg = stat_dict[diag_level]
280 msg = DiagnosticArray()
281 msg.header.stamp = rospy.get_rostime()
286 if __name__ ==
'__main__':