def run(self): """The run method for this worker task. :return: None :rtype: None """ logger.info('{0} filling in {1} from {2} to {3} in steps of {4}'.format(repr(self), self.rrd_name, self.from_ts, self.to_ts, self.step)) self.rrd_init(self.rrd_name, self.from_ts - self.step, self.step) counter = 0 top = None try: # Populate the database with some 'fake' data for ts in range(int(self.from_ts), int(self.to_ts), int(self.step)): if not counter % 100: # Update the Linux top data at every 100 points top = com.mitel.pyrate.resmon_util.execute_top() total = (self.to_ts - self.from_ts)/self.step logger.info('{0} data generation progress = {1} of {2}, {3}%'. format(repr(self), counter, total, 100.0*(float(counter) / float(total)))) if top: # Now update the resource utilisation stats to the RRDs self.rrd_update(self.rrd_name, top, ts) else: logger.error('{0} failed to acquire result from top, exit'.format(repr(self))) break counter += 1 logger.info('{0} completed'.format(repr(self))) except BaseException as e: logger.error('{0} encountered unexpected {1} at {2}'.format(repr(self), e, traceback.format_tb(sys.exc_info()[2])))
def main(args): """Main entry point of this program. :param args: The command-line argument list :return: Exit code :rtype: int """ parser = argparse.ArgumentParser(prog='resmon.py', description='Monitor the system resource utilisation, periodically') top = parser group1 = top.add_argument_group() group1.add_argument('-n', metavar='name', help='Name of the resource monitoring session, artifacts will follow this' ' name', type=str) group1.add_argument('-p', metavar='period', help='The sampling period of the monitoring process. E.g. 10s, 1m, 2h.' ' Default is 1m', default='1m', type=str) group2 = top.add_argument_group() group2.add_argument('-l', help='List all the resmon databases found in the working directory and return.', action='count') arg = parser.parse_args(args) if arg.l: print(execute_list_dbs()) return 0 if not arg.n: logger.error('No name specified') return errno.EINVAL if arg.p: period = parse_timespec(arg.p) else: period = 60 # Default period is 1m monitor = start_monitor(arg.n, period) try: while 1: # Run until stopped # Wake up periodically and do something, like kicking a watchdog or something like that, not sure what yet. sleep(600) except KeyboardInterrupt: logger.info('User interrupted') return errno.EINTR finally: monitor.stop() logger.info('resmon terminated') return errno.EINVAL # If we are here we were interrupted by something other than KeyboardInterrupt
def __call__(self): """The run entry for the worker thread.""" try: self.run() # Sub-classes must implement this. except IOError as e: logger.warning('{0} encountered {1} at {2}'.format(repr(self), e, traceback.format_tb(sys.exc_info()[2]))) except BaseException as e: logger.error("{0} encountered unexpected {1} at {2}".format(repr(self), e, traceback.format_tb(sys.exc_info()[2]))) finally: # Make sure everything is properly reset with self._lock: self._runFlag = False self.stopWaiting.set()
def generate_graph(img_file, start_ts, end_ts, title, width, height, data_defs): """Generate a graph for the specific RRD. :param img_file: The name of the image file to be generated (use '-' to send it to stdout) :type img_file: str :param start_ts: The start time of the graph :type start_ts: int :param end_ts: The end time of the graph :type end_ts: int :param width: The width of the graph, in number of pixels :type width: int :param height: The height of the graph, in number of pixels :type height: int :param data_defs: A series of one or more data definition, e.g. DEF:ds=abc.rrd:dataX:AVERAGE... :type data_defs: [str] :return: None :rtype: None """ try: # Force img_file to str since rrdtool doesn't like Unicode or other kinds of strings args = [str(img_file), '--start', str(int(start_ts)), '--end', str(int(end_ts)), '--imgformat', 'PNG', '--title', str(title), '--slope-mode', '--full-size-mode'] if width: args += ['-w', str(int(width))] if height: args += ['-h', str(int(height))] args += data_defs rrdtool.graph(*args) except BaseException as e: logger.error('Encountered unexpected {0} at {1}'.format(e, traceback.format_tb(sys.exc_info()[2])))
def main(args): """Main entry to program. :param args: Parsed command-line args. :return: Exit code. """ try: start_ts = (int(time.time()) / _step) * _step # TS should be aligned with the period # Step 1: Start the monitoring if (not os.path.exists(_base_name + 'cpu.rrd')) or (not os.path.exists(_base_name + 'mem.rrd')): fill_in_the_rrds(_base_name + 'cpu.rrd', _base_name + 'mem.rrd', start_ts - (24 * 3600), start_ts, _step) else: fill_in_the_rrds(_base_name + 'cpu.rrd', _base_name + 'mem.rrd', int(rrdutil.get_last_update(_base_name + 'cpu.rrd')) + _step, start_ts, _step) monitor = resmon_util.start_monitor(_base_name, _step) try: prev_ts = start_ts for loop in range(0, 360): # Run for an hour (360 loops of 10 seconds). # Step 2: Wait for some time (10s) for the monitor to gather data logger.info('Waiting for data, loop #{0}'.format(loop)) time.sleep(10) # Step 3: Observe the result last_cpu_data = rrdutil.fetch_last_data(monitor.get_cpu_rrd(), start_ts=prev_ts, resolution=1) last_mem_data = rrdutil.fetch_last_data(monitor.get_mem_rrd(), start_ts=prev_ts) # Print out the result print('\nLAST CPU data {0}, curr time = {1}'.format(last_cpu_data[0], int(time.time()))) print(rrdutil.format_cpu_stats(last_cpu_data)) print('\nLAST Memory data {0}'.format(last_mem_data[0])) print(rrdutil.format_mem_stats(last_mem_data)) prev_ts = (int(time.time()) / _step) * _step # TS should be aligned with the period avg_data = rrdutil.fetch_avg_data(monitor.get_cpu_rrd(), start_ts=start_ts, resolution=10) print('\nAVG CPU data {0}'.format(avg_data[0])) print(rrdutil.format_cpu_stats(avg_data)) avg_data = rrdutil.fetch_avg_data(monitor.get_mem_rrd(), start_ts=start_ts, resolution=10) print('\nAVG Memory data {0}'.format(avg_data[0])) print(rrdutil.format_mem_stats(avg_data)) finally: # Don't forget to stop the monitor when finish logger.info('Stopping {0}'.format(monitor)) monitor.stop() # Generate a graph end_graf = time.time() start_graf = end_graf - (2 * SECONDS_IN_HOUR) gen_graph('cpu.png', rrd_name=monitor.get_cpu_rrd(), title='CPU Utilisation', cf='AVERAGE', start_ts=start_graf, end_ts=end_graf, dataset=[('idle', '%Idle'), ('wait', '%Wait'), ('load', 'Load avg')]) gen_graph('mem.png', rrd_name=monitor.get_mem_rrd(), title='Memory Utilisation', cf='AVERAGE', start_ts=start_graf, end_ts=end_graf, dataset=[('memtotal', 'Total'), ('memfree', 'Free'), ('buffers', 'Buffers'), ('cached', 'Cached')]) except (TypeError, ValueError) as e: logger.warning('Encountered invalid monitor period {0}, at {1}'.format(e, format_tb(sys.exc_info()[2]))) except KeyboardInterrupt: logger.warning('User interruption at {0}'.format(format_tb(sys.exc_info()[2]))) except BaseException as e: logger.error('Encountered unexpected exception {0} at {1}'.format(repr(e), format_tb(sys.exc_info()[2])))