def generate_recommendations(report, node_info): """generate recommendations and add them to report""" report.append("recommendations") report.append("---------------") # generate recommendations fc_recs = OrderedDict() for node in node_info: key = recs.analyze_filter_cache_stats(node) if key[0] and key[1]: if key not in fc_recs: fc_recs[key] = [] fc_recs[key].append(node.name) if not fc_recs: report.append("No recommendations\n") return sorted_recs = [] for rec in fc_recs: nodes = fc_recs[rec] sorted_recs.append((rec[0], rec[1], nodes, len(nodes))) sorted(sorted_recs, key=itemgetter(3), reverse=True) if len(sorted_recs) > 1: report.append("NOTE: Do top recommendation first.") report.append("") for rec in sorted_recs: # allows nodes to be tabbed out for a block look nodes_fmtd = humanize.format_list(rec[2], newline="\n" + " " * 17) report.append("* affects nodes: %s\n reason: %s\n fix: %s" % (nodes_fmtd, rec[0], rec[1])) report.append("")
def test_format_list_with_many_elements(self): """should wrap next line""" data = ["1", "2", "3", "4", "5", "6", "7"] output = humanize.format_list(data) self.assertEqual(output, "1, 2, 3\n4, 5, 6\n7")
def test_format_list_with_2_elements(self): """should use separator""" self.assertEqual(humanize.format_list(["1", "2"]), "1, 2")
def test_format_list_with_1_element(self): """should not mess with single element output""" self.assertEqual(humanize.format_list(["1"]), "1")
def test_format_list_with_no_elements(self): """zero case""" self.assertEqual(humanize.format_list([]), "")
def test_format_list_with_2_elements(): """should use separator""" assert humanize.format_list(["1", "2"]) == "1, 2"
def test_format_list_with_1_element(): """should not mess with single element output""" assert humanize.format_list(["1"]) == "1"
def test_format_list_with_no_elements(): """zero case""" assert humanize.format_list([]) == ""
def write_config(report, config): #pylint: disable=too-many-statements """generates the configuration text""" append(report, "nodes count", simple_format(config.get("nodes"))) append(report, "cass drive(s) read ahead", _format_read_ahead(config.get("cass_ra"))) append(report, "dse version", simple_format(config.get("version"))) append(report, "cassandra version", simple_format(config.get("cassandra_version"))) append(report, "solr version", simple_format(config.get("solr_version"))) append(report, "spark version", simple_format(config.get("spark_version"))) append(report, "spark connector version", _format_spark_connector(config)) append(report, "disk access mode", format_disk_access_mode(config)) append(report, 'disk optimization', simple_format(config.get('disk_optimization_strategy'))) append(report, "memtable cleanup threshold", \ simple_format(config.get("memtable_cleanup_threshold"))) append(report, "flush writers", _format_flush_writers(config.get("memtable_flush_writers"))) append(report, "compaction throughput", \ _format_compaction_throughput(config.get("compaction_throughput_mb_per_sec"))) append(report, "concurrent compactors", simple_format(config.get("concurrent_compactors"))) memtable_heap_size = config.get("memtable_heap_space_in_mb", config.get("memtable_space_in_mb")) append(report, "memtable size (heap)", simple_format(memtable_heap_size)) append(report, "memtable size (offheap)", \ simple_format(config.get("memtable_offheap_space_in_mb"))) append(report, "memtable allocation type", \ simple_format(config.get("memtable_allocation_type"))) append(report, "file cache size", \ simple_format(config.get("file_cache_size_in_mb"))) append(report, "heap size", \ simple_format(config.get("heap_size"))) append(report, "gc", simple_format(config.get("gc"))) append(report, "total ram", simple_format(config.get("ram_in_mb"))) append(report, "total cpu cores (real)", _format_cores(config)) append(report, "threads per core", \ simple_format(config.get("threads_per_core"))) append(report, "worst gc pause", format_gc(config)) append(report, "worst write latency (all)", \ format_table_stat_float(config.get("worst_write_latency"), val_suffix="ms")) append(report, "worst read latency (all)", \ format_table_stat_float(config.get("worst_read_latency"), val_suffix="ms")) append(report, "worst tombstones query (all)", \ format_table_stat(config.get("worst_tombstone"))) append(report, "worst live cells query (all)", \ format_table_stat(config.get("worst_live_cells"))) append(report, "largest table", format_largest_table(config)) append(report, "busiest table reads", format_busiest_table(config.get("busiest_table_reads"), "reads")) append(report, "busiest table writes", format_busiest_table(config.get("busiest_table_writes"), "writes")) append(report, "worst partition in", format_table_loc(config.get('worst_part_size'))) append(report, "* max partition size", \ format_partition_bytes(config.get('worst_part_size'), 2)) append(report, "* mean partition size", \ format_partition_bytes(config.get('worst_part_size'), 3)) append(report, "* min partition size", \ format_partition_bytes(config.get('worst_part_size'), 4)) report.append("") report.append("nodes") report.append("-----") report.append(humanize.format_list(config.get("nodes_list"), wrap_every=5)) report.append("") if config.get("diff"): conversions = { "ram_in_mb": "ram in mb", "cpu_cores": "cpu", "threads_per_core": "cpu threads", "cass_ra": "read ahead", } report.append("") report.append("config diff from common:") for diff in config.get("diff"): tokens = diff.split(":") if len(tokens) > 1: key = conversions.get(tokens[0], tokens[0]) if key.startswith("-Xms"): # duplicates heap size continue if key.startswith("-Xmx"): # duplicates heap size continue if key == "read ahead": value = _format_read_ahead(config.get("cass_ra")) else: value = tokens[1] report.append("* %s: %s" % (key, value))
def generate_report(parsed, recommendations): """generates report from calculated data""" calculated = parsed.get("summary") # allows nodes to be tabbed out for a block look table = [] table.append(["nodes", simple_format(calculated.get("nodes"))]) table.append([ "dse version(s) (startup logs)", format_list(calculated.get("versions", [])) ]) table.append([ "cassandra version(s) (startup logs)", format_list(calculated.get("cassandra_versions", [])), ]) table.append([ "solr version(s) (startup logs)", format_list(calculated.get("solr_versions", [])), ]) table.append([ "spark version(s) (startup logs)", format_list(calculated.get("spark_versions", [])), ]) table.append(["worst gc pause (system logs)", format_gc(calculated)]) table.append([ "worst read latency (cfstats)", format_table_stat_float(calculated.get("worst_read_latency"), val_suffix="ms"), ]) table.append([ "worst write latency (cfstats)", format_table_stat_float(calculated.get("worst_write_latency"), val_suffix="ms"), ]) table.append([ "worst tombstones query (cfstats)", format_table_stat(calculated.get("worst_tombstone")), ]) table.append([ "worst live cells query (cfstats)", format_table_stat(calculated.get("worst_live_cells")), ]) table.append(["largest table (cfstats)", format_largest_table(calculated)]) table.append([ "busiest table reads (cfstats)", format_busiest_table(calculated.get("busiest_table_reads"), "reads"), ]) table.append([ "busiest table writes (cfstats)", format_busiest_table(calculated.get("busiest_table_writes"), "writes"), ]) table.append([ "largest partition (cfstats)", format_partition_bytes(calculated.get("worst_part_size"), 2) + " " + format_table_loc(calculated.get("worst_part_size")), ]) humanize.pad_table(table) report = [""] for row in table: report.append(" ".join(row)) report.append("") report.append("errors parsing") report.append("--------------") if parsed.get("warnings"): for warning in parsed.get("warnings"): report.append("* %s" % warning) else: report.append("No parsing errors") # "* random error is here" report.append("") report.append("recommendations") report.append("---------------") # recs here if recommendations: for rec in recommendations: rec_str = "* %s." % rec.get("issue") if rec.get("rec"): rec_str = rec_str + " %s." % rec.get("rec") report.append(rec_str) if rec.get("nodes"): # allows nodes to be tabbed out for a block look nodes_fmtd = humanize.format_list(rec.get("nodes"), newline="\n" + " " * 18) report.append(" nodes affected: %s" % nodes_fmtd) report.append(" --") else: report.append("No recommendations") return "\n".join(report)