def print_report(self): "prints a report for the file this class was initialized with, analyzing if necessary" if not self.analyzed: self.analyze() print("sysbottle version %s" % VERSION) print() print() print("* total records: %s" % self.count) if self.count: def report_percentage(a): return (float(a) / float(self.count)) * 100.0 print( "* total bottleneck time: %.2f%% (cpu bound, io bound, or both)" % report_percentage(self.iowait_exceeded + self.cpu_exceeded)) print("* cpu+system+nice+steal time > %.2f%%: %.2f%%" % (self.conf["cpu_threshold"], report_percentage(self.cpu_exceeded))) print("* iowait time > %.2f%%: %.2f%%" % ( self.conf["iowait_threshold"], report_percentage(self.iowait_exceeded), )) print("* start %s" % self.start) print("* end %s" % self.end) log_time_seconds = (self.end - self.start).total_seconds() + 1 print("* log time: %ss" % log_time_seconds) print("* interval: %ss" % report_percentage(log_time_seconds)) for device in self.devices.keys(): print("* %s time at queue depth >= %.2f: %.2f%%" % ( device, self.conf["queue_threshold"], report_percentage(self.queuedepth[device]), )) print() lines = [] lines.append(get_percentile_headers()) lines.append(["", "---", "---", "---", "---", "---", "---"]) lines.append(get_percentiles("cpu", self.cpu_stats["total"])) lines.append(get_percentiles("iowait", self.cpu_stats["%iowait"])) lines.append([]) lines.append(get_percentile_headers()) lines.append(["", "---", "---", "---", "---", "---", "---"]) for device in self.devices: lines.append([device, "", "", "", "", "", ""]) for iotype in self.devices[device].keys(): if "qu" in iotype or "wait" in iotype: lines.append( get_percentiles("- " + iotype + ":", self.devices[device][iotype])) lines.append([]) humanize.pad_table(lines, 8, 2) for line in lines: print("".join(line)) self.print_recommendations()
def __print_gc(self, data): """ print data to the user, expecting datetime keys and list(int) values """ print(". <300ms + 301-500ms ! >500ms") print('-'*30) busiest = None for time, pauses in data: total = sum(pauses) if not busiest: busiest = (time, total) elif total > busiest[1]: busiest = (time, total) print(time.strftime("%Y-%m-%d %H:%M:%S"), end=' ') print(len(pauses), end=' ') for pause in pauses: c = '.' if pause > 300: c = '+' if pause > 500: c = '!' print(c, end='') print('') print('') print('busiest period: %s (%sms)' % (busiest[0].strftime("%Y-%m-%d %H:%M:%S"), busiest[1])) print('') percentiles = [[]] percentiles.append(get_percentile_headers("GC pauses")) header = [""] header.extend(["---" for i in range(6)]) percentiles.append(header) percentiles.append(get_percentiles("ms", list(itertools.chain.from_iterable( pauses for time, pauses in data)), strformat="%i")) pad_table(percentiles, min_width=11, extra_pad=2) for line in percentiles: print("".join(line)) print()
def test_get_percentile_headers(): """happy path and default""" perc = util.get_percentile_headers(label='stuff', names=('max', 'p99', 'p90', 'p25', 'min')) assert perc[0] == "stuff" assert perc[1] == "max" assert perc[2] == "p99" assert perc[3] == "p90" assert perc[4] == "p25" assert perc[5] == "min" perc = util.get_percentile_headers() assert perc[0] == "" assert perc[1] == "max" assert perc[2] == "p99" assert perc[3] == "p75" assert perc[4] == "p50" assert perc[5] == "p25" assert perc[6] == "min"
def test_get_percentile_headers(self): """happy path and default""" perc = util.get_percentile_headers(label="stuff", names=("max", "p99", "p90", "p25", "min")) self.assertEqual(perc[0], "stuff") self.assertEqual(perc[1], "max") self.assertEqual(perc[2], "p99") self.assertEqual(perc[3], "p90") self.assertEqual(perc[4], "p25") self.assertEqual(perc[5], "min") perc = util.get_percentile_headers() self.assertEqual(perc[0], "") self.assertEqual(perc[1], "max") self.assertEqual(perc[2], "p99") self.assertEqual(perc[3], "p75") self.assertEqual(perc[4], "p50") self.assertEqual(perc[5], "p25") self.assertEqual(perc[6], "min")
def print_summary(self): """ prints a summary report """ self.analyze() summary = Summary(self.nodes) print("%s version: %s" % (self.command_name, VERSION)) print('') print("Summary (%s lines)" % format_num(summary.lines)) print("Summary (%s skipped lines)" % format_num(summary.skipped_lines)) print('') print("dse versions: %s" % (set(summary.versions) or 'unknown')) print("cassandra versions: %s" % (set(summary.cassandra_versions) or 'unknown')) print("first log time: %s" % summary.start) print("last log time: %s" % summary.end) if not self.dumps_analyzed: print("Nothing found!") return print("duration: %s" % format_seconds(int(summary.duration.total_seconds()))) print("total stages analyzed: %s" % self.dumps_analyzed) print("total nodes analyzed: %s" % len(summary.nodes)) pauses = summary.get_pauses() if pauses: print('') percentiles = [] percentiles.append(get_percentile_headers("GC pauses")) percentiles.append(["", "---", "---", "---", "---", "---", "---"]) percentiles.append(get_percentiles("ms", pauses, strformat="%i")) pad_table(percentiles, min_width=11, extra_pad=2) for line in percentiles: print("".join(line)) print("total GC events: %s" % len(pauses)) print('') ops = summary.get_busiest_tables('ops')[:5] if ops: print("busiest tables by ops across all nodes") print('-' * 30) for onode, (oname, num) in ops: print("* %s: %s: %s" % (onode, oname, num)) print('') print("busiest table by data across all nodes") print('-' * 30) for dnode, (dname, data) in summary.get_busiest_tables('data')[:5]: print("* %s: %s: %s" % (dnode, dname, data)) print('') print("busiest stages across all nodes") print('-' * 30) data = [] for (name, status, stage, value) in summary.get_busiest_stages(): data.append( ["* %s %s:" % (stage, status), str(value), "(%s)" % name]) pad_table(data, extra_pad=2) for line in data: print("".join(line)) pending = summary.get_stages_in('pending') data = [] if pending: data.append([]) self.__print_stages('pending', pending, data) delayed = summary.get_stages_in('local backpressure') if delayed: data.append([]) self.__print_backpressure(delayed, data) data.append([]) pad_table(data, extra_pad=2) for line in data: print("".join(line)) self.__print_recs()
def print_histogram(self): """ print histogram report, analyzing if necessary """ self.analyze() print("%s version: %s" % (self.command_name, VERSION)) print('') print("Histogram") print('') if not self.nodes: print("Nothing found!") return for name, node in self.nodes.items(): print(name) print('-' * 60) print("%s lines" % format_num(node.lines)) print("%s skipped lines" % format_num(node.skipped_lines)) print("dse version: %s" % (node.version or 'unknown')) print("cassandra version: %s" % (node.cassandra_version or 'unknown')) print("log start time: %s" % node.start) print("log end time: %s" % node.end) if not node.dumps_analyzed: print("Nothing found!") continue print("duration: %s" % format_seconds(int(node.duration().total_seconds()))) print("stages analyzed: %s" % node.dumps_analyzed) if node.pauses: percentiles = [[]] percentiles.append(get_percentile_headers("GC pauses")) header = [""] header.extend(["---" for i in range(6)]) percentiles.append(header) percentiles.append( get_percentiles("ms", node.pauses, strformat="%i")) pad_table(percentiles, min_width=11, extra_pad=2) for line in percentiles: print("".join(line)) print("total GC events: %s" % len(node.pauses)) print('') ops = node.get_busiest_tables('ops')[:5] if ops: print("busiest tables (ops)") print('-' * 30) nlen = max(len(o[0]) for o in ops) for n, t in ops: print(n.ljust(nlen), t) data = node.get_busiest_tables('data')[:5] print("busiest tables (data)") print('-' * 30) nlen = max(len(d[0]) for d in data) for n, t in data: print(n.ljust(nlen), t) print('') if node.stages: percentiles = [] percentiles.append(get_percentile_headers('stages')) percentiles.append([]) for status, stage in node.stages.items(): header = [status.upper()] header.extend("" for i in range(6)) percentiles.append(header) for tpname, vals in sorted(stage.items(), key=lambda tpool: max(tpool[1]), reverse=True): percentiles.append( get_percentiles(tpname, vals, strformat="%i")) percentiles.append([]) pad_table(percentiles, extra_pad=2) for line in percentiles: print("".join(line)) print('') self.__print_recs()