def discover_connection_facts(self, comn): ''' Discover all the connections in this router-instance log For each connection: * determine connection direction * discover name of peer container * generate html to use to display the peer nickname * count log lines * count transfer bytes :param comn: :return: ''' for item in self.lines: if item.data.is_scraper: # scraper lines are pass-through continue conn_num = int(item.data.conn_num) id = item.data.conn_id # full name A0_3 if conn_num not in self.conn_list: cdir = "" if item.data.direction != "": cdir = item.data.direction else: if "Connecting" in item.data.web_show_str: cdir = text.direction_out() elif "Accepting" in item.data.web_show_str: cdir = text.direction_in() self.conn_list.append(conn_num) self.conn_to_frame_map[id] = [] self.conn_dir[id] = cdir self.conn_log_lines[id] = 0 # line counter self.conn_xfer_bytes[id] = 0 # byte counter self.conn_open_time[id] = item self.conn_to_frame_map[id].append(item) # inbound open handling if item.data.name == "open" and item.data.direction == text.direction_in( ): if item.data.conn_id in self.conn_peer: sys.exit( 'ERROR: file: %s connection %s has multiple connection peers' % (self.fn, id)) self.conn_peer[id] = item.data.conn_peer self.conn_peer_display[ id] = comn.shorteners.short_peer_names.translate( item.data.conn_peer, True) # close monitor if item.data.name == "close": self.conn_close_time[id] = item # connection log-line count self.conn_log_lines[id] += 1 # transfer byte count if item.data.name == "transfer": self.conn_xfer_bytes[id] += int(item.data.transfer_size) self.conn_list = sorted(self.conn_list) self.details = amqp_detail.AllDetails(self, comn)
def discover_connection_facts(self, comn): ''' Discover all the connections in this router-instance log For each connection: * determine connection direction * discover name of peer container * generate html to use to display the peer nickname * count log lines * count transfer bytes :param comn: :return: ''' for item in self.lines: conn_num = int(item.data.conn_num) id = item.data.conn_id # full name A0_3 if conn_num not in self.conn_list: cdir = "" if item.data.direction != "": cdir = item.data.direction else: if "Connecting" in item.data.web_show_str: cdir = text.direction_out() elif "Accepting" in item.data.web_show_str: cdir = text.direction_in() self.conn_list.append(conn_num) self.conn_to_frame_map[id] = [] self.conn_dir[id] = cdir self.conn_log_lines[id] = 0 # line counter self.conn_xfer_bytes[id] = 0 # byte counter self.conn_open_time[id] = item self.conn_to_frame_map[id].append(item) # inbound open handling if item.data.name == "open" and item.data.direction == text.direction_in(): if item.data.conn_id in self.conn_peer: sys.exit('ERROR: file: %s connection %s has multiple connection peers' % ( self.fn, id)) self.conn_peer[id] = item.data.conn_peer self.conn_peer_display[id] = comn.shorteners.short_peer_names.translate( item.data.conn_peer, True) # close monitor if item.data.name == "close": self.conn_close_time[id] = item # connection log-line count self.conn_log_lines[id] += 1 # transfer byte count if item.data.name == "transfer": self.conn_xfer_bytes[id] += int(item.data.transfer_size) self.conn_list = sorted(self.conn_list) self.details = amqp_detail.AllDetails(self, comn)
def direction_is_out(self): return self.direction == text.direction_out()
def evaluate_credit(self): for conn in self.rtr.conn_list: id = self.rtr.conn_id(conn) conn_detail = self.rtr.details.conn_details[id] for sess in conn_detail.session_list: for link in sess.link_list: # ignore links without starting attach if link.frame_list[0].data.name != "attach": link.counts.credit_not_evaluated += 1 sess.counts.credit_not_evaluated += 1 conn_detail.counts.credit_not_evaluated += 1 break # process flaggage look_for_sender_delivery_id = True dir_of_xfer = '' dir_of_flow = '' current_delivery = 0 # next transfer expected id delivery_limit = 0 # first unreachable delivery id from flow n_attaches = 0 tod_of_second_attach = None multiframe_in_progress = False init_stall = True credit_stall = False tod_of_no_credit = None tod_of_shutdown = None # record info about initial attach is_rcvr = link.frame_list[0].data.is_receiver o_dir = link.frame_list[0].data.direction # derive info about where to look for credit and transfer id # role dir transfers flow w/credit case # ---- ---- --------- ------------- ---- # rcvr <- -> <- A # rcvr -> <- -> B # sndr <- <- -> B # sndr -> -> <- A # if (((is_rcvr) and (o_dir == text.direction_in())) or ((not is_rcvr) and (o_dir == text.direction_out()))): # case A dir_of_xfer = text.direction_out() dir_of_flow = text.direction_in() else: # case B dir_of_xfer = text.direction_in() dir_of_flow = text.direction_out() for plf in link.frame_list: # initial credit delay starts at reception of second attach if n_attaches < 2: if plf.data.name == "attach": n_attaches += 1 if n_attaches == 2: tod_of_second_attach = plf.datetime if look_for_sender_delivery_id: if plf.data.name == "attach" and not plf.data.is_receiver: current_delivery = int(plf.data.described_type.dict.get("initial-delivery_count", "0")) delivery_limit = current_delivery look_for_sender_delivery_id = False if plf.data.name == "flow": if plf.data.direction == dir_of_flow: # a flow in the normal direction updates the delivery limit dc = plf.data.described_type.dict.get("delivery-count", "0") lc = plf.data.described_type.dict.get("link-credit", "0") delivery_limit = int(dc) + int(lc) # TODO: wrap at 32-bits if n_attaches < 2: # a working flow before sender attach - cancel initial stall init_stall = False if init_stall: init_stall = False dur = plf.datetime - tod_of_second_attach link.counts.initial_no_credit_duration = dur sess.counts.initial_no_credit_duration += dur conn_detail.counts.initial_no_credit_duration += dur if credit_stall and delivery_limit > current_delivery: # TODO: wrap credit_stall = False plf.data.web_show_str += " <span style=\"background-color:%s\">credit restored</span>" % common.color_of("no_credit") dur = plf.datetime - tod_of_no_credit link.counts.no_credit_duration += dur sess.counts.no_credit_duration += dur conn_detail.counts.no_credit_duration += dur else: # flow in the opposite direction updates the senders current delivery # normally used to consume credit in response to a drain from receiver current_delivery = int(plf.data.described_type.dict.get("initial-delivery_count", "0")) elif plf.data.transfer: if plf.data.direction == dir_of_xfer: if not plf.data.transfer_more: # consider the transfer to have arrived when last transfer seen current_delivery += 1 # TODO: wrap at 32-bits if current_delivery == delivery_limit: link.counts.no_credit += 1 sess.counts.no_credit += 1 conn_detail.counts.no_credit += 1 plf.data.transfer_exhausted_credit = True credit_stall = True plf.data.web_show_str += " <span style=\"background-color:%s\">no more credit</span>" % common.color_of("no_credit") tod_of_no_credit = plf.datetime else: pass # still have credit multiframe_in_progress = False else: # transfers with 'more' set don't consume credit multiframe_in_progress = True else: pass # transfer in wrong direction?? elif plf.data.name == "detach": tod_of_shutdown = plf.datetime break # clean up lingering credit stall if init_stall or credit_stall: if tod_of_shutdown is None: # find first end or close and call that shutdown time for plf in sess.session_frame_list: if plf.data.name == "end": tod_of_shutdown = plf.datetime break if tod_of_shutdown is None: for plf in conn_detail.unaccounted_frame_list: if plf.data.name == "close": tod_of_shutdown = plf.datetime break if tod_of_shutdown is None: # Hmmm, no shutdown. Use last link frame tod_of_shutdown = link.frame_list[-1].datetime if tod_of_second_attach is None: # Hmmm, no second attach. Use first link frame time tod_of_second_attach = link.frame_list[0].datetime if init_stall: dur = tod_of_shutdown - tod_of_second_attach link.counts.initial_no_credit_duration = dur sess.counts.initial_no_credit_duration += dur conn_detail.counts.initial_no_credit_duration += dur if credit_stall: # TODO: wrap dur = tod_of_shutdown - tod_of_no_credit link.counts.no_credit_duration += dur sess.counts.no_credit_duration += dur conn_detail.counts.no_credit_duration += dur # record multiframe transfer that didn't complete if multiframe_in_progress: link.counts.incomplete += 1 sess.counts.incomplete += 1 conn_detail.counts.incomplete += 1