def get_info(self): info = { "min-delay": self.min_delay, "max-delay": self.max_delay, "expire": self.expire_delay, "timeout-delay": self.timeout_delay, "locked": self.locked, } if self.delay_per_megapixel >= 0: info["normalized"] = self.delay_per_megapixel if self.last_event > 0: info["last-event"] = int(monotonic_time() - self.last_event) if self.locked: info["delay"] = self.delay else: ld = tuple(x for _, x in self.last_delays) if ld: info["delay"] = get_list_stats(ld) lad = tuple(x for _, x in self.last_actual_delays) if lad: info["actual_delays"] = get_list_stats(lad, show_percentile=(9, )) for name, details, factor, weight in self.factors: fdetails = details.copy() fdetails[""] = int(100.0 * factor), int(100.0 * weight) info[name] = fdetails return info
def get_connection_info(self) -> dict: latencies = tuple( int(x * 1000) for (_, _, _, x) in tuple(self.client_latency)) now = monotonic() info = { "mmap_bytecount": self.mmap_bytes_sent, "latency": get_list_stats(latencies), "server": { "ping_latency": get_list_stats( int(1000 * x[1]) for x in tuple(self.server_ping_latency)), }, "client": { "ping_latency": get_list_stats( int(1000 * x[1]) for x in tuple(self.client_ping_latency)), }, "congestion": { "avg-send-speed": self.avg_congestion_send_speed, "elapsed-time": int(now - self.last_congestion_time), }, } if self.min_client_latency is not None: info["latency"] = {"absmin": int(self.min_client_latency * 1000)} return info
def get_info(self) -> dict: info = { "min-delay": self.min_delay, "max-delay": self.max_delay, "expire": self.expire_delay, "timeout-delay": self.timeout_delay, "locked": self.locked, } if self.delay_per_megapixel >= 0: info["normalized"] = self.delay_per_megapixel if self.last_event > 0: info["last-event"] = int(monotonic_time() - self.last_event) if self.locked: info["delay"] = self.delay else: ld = tuple(x[1] for x in self.last_delays) if ld: ls = get_list_stats(ld) ldv = self.last_delay if ldv: ls["last"] = ldv[1] #pylint: disable=unsubscriptable-object info["delay"] = ls lad = tuple(x[1] for x in self.last_actual_delays) if lad: ls = get_list_stats(lad, show_percentile=(9, )) ladv = self.last_actual_delay if ladv: ls["last"] = ladv[1] #pylint: disable=unsubscriptable-object info["actual_delays"] = ls for name, details, factor, weight in self.factors: fdetails = details.copy() fdetails[""] = int(100.0 * factor), int(100.0 * weight) info[name] = fdetails return info
def get_window_info(self): """ Adds encoding and window specific information """ from xpra.simple_stats import get_list_stats pqpixels = [x[2] for x in tuple(self.packet_queue)] pqpi = get_list_stats(pqpixels) if len(pqpixels) > 0: pqpi["current"] = pqpixels[-1] info = { "damage": { "compression_queue": { "size": { "current": self.encode_queue_size() } }, "packet_queue": { "size": { "current": len(self.packet_queue) } }, "packet_queue_pixels": pqpi, }, "batch": self.global_batch_config.get_info(), } info.update(self.statistics.get_info()) if len(self.window_sources) > 0: total_pixels = 0 total_time = 0.0 in_latencies, out_latencies = [], [] winfo = {} for wid, ws in list(self.window_sources.items()): #per-window source stats: winfo[wid] = ws.get_info() #collect stats for global averages: for _, _, pixels, _, _, encoding_time in tuple( ws.statistics.encoding_stats): total_pixels += pixels total_time += encoding_time in_latencies += [ x * 1000 for _, _, _, x in tuple(ws.statistics.damage_in_latency) ] out_latencies += [ x * 1000 for _, _, _, x in tuple(ws.statistics.damage_out_latency) ] info["window"] = winfo v = 0 if total_time > 0: v = int(total_pixels / total_time) info.setdefault("encoding", {})["pixels_encoded_per_second"] = v dinfo = info.setdefault("damage", {}) dinfo["in_latency"] = get_list_stats(in_latencies, show_percentile=[9]) dinfo["out_latency"] = get_list_stats(out_latencies, show_percentile=[9]) return info
def get_info(self): cwqsizes = [x for _, x in tuple(self.compression_work_qsizes)] pqsizes = [x for _, x in tuple(self.packet_qsizes)] now = monotonic_time() time_limit = now - 60 #ignore old records (60s) info = { "damage": { "events": self.damage_events_count, "packets_sent": self.packet_count, "data_queue": { "size": get_list_stats(cwqsizes), }, "packet_queue": { "size": get_list_stats(pqsizes), }, }, "encoding": { "decode_errors": self.decode_errors }, "congestion": { "avg-send-speed": self.avg_congestion_send_speed, "elapsed-time": int(now - self.last_congestion_time), }, } #client pixels per second: #pixels per second: decode time and overall total_pixels = 0 #total number of pixels processed total_time = 0 #total decoding time start_time = None #when we start counting from (oldest record) region_sizes = [] for _, event_time, pixels, decode_time in tuple( self.client_decode_time): #time filter and ignore failed decoding (decode_time==0) if event_time < time_limit or decode_time <= 0: continue if start_time is None or start_time > event_time: start_time = event_time total_pixels += pixels total_time += decode_time region_sizes.append(pixels) log("total_time=%s, total_pixels=%s", total_time, total_pixels) if total_time > 0: pixels_decoded_per_second = int(total_pixels * 1000 * 1000 / total_time) info["encoding"][ "pixels_decoded_per_second"] = pixels_decoded_per_second if start_time: elapsed = now - start_time pixels_per_second = int(total_pixels / elapsed) info.setdefault("encoding", {}).update({ "pixels_per_second": pixels_per_second, "regions_per_second": int(len(region_sizes) / elapsed), "average_region_size": int(total_pixels / len(region_sizes)), }) return info
def get_info(self) -> dict: cwqsizes = tuple(x[1] for x in tuple(self.compression_work_qsizes)) pqsizes = tuple(x[1] for x in tuple(self.packet_qsizes)) now = monotonic() time_limit = now-60 #ignore old records (60s) client_latency = max(0, self.avg_frame_total_latency- int((self.avg_client_ping_latency+self.avg_server_ping_latency)//2)) info = { "damage" : { "events" : self.damage_events_count, "packets_sent" : self.packet_count, "data_queue" : { "size" : get_list_stats(cwqsizes), }, "packet_queue" : { "size" : get_list_stats(pqsizes), }, "frame-total-latency" : self.avg_frame_total_latency, "client-latency" : client_latency, }, "encoding" : {"decode_errors" : self.decode_errors}, "connection" : self.get_connection_info(), } if self.quality: ql = tuple(quality for _,_,quality in self.quality) info["encoding"]["quality"] = get_list_stats(ql) if self.speed: sl = tuple(speed for _,_,speed in self.speed) info["encoding"]["speed"] = get_list_stats(sl) #client pixels per second: #pixels per second: decode time and overall total_pixels = 0 #total number of pixels processed total_time = 0 #total decoding time start_time = None #when we start counting from (oldest record) region_sizes = [] for _, event_time, pixels, decode_time in tuple(self.client_decode_time): #time filter and ignore failed decoding (decode_time==0) if event_time<time_limit or decode_time<=0: continue if start_time is None or start_time>event_time: start_time = event_time total_pixels += pixels total_time += decode_time region_sizes.append(pixels) log("total_time=%s, total_pixels=%s", total_time, total_pixels) if total_time>0: pixels_decoded_per_second = int(total_pixels *1000*1000 / total_time) info["encoding"]["pixels_decoded_per_second"] = pixels_decoded_per_second if start_time: elapsed = now-start_time pixels_per_second = int(total_pixels/elapsed) info.setdefault("encoding", {}).update({ "pixels_per_second" : pixels_per_second, "regions_per_second" : int(len(region_sizes)/elapsed), "average_region_size" : int(total_pixels/len(region_sizes)), }) return info
def get_info(self) -> dict: info = { "damage": { "events": self.damage_events_count, "packets_sent": self.packet_count, "target-latency": int(1000 * self.target_latency), } } #encoding stats: estats = tuple(self.encoding_stats) if estats: def add_compression_stats(enc_stats, encoding=None): comp_ratios_pct = [] comp_times_ns = [] total_pixels = 0 total_time = 0.0 for _, _, pixels, bpp, compressed_size, compression_time in enc_stats: if compressed_size > 0 and pixels > 0: osize = pixels * bpp / 8 comp_ratios_pct.append( (100.0 * compressed_size / osize, pixels)) comp_times_ns.append( (1000.0 * 1000 * 1000 * compression_time / pixels, pixels)) total_pixels += pixels total_time += compression_time einfo = info.setdefault("encoding", {}) if encoding: einfo = einfo.setdefault(encoding, {}) einfo["ratio_pct"] = get_weighted_list_stats(comp_ratios_pct) einfo["pixels_per_ns"] = get_weighted_list_stats(comp_times_ns) if total_time > 0: einfo["pixels_encoded_per_second"] = int(total_pixels / total_time) add_compression_stats(estats) encodings_used = tuple(x[1] for x in estats) for encoding in encodings_used: enc_stats = tuple(x for x in estats if x[1] == encoding) add_compression_stats(enc_stats, encoding) dinfo = info.setdefault("damage", {}) latencies = tuple(x[-1] * 1000 for x in tuple(self.damage_in_latency)) dinfo["in_latency"] = get_list_stats(latencies, show_percentile=[9]) latencies = tuple(x[-1] * 1000 for x in tuple(self.damage_out_latency)) dinfo["out_latency"] = get_list_stats(latencies, show_percentile=[9]) #per encoding totals: if self.encoding_totals: tf = info.setdefault("total_frames", {}) tp = info.setdefault("total_pixels", {}) for encoding, totals in self.encoding_totals.items(): tf[encoding] = totals[0] tp[encoding] = totals[1] return info
def get_client_info(self): latencies = [x * 1000 for (_, _, _, x) in list(self.client_latency)] info = { "connection": {"mmap_bytecount": self.mmap_bytes_sent}, "latency": get_list_stats(latencies), "server": {"ping_latency": get_list_stats(1000.0 * x for _, x in list(self.server_ping_latency))}, "client": {"ping_latency": get_list_stats(1000.0 * x for _, x in list(self.client_ping_latency))}, } if self.min_client_latency is not None: info["latency"] = {"absmin": int(self.min_client_latency * 1000)} return info
def get_connection_info(self): latencies = [x*1000 for (_, _, _, x) in tuple(self.client_latency)] info = { "mmap_bytecount" : self.mmap_bytes_sent, "latency" : get_list_stats(latencies), "server" : { "ping_latency" : get_list_stats(1000.0*x for _, x in tuple(self.server_ping_latency)), }, "client" : { "ping_latency" : get_list_stats(1000.0*x for _, x in tuple(self.client_ping_latency)), }, } if self.min_client_latency is not None: info["latency"] = {"absmin" : int(self.min_client_latency*1000)} return info
def get_info(self): info = {"damage" : {"events" : self.damage_events_count, "packets_sent" : self.packet_count} } #encoding stats: if len(self.encoding_stats)>0: estats = list(self.encoding_stats) encodings_used = [x[1] for x in estats] def add_compression_stats(enc_stats, encoding=None): comp_ratios_pct = [] comp_times_ns = [] total_pixels = 0 total_time = 0.0 for _, _, pixels, bpp, compressed_size, compression_time in enc_stats: if compressed_size>0 and pixels>0: osize = pixels*bpp/8 comp_ratios_pct.append((100.0*compressed_size/osize, pixels)) comp_times_ns.append((1000.0*1000*1000*compression_time/pixels, pixels)) total_pixels += pixels total_time += compression_time einfo = info.setdefault("encoding", {}) if encoding: einfo = einfo.setdefault(encoding, {}) einfo["ratio_pct"] = get_weighted_list_stats(comp_ratios_pct) einfo["pixels_per_ns"] = get_weighted_list_stats(comp_times_ns) if total_time>0: einfo["pixels_encoded_per_second"] = int(total_pixels / total_time) add_compression_stats(estats) for encoding in encodings_used: enc_stats = [x for x in estats if x[1]==encoding] add_compression_stats(enc_stats, encoding) dinfo = info.setdefault("damage", {}) latencies = [x*1000 for _, _, _, x in list(self.damage_in_latency)] dinfo["in_latency"] = get_list_stats(latencies, show_percentile=[9]) latencies = [x*1000 for _, _, _, x in list(self.damage_out_latency)] dinfo["out_latency"] = get_list_stats(latencies, show_percentile=[9]) #per encoding totals: if self.encoding_totals: tf = info.setdefault("total_frames", {}) tp = info.setdefault("total_pixels", {}) for encoding, totals in self.encoding_totals.items(): tf[encoding] = totals[0] tp[encoding] = totals[1] return info
def get_info(self): info = { "min-delay": self.min_delay, "max-delay": self.max_delay, "timeout-delay": self.timeout_delay, "locked": self.locked, } if len(self.last_delays) > 0: batch_delays = [x for _, x in list(self.last_delays)] info["delay"] = get_list_stats(batch_delays) if len(self.last_actual_delays) > 0: batch_delays = [x for _, x in list(self.last_actual_delays)] info["actual_delays"] = get_list_stats(batch_delays, show_percentile=[9]) for name, details, factor, weight in self.factors: fdetails = details.copy() fdetails[""] = int(100.0 * factor), int(100.0 * weight) info[name] = fdetails return info
def get_info(self): cwqsizes = [x for _, x in list(self.compression_work_qsizes)] pqsizes = [x for _, x in list(self.packet_qsizes)] info = { "damage": { "events": self.damage_events_count, "packets_sent": self.packet_count, "data_queue": {"size": get_list_stats(cwqsizes)}, "packet_queue": {"size": get_list_stats(pqsizes)}, }, "encoding": {"decode_errors": self.decode_errors}, } # client pixels per second: now = time.time() time_limit = now - 30 # ignore old records (30s) # pixels per second: decode time and overall total_pixels = 0 # total number of pixels processed total_time = 0 # total decoding time start_time = None # when we start counting from (oldest record) region_sizes = [] for _, event_time, pixels, decode_time in list(self.client_decode_time): # time filter and ignore failed decoding (decode_time==0) if event_time < time_limit or decode_time <= 0: continue if start_time is None or start_time > event_time: start_time = event_time total_pixels += pixels total_time += decode_time region_sizes.append(pixels) log("total_time=%s, total_pixels=%s", total_time, total_pixels) if total_time > 0: pixels_decoded_per_second = int(total_pixels * 1000 * 1000 / total_time) info["encoding"]["pixels_decoded_per_second"] = pixels_decoded_per_second if start_time: elapsed = now - start_time pixels_per_second = int(total_pixels / elapsed) info.setdefault("encoding", {}).update( { "pixels_per_second": pixels_per_second, "regions_per_second": int(len(region_sizes) / elapsed), "average_region_size": int(total_pixels / len(region_sizes)), } ) return info
def get_info(self): info = { "min-delay": self.min_delay, "max-delay": self.max_delay, "timeout-delay": self.timeout_delay, "locked": self.locked } if len(self.last_delays) > 0: batch_delays = [x for _, x in list(self.last_delays)] info["delay"] = get_list_stats(batch_delays) if len(self.last_actual_delays) > 0: batch_delays = [x for _, x in list(self.last_actual_delays)] info["actual_delays"] = get_list_stats(batch_delays, show_percentile=[9]) for name, details, factor, weight in self.factors: fdetails = details.copy() fdetails[""] = int(100.0 * factor), int(100.0 * weight) info[name] = fdetails return info