25 from diagnostic_msgs.msg
import DiagnosticArray, DiagnosticStatus, KeyValue
27 stat_dict = { DiagnosticStatus.OK:
'OK', DiagnosticStatus.WARN:
'Warning', DiagnosticStatus.ERROR:
'Error' }
28 usage_dict = { DiagnosticStatus.OK:
'OK', DiagnosticStatus.WARN:
'Low Disk Space', DiagnosticStatus.ERROR:
'Very Low Disk Space' }
31 def __init__(self, hostname, diag_hostname, home_dir = ''):
40 self._usage_stat.level = DiagnosticStatus.WARN
41 self._usage_stat.hardware_id = hostname
42 self._usage_stat.name =
'%s HD Usage' % diag_hostname
43 self._usage_stat.message =
'No Data' 44 self._usage_stat.values = []
47 self._io_stat.name =
'%s HD IO' % diag_hostname
48 self._io_stat.level = DiagnosticStatus.WARN
49 self._io_stat.hardware_id = hostname
50 self._io_stat.message =
'No Data' 51 self._io_stat.values = []
53 self.
_diag_pub = rospy.Publisher(
'/diagnostics', DiagnosticArray, queue_size=1)
61 diag_level = DiagnosticStatus.OK
64 p = subprocess.Popen(
'iostat -d',
65 stdout = subprocess.PIPE,
66 stderr = subprocess.PIPE, shell =
True)
67 stdout, stderr = p.communicate()
68 retcode = p.returncode
70 stdout = stdout.decode()
71 except (UnicodeDecodeError, AttributeError):
75 diag_level = DiagnosticStatus.ERROR
76 diag_msg =
'HD IO Error' 77 diag_vals = [ KeyValue(key =
'HD IO Error', value = stderr),
78 KeyValue(key =
'Output', value = stdout) ]
79 return (diag_vals, diag_msg, diag_level)
81 for index, row
in enumerate(stdout.split(
'\n')):
94 diag_vals.append(KeyValue(
95 key =
'%s tps' % device, value=tps))
96 diag_vals.append(KeyValue(
97 key =
'%s kB_read/s' % device, value=kB_read_s))
98 diag_vals.append(KeyValue(
99 key =
'%s kB_wrtn/s' % device, value=kB_wrtn_s))
100 diag_vals.append(KeyValue(
101 key =
'%s kB_read' % device, value=kB_read))
102 diag_vals.append(KeyValue(
103 key =
'%s kB_wrtn' % device, value=kB_wrtn))
105 except Exception
as e:
106 diag_level = DiagnosticStatus.ERROR
107 diag_msg =
'HD IO Exception' 108 diag_vals = [ KeyValue(key =
'Exception', value = str(e)) ]
110 self._io_stat.values = diag_vals
111 self._io_stat.message = diag_msg
112 self._io_stat.level = diag_level
117 diag_level = DiagnosticStatus.OK
119 p = subprocess.Popen([
"df",
"--print-type",
"--portability",
"--block-size=1"+self.
unit, self.
_home_dir],
120 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
121 stdout, stderr = p.communicate()
122 retcode = p.returncode
124 stdout = stdout.decode()
125 except (UnicodeDecodeError, AttributeError):
129 diag_level = DiagnosticStatus.ERROR
130 diag_message =
'HD Usage Error' 131 diag_vals = [ KeyValue(key =
'HD Usage Error', value = stderr),
132 KeyValue(key =
'Output', value = stdout) ]
135 diag_vals.append(KeyValue(key =
'Disk Space Reading', value =
'OK'))
137 for row
in stdout.split(
'\n'):
139 if len(row.split()) < 2:
141 if float(row.split()[2]) < 10:
148 name = row.split()[0]
150 size = row.split()[2]
151 used = row.split()[3]
152 available = row.split()[4]
153 capacity = row.split()[5]
154 mount_pt = row.split()[6]
157 level = DiagnosticStatus.OK
159 level = DiagnosticStatus.WARN
161 level = DiagnosticStatus.ERROR
163 diag_vals.append(KeyValue(
164 key =
'Disk %d Name' % row_count, value = name))
165 diag_vals.append(KeyValue(
166 key =
'Disk %d Size' % row_count, value = size +
' ' +self.
unit))
167 diag_vals.append(KeyValue(
168 key =
'Disk %d Used' % row_count, value = used +
' ' +self.
unit))
169 diag_vals.append(KeyValue(
170 key =
'Disk %d Available' % row_count, value = available +
' ' +self.
unit))
171 diag_vals.append(KeyValue(
172 key =
'Disk %d Capacity' % row_count, value = capacity))
173 diag_vals.append(KeyValue(
174 key =
'Disk %d Status' % row_count, value = stat_dict[level]))
175 diag_vals.append(KeyValue(
176 key =
'Disk %d Mount Point' % row_count, value = mount_pt))
178 diag_level = max(diag_level, level)
179 diag_message = usage_dict[diag_level]
181 except Exception
as e:
182 diag_level = DiagnosticStatus.ERROR
183 diag_message =
'HD Usage Exception' 184 diag_vals = [ KeyValue(key =
'Exception', value = str(e)) ]
186 self._usage_stat.values = diag_vals
187 self._usage_stat.message = diag_message
188 self._usage_stat.level = diag_level
191 msg = DiagnosticArray()
192 msg.header.stamp = rospy.get_rostime()
194 self._diag_pub.publish(msg)
199 if __name__ ==
'__main__':
200 hostname = socket.gethostname()
203 parser = optparse.OptionParser(usage=
"usage: hd_monitor.py --diag-hostname=X --directory=/name_of_dir")
204 parser.add_option(
"--diag-hostname",
205 dest=
"diag_hostname",
206 help=
"Computer name in diagnostics output (ex: 'b1' for the base PC, 'h32' for the head PC and so on)",
207 metavar=
"DIAG_HOSTNAME",
210 parser.add_option(
"--directory",
212 help=
"Enter the directory name (ex: /directory/sub_directory)",
215 options, args = parser.parse_args(rospy.myargv())
216 if len(sys.argv[1:]) == 0:
217 parser.error(
"argument not found.")
222 node_name = (
"hd_monitor_"+hostname).replace (
"-",
"_")
223 rospy.init_node(node_name)
224 except rospy.exceptions.ROSInitException:
225 print(
'HD monitor is unable to initialize node. Master may not be running.')
228 hd_monitor =
hd_monitor(hostname, options.diag_hostname, options.directory)
def check_io_stat(self, event)
def publish_stats(self, event)
def __init__(self, hostname, diag_hostname, home_dir='')
def check_disk_usage(self, event)