def resmon_on_off(request, action, name): """Activate/deactivate a specific resmon, create a new resmon DB if necessary. :param request: The original HTTP request. :type request: HttpRequest :param action: The action to take, must be one of: 'on' or 'off'. :type action: str :param name: The name of the monitor against which to apply the action. :type name: str :return: The response to this request. :rtype: HttpResponse """ global _task_repository global _lock try: resp = RestCmd('resmon', '') if action == 'on': period = request.GET.get('period') with _lock: if name in _task_repository: logger.warning('Monitor {0} already running, restarting.'.format(name)) _task_repository.pop(name).stop() logger.info('Staring monitor {0} at intervals {1}.'.format(name, period)) _task_repository[name] = start_monitor(name, parse_timespec(period), ResmonListener()) if 'xml' in request.META.get('HTTP_ACCEPT'): return HttpResponse(ElementTree.tostring(resp.export_xml()), content_type='application/xml') return HttpResponse(resp.export_json(), content_type='application/json') with _lock: if name in _task_repository: task = _task_repository.pop(name) logger.info('Stopping {0}'.format(name)) task.stop() else: logger.warning('{0} not in resmon repository. Attempt to stop is ignored.'.format(name)) if 'xml' in request.META.get('HTTP_ACCEPT'): return HttpResponse(ElementTree.tostring(resp.export_xml()), content_type='application/xml') return HttpResponse(resp.export_json(), content_type='application/json') except Exception as e: tb = sys.exc_info()[2] logger.warning('Encountered unexpected {0} at {1}'.format(e, traceback.format_tb(tb))) return HttpResponseServerError('Encountered unexpected internal server error')
def graph(request, name): """Handle the graph request. :param request: The original resmon GRAPH request. :type request: HttpRequest :param name: The name of the resmon RRD whose graph is desired. :type name: str :return: The response to the graph request. :rtype: HttpResponse """ try: period = request.GET.get('period') width = request.GET.get('width') height = request.GET.get('height') dataset = request.GET.get('dataset') # Space delimited data set end_ts = int(time.time()) start_ts = end_ts - parse_timespec(period) if not dataset: raise HttpResponseBadRequest('No dataset given') resp = RestCmd('resmon/graph', '') img = tempfile.mkstemp(suffix=".png", prefix="resmongraph") try: close(img[0]) execute_graph_request(name, dataset.split(), img[1], start_ts, end_ts, 'AVERAGE', width, height) # Now read in the image file and prepare for the response. with open(img[1], 'r') as f: img_size = os.path.getsize(img[1]) if img_size <= 2095104: # Read maximum 2Mb resp.data = f.read() if 'xml' in request.META.get('HTTP_ACCEPT'): return HttpResponse(ElementTree.tostring(resp.export_xml()), content_type='application/xml') return HttpResponse(resp.export_json(), content_type='application/json') else: logger.warning('Image file size {0} exceeded the maximum limit of 2Mb, please retry with smaller dimensions.' .format(img_size)) return HttpResponseServerError('Image file too large') finally: os.remove(img[1]) # Clean up the temp file. except Exception as e: tb = sys.exc_info()[2] logger.error('Encountered unexpected {0} at {1}'.format(e, traceback.format_tb(tb))) return HttpResponseServerError('Unexpected internal server error')
def query(request): """List all the resmon DB's found in the working directory, in JSON format. :param request: The original HTTP request. :type request: HttpRequest :return: The response to the query. :rtype: HttpResponse """ resp = RestCmd('resmon query', execute_list_dbs()) if 'xml' in request.META.get('HTTP_ACCEPT'): return HttpResponse(ElementTree.tostring(resp.export_xml()), content_type='application/xml') return HttpResponse(resp.export_json(), content_type='application/json')
def fetch(request, name, res_type, consolidation): """Fetch the data from a specific RRD, in some time frame, with a particular resolution. :param request: The original request. :type request: HttpRequest :param name: The name of the target resmon database. :type name: str :param res_type: The type of data: cpu | memory :type res_type: str :param consolidation: The optional consolidation function used. If specified must be one of: average | last. The default is last. :type consolidation; str :return: The requested data set. """ try: resolution = request.GET.get('resolution') start = request.GET.get('start') end = request.GET.get('end') if not resolution: resolution = '1s' # Default to the fastest resolution if not end: end = time.time() # Default to now if not start: start = end - (24 * 3600) # Default to one day worth of data ts = time.time() data = None if consolidation == 'average': data = rrdutil.fetch_avg_data(name + res_type + '.rrd', start_ts=int(start), end_ts=int(end), resolution=parse_timespec(resolution)) else: data = rrdutil.fetch_last_data(name + res_type + '.rrd', start_ts=int(start), end_ts=int(end), resolution=parse_timespec(resolution)) resp = RestCmd('/resmon/fetch', _process_fetch_data(data)) if 'xml' in request.META.get('HTTP_ACCEPT'): return HttpResponse(ElementTree.tostring(resp.export_xml()), content_type='application/xml') return HttpResponse(resp.export_json(), content_type='application/json') except Exception as e: tb = sys.exc_info()[2] logger.error('Encountered unexpected {0} at {1}'.format(e, traceback.format_tb(tb))) return HttpResponseServerError('Encountered unexpected error, please check service log for more details')
def pstat(request): """Execute the pstat command, which is basically the pyrate execute_ps() function. :param request: The original HTTP request. :type request: django.http.request.HttpRequest :return: The response object. :rtype: HttpResponse """ output_format = 'json' if 'xml' in request.META.get('HTTP_ACCEPT'): output_format = 'xml' cmd = RestCmd('pstat', format_process_tree(build_process_tree(execute_ps()), output_format)) if output_format == 'xml': return HttpResponse(ElementTree.tostring(cmd.export_xml()), content_type='application/xml') # Default format is JSON return HttpResponse(cmd.export_json(), content_type='application/json')
output_format = 'json' if 'xml' in request.META.get('HTTP_ACCEPT'): output_format = 'xml' cmd = RestCmd('pstat', format_process_tree(build_process_tree(execute_ps()), output_format)) if output_format == 'xml': return HttpResponse(ElementTree.tostring(cmd.export_xml()), content_type='application/xml') # Default format is JSON return HttpResponse(cmd.export_json(), content_type='application/json') if __name__ == '__main__': cmd = RestCmd('command', b'This is a cat') jsontxt = cmd.export_json() print("CMD = {0} -> {1}".format(jsontxt, ElementTree.tostring(cmd.export_xml()))) try: cmd.import_json('asd asda sdasd') print(ElementTree.tostring(cmd.export_xml())) except (ValueError, KeyError, TypeError) as e: bt = sys.exc_info()[2] print('Encountered {0} @ {1}'.format(e, traceback.format_tb(bt))) try: cmd.import_json('{"abc":"def", "ada":"4312", "data":"asdasdasdasdasd"}') print(ElementTree.tostring(cmd.export_xml())) except (ValueError, KeyError, TypeError) as e: bt = sys.exc_info()[2] print('Encountered {0} @ {1}'.format(e, traceback.format_tb(bt)))