26 from diagnostic_msgs.msg
import DiagnosticArray, DiagnosticStatus, KeyValue
28 stat_dict = { DiagnosticStatus.OK:
'OK', DiagnosticStatus.WARN:
'Warning', DiagnosticStatus.ERROR:
'Error' }
29 usage_dict = { DiagnosticStatus.OK:
'OK', DiagnosticStatus.WARN:
'Low Disk Space', DiagnosticStatus.ERROR:
'Very Low Disk Space' }
32 def __init__(self, hostname, diag_hostname, home_dir = ''):
43 self.
_usage_stat.name =
'%s HD Usage' % diag_hostname
48 self.
_io_stat.name =
'%s HD IO' % diag_hostname
49 self.
_io_stat.level = DiagnosticStatus.WARN
54 self.
_diag_pub = rospy.Publisher(
'/diagnostics', DiagnosticArray, queue_size=1)
62 diag_level = DiagnosticStatus.OK
65 p = subprocess.Popen(
'iostat -d',
66 stdout = subprocess.PIPE,
67 stderr = subprocess.PIPE, shell =
True)
68 stdout, stderr = p.communicate()
69 retcode = p.returncode
71 stdout = stdout.decode()
72 except (UnicodeDecodeError, AttributeError):
76 diag_level = DiagnosticStatus.ERROR
77 diag_msg =
'HD IO Error'
78 diag_vals = [ KeyValue(key =
'HD IO Error', value = stderr),
79 KeyValue(key =
'Output', value = stdout) ]
80 return (diag_vals, diag_msg, diag_level)
82 for index, row
in enumerate(stdout.split(
'\n')):
95 diag_vals.append(KeyValue(
96 key =
'%s tps' % device, value=tps))
97 diag_vals.append(KeyValue(
98 key =
'%s kB_read/s' % device, value=kB_read_s))
99 diag_vals.append(KeyValue(
100 key =
'%s kB_wrtn/s' % device, value=kB_wrtn_s))
101 diag_vals.append(KeyValue(
102 key =
'%s kB_read' % device, value=kB_read))
103 diag_vals.append(KeyValue(
104 key =
'%s kB_wrtn' % device, value=kB_wrtn))
106 except Exception
as e:
107 diag_level = DiagnosticStatus.ERROR
108 diag_msg =
'HD IO Exception'
109 diag_vals = [ KeyValue(key =
'Exception', value = str(e)), KeyValue(key =
'Traceback', value = str(traceback.format_exc())) ]
118 diag_level = DiagnosticStatus.OK
120 p = subprocess.Popen([
"df",
"--print-type",
"--portability",
"--block-size=1"+self.
unit, self.
_home_dir],
121 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
122 stdout, stderr = p.communicate()
123 retcode = p.returncode
125 stdout = stdout.decode()
126 except (UnicodeDecodeError, AttributeError):
130 diag_level = DiagnosticStatus.ERROR
131 diag_message =
'HD Usage Error'
132 diag_vals = [ KeyValue(key =
'HD Usage Error', value = stderr),
133 KeyValue(key =
'Output', value = stdout) ]
136 diag_vals.append(KeyValue(key =
'Disk Space Reading', value =
'OK'))
138 for row
in stdout.split(
'\n'):
140 if len(row.split()) < 2:
142 if float(row.split()[2]) < 10:
149 name = row.split()[0]
151 size = row.split()[2]
152 used = row.split()[3]
153 available = row.split()[4]
154 capacity = row.split()[5]
155 mount_pt = row.split()[6]
158 level = DiagnosticStatus.OK
160 level = DiagnosticStatus.WARN
162 level = DiagnosticStatus.ERROR
164 diag_vals.append(KeyValue(
165 key =
'Disk %d Name' % row_count, value = name))
166 diag_vals.append(KeyValue(
167 key =
'Disk %d Size' % row_count, value = size +
' ' +self.
unit))
168 diag_vals.append(KeyValue(
169 key =
'Disk %d Used' % row_count, value = used +
' ' +self.
unit))
170 diag_vals.append(KeyValue(
171 key =
'Disk %d Available' % row_count, value = available +
' ' +self.
unit))
172 diag_vals.append(KeyValue(
173 key =
'Disk %d Capacity' % row_count, value = capacity))
174 diag_vals.append(KeyValue(
175 key =
'Disk %d Status' % row_count, value = stat_dict[level]))
176 diag_vals.append(KeyValue(
177 key =
'Disk %d Mount Point' % row_count, value = mount_pt))
179 diag_level = max(diag_level, level)
180 diag_message = usage_dict[diag_level]
182 except Exception
as e:
183 diag_level = DiagnosticStatus.ERROR
184 diag_message =
'HD Usage Exception'
185 diag_vals = [ KeyValue(key =
'Exception', value = str(e)), KeyValue(key =
'Traceback', value = str(traceback.format_exc())) ]
192 msg = DiagnosticArray()
193 msg.header.stamp = rospy.get_rostime()
200 if __name__ ==
'__main__':
201 hostname = socket.gethostname()
204 parser = optparse.OptionParser(usage=
"usage: hd_monitor.py --diag-hostname=X --directory=/name_of_dir")
205 parser.add_option(
"--diag-hostname",
206 dest=
"diag_hostname",
207 help=
"Computer name in diagnostics output (ex: 'b1' for the base PC, 'h32' for the head PC and so on)",
208 metavar=
"DIAG_HOSTNAME",
211 parser.add_option(
"--directory",
213 help=
"Enter the directory name (ex: /directory/sub_directory)",
216 options, args = parser.parse_args(rospy.myargv())
217 if len(sys.argv[1:]) == 0:
218 parser.error(
"argument not found.")
223 node_name = (
"hd_monitor_"+hostname).replace (
"-",
"_")
224 rospy.init_node(node_name)
225 except rospy.exceptions.ROSInitException:
226 print(
'HD monitor is unable to initialize node. Master may not be running.')
229 hd_monitor =
hd_monitor(hostname, options.diag_hostname, options.directory)