def run(self): """ Collect data from cimmaron tsdb in relation to the specified graph and time windows and store an annotated subgraph in specified directory :param graph: (NetworkX Graph) Graph to be annotated with data :param ts_from: (str) Epoch time representation of start time :param ts_to: (str) Epoch time representation of stop time :param utilization: (bool) if True the method calculates also utilization for each node, if available :return: NetworkX Graph annotated with telemetry data """ utilization = True saturation = True for node in self.node_pool: # node = self.node telemetry_data = None if isinstance(self.telemetry, SnapAnnotation): queries = list() try: queries = self.telemetry.get_queries( self.internal_graph, node, self.ts_from, self.ts_to) # queries = self.telemetry.get_queries(graph, node, ts_from, ts_to) except Exception as e: LOG.error("Exception: {}".format(e)) LOG.error(e) import traceback traceback.print_exc() if len(queries) != 0: InfoGraphNode.set_queries(node, queries) telemetry_data = self.telemetry.get_data(node) InfoGraphNode.set_telemetry_data(node, telemetry_data) if utilization and not telemetry_data.empty: SnapUtils.utilization(self.internal_graph, node, self.telemetry) # if only procfs is available, results needs to be # propagated at machine level if saturation: SnapUtils.saturation(self.internal_graph, node, self.telemetry) elif isinstance(self.telemetry, PrometheusAnnotation): telemetry_data = self.telemetry.get_data(node) InfoGraphNode.set_telemetry_data(node, telemetry_data) if utilization and not telemetry_data.empty: self.utils.utilization(self.internal_graph, node, self.telemetry) if saturation: self.utils.saturation(self.internal_graph, node, self.telemetry) self.telemetry_data = telemetry_data
def filter_graph(graph): """ Returns the graph filtered removing all the nodes with no telemetry """ template_mapping = dict() res = graph.copy() for node in res.nodes(data=True): # for p in node[1]['attributes']: # p = str(p) template = node[1]['attributes']['template'] \ if 'template' in node[1]['attributes'] else None # If node is a service node, need to remove the template if template: template_mapping[InfoGraphNode.get_name(node)] = template node[1]['attributes'].pop('template') # Fix format for conversion to JSON (happening in analytics) node[1]['attributes'] = \ str(misc.convert_unicode_dict_to_string(node[1]['attributes'])).\ replace("'", '"') for node in res.nodes(data=True): node_name = InfoGraphNode.get_name(node) telemetry = InfoGraphNode.get_telemetry_data(node) layer = InfoGraphNode.get_layer(node) # if len(telemetry.columns.values) <= 1: if len(telemetry.columns) <= 1 and \ not layer == InfoGraphNodeLayer.SERVICE: InfoGraphNode.set_telemetry_data(node, dict()) res.filter_nodes('node_name', node_name) # Convert attributes back to dict() for node in res.nodes(data=True): string = InfoGraphNode.get_attributes(node) attrs = InfoGraphUtilities.str_to_dict(string) if InfoGraphNode.get_type(node) == \ InfoGraphNodeType.SERVICE_COMPUTE: attrs['template'] = \ template_mapping[InfoGraphNode.get_name(node)] InfoGraphNode.set_attributes(node, attrs) return res
def get_annotated_graph(self, graph, ts_from, ts_to, utilization=False, saturation=False): """ Collect data from cimmaron tsdb in relation to the specified graph and time windows and store an annotated subgraph in specified directory :param graph: (NetworkX Graph) Graph to be annotated with data :param ts_from: (str) Epoch time representation of start time :param ts_to: (str) Epoch time representation of stop time :param utilization: (bool) if True the method calculates also utilization for each node, if available :return: NetworkX Graph annotated with telemetry data """ TelemetryAnnotation._get_annotated_graph_input_validation( graph, ts_from, ts_to) internal_graph = graph.copy() self.internal_graph = internal_graph for node in internal_graph.nodes(data=True): if isinstance(self.telemetry, SnapAnnotation): queries = list() try: queries = self.telemetry.get_queries( internal_graph, node, ts_from, ts_to) # queries = self.telemetry.get_queries(graph, node, ts_from, ts_to) except Exception as e: LOG.error("Exception: {}".format(e)) LOG.error(e) import traceback traceback.print_exc() if len(queries) != 0: InfoGraphNode.set_queries(node, queries) telemetry_data = self.telemetry.get_data(node) InfoGraphNode.set_telemetry_data(node, telemetry_data) if utilization and not telemetry_data.empty: SnapUtils.utilization(internal_graph, node, self.telemetry) # if only procfs is available, results needs to be # propagated at machine level if InfoGraphNode.get_type( node) == InfoGraphNodeType.PHYSICAL_PU: SnapUtils.annotate_machine_pu_util( internal_graph, node) if InfoGraphNode.node_is_disk(node): SnapUtils.annotate_machine_disk_util( internal_graph, node) if InfoGraphNode.node_is_nic(node): SnapUtils.annotate_machine_network_util( internal_graph, node) if saturation: SnapUtils.saturation(internal_graph, node, self.telemetry) elif isinstance(self.telemetry, PrometheusAnnotation): queries = list() try: queries = self.telemetry.get_queries( internal_graph, node, ts_from, ts_to) # queries = self.telemetry.get_queries(graph, node, ts_from, ts_to) except Exception as e: LOG.error("Exception: {}".format(e)) LOG.error(e) import traceback traceback.print_exc() if len(queries) != 0: InfoGraphNode.set_queries(node, queries) telemetry_data = self.telemetry.get_data(node) InfoGraphNode.set_telemetry_data(node, telemetry_data) # if utilization and not telemetry_data.empty: #PrometheusUtils.utilization(internal_graph, node, self.telemetry) # if only procfs is available, results needs to be # propagated at machine level #if InfoGraphNode.get_type(node) == InfoGraphNodeType.PHYSICAL_PU: # PrometheusUtils.annotate_machine_pu_util(internal_graph, node) #if InfoGraphNode.node_is_disk(node): # PrometheusUtils.annotate_machine_disk_util(internal_graph, node) #if InfoGraphNode.node_is_nic(node): # PrometheusUtils.annotate_machine_network_util(internal_graph, node) #if saturation: #PrometheusUtils.saturation(internal_graph, node, self.telemetry) else: telemetry_data = self.telemetry.get_data(node) InfoGraphNode.set_telemetry_data(node, telemetry_data) if utilization and not telemetry_data.empty: SnapUtils.utilization(internal_graph, node, self.telemetry) # if only procfs is available, results needs to be # propagated at machine level if InfoGraphNode.get_type( node) == InfoGraphNodeType.PHYSICAL_PU: source = InfoGraphNode.get_machine_name_of_pu(node) machine = InfoGraphNode.get_node( internal_graph, source) machine_util = InfoGraphNode.get_compute_utilization( machine) if '/intel/use/compute/utilization' not in machine_util.columns: sum_util = None pu_util = InfoGraphNode.get_compute_utilization( node )['intel/procfs/cpu/utilization_percentage'] pu_util = pu_util.fillna(0) if 'intel/procfs/cpu/utilization_percentage' in machine_util.columns: machine_util = machine_util[ 'intel/procfs/cpu/utilization_percentage'] machine_util = machine_util.fillna(0) sum_util = machine_util.add(pu_util, fill_value=0) else: sum_util = pu_util if isinstance(sum_util, pandas.Series): # sum_util.index.name = None sum_util = pandas.DataFrame( sum_util, columns=[ 'intel/procfs/cpu/utilization_percentage' ]) InfoGraphNode.set_compute_utilization( machine, sum_util) else: LOG.debug('Found use for node {}'.format( InfoGraphNode.get_name(node))) if saturation: self._saturation(internal_graph, node, self.telemetry) return internal_graph
def run(self, workload): tmp_path = "/media/iolie/WORK/data/" # Extract data from Info Core service_subgraphs = workload.get_latest_graph() telemetry = {} cols = [] if not service_subgraphs or len(service_subgraphs) == 0: return # first add telemetry data of all nodes to a dictionary print "Data merger started " + str(time.time()) for subgraph in service_subgraphs: for node in subgraph.nodes(data=True): node_id = node[0] node_tm = InfoGraphNode.get_telemetry_data(node) if InfoGraphNode.node_is_vm(node): if not node_tm.empty: node_tm.columns = tm_utils.clean_vm_telemetry_colnames(node_tm.columns) vm_name = InfoGraphNode.get_attributes(node).get("vm_name") if vm_name: node_id = vm_name if not node_tm.empty: tm = telemetry.get(node_id) if not isinstance(tm, pd.DataFrame): #if not tm: telemetry[node_id] = node_tm #telemetry[node_id] = [node_tm] #node_tm.to_csv(tmp_path+node_id, index=False) else: telemetry[node_id] = pd.concat([tm, node_tm]) #telemetry[node_id].append(node_tm) #node_tm.to_csv(tmp_path + node_id, mode='a', header=False, index=False) InfoGraphNode.set_telemetry_data(node, pd.DataFrame()) print "Data merger finished " + str(time.time()) print telemetry.keys() print len(telemetry) # merge subgraphs graph = None counter = 0 for subgraph in service_subgraphs: counter = counter + 1 if not graph and len(subgraph.nodes()) > 0: graph = subgraph elif len(subgraph.nodes()) > 0: graphs.merge_graph(graph, subgraph) #print "Merged {} subgraphs out of {} subgraphs in all".format(counter, len(service_subgraphs)) # merge telemetry data #for key in telemetry.keys(): # val = telemetry[key] # print key + ' {}'.format(len(val)) # if len(val) > 1: # telemetry[key] = pd.concat(val) # elif len(val) == 1: # telemetry[key] = val[0] # print node_id + ', ' + str(time.time()) # print "Merged telemetry data of {} nodes out of {} nodes in all".format(counter, len(telemetry.keys())) # set telemetry data on merged graph for node in graph.nodes(data=True): node_id = node[0] if InfoGraphNode.node_is_vm(node): vm_name = InfoGraphNode.get_attributes(node).get("vm_name") if vm_name: node_id = vm_name tm = telemetry.get(node_id) #try: # tm = pd.read_csv(tmp_path + node_id) #except: # tm = pd.DataFrame() if isinstance(tm, pd.DataFrame): if not tm.empty: InfoGraphNode.set_telemetry_data(node, tm) del telemetry[node_id] # delete telemetry data so that only one copy exists in the graph else: InfoGraphNode.set_telemetry_data(node, None) # print "Set telemetry data of node {}".format(node_id) print "Set telemetry data of merged graph" workload.save_results(self.__filter_name__, graph) return graph