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_filter_cache_analysis_zero_set(self): """when filter cache eviction duration is longer than 1 second recommend raising limits""" stats = types.SimpleNamespace() stats.avg_evict_freq = 0.0 stats.avg_evict_duration = 0.0 stats.perc_item_limit = 0.0 reason, rec = recs.analyze_filter_cache_stats(stats) self.assertIsNone(rec) self.assertIsNone(reason)
def test_filter_cache_analysis_long_duration_evictions(): """when filter cache eviction duration is longer than 1 second recommend raising limits""" stats = types.SimpleNamespace() stats.avg_evict_freq = 60.0 stats.avg_evict_duration = 1001 stats.last_evict_item_limit = 256000 stats.perc_item_limit = 0.95 reason, rec = recs.analyze_filter_cache_stats(stats) assert reason == "Filter cache eviction duration is too long." assert rec == "Lower filter cache item limit from 256000 to 32000 via -Dsolr.solrfiltercache.maxSize."
def test_filter_cache_analysis_frequent_evictions(): """when filter cache eviction freq is sooner than ever 20 seconds recommend raising limits""" stats = types.SimpleNamespace() stats.avg_evict_freq = 19.9 stats.avg_evict_duration = 10 stats.last_evict_item_limit = 32000 stats.perc_item_limit = 0.95 reason, rec = recs.analyze_filter_cache_stats(stats) assert reason == "Filter cache evictions are happening too frequently." assert rec == "Raise filter cache item limit from 32000 to 256000 via -Dsolr.solrfiltercache.maxSize."
def test_limit_eviction_limit_already_reached(): """already as low as one can go""" stats = types.SimpleNamespace() stats.avg_evict_freq = 100.0 stats.avg_evict_duration = 1244.0 stats.last_evict_item_limit = 31000 stats.perc_item_limit = 0.95 reason, rec = recs.analyze_filter_cache_stats(stats) assert reason == "Filter cache eviction duration long but limit is already too low." assert rec == "Make more FQ queries uncached. " + \ "Example: change \"fq\":\"status:DELETED\" to \"fq\":\"{!cached=false}status:DELETED\"."
def test_filter_cache_analysis_frequent_long_evictions(): """when filter cache eviction duration is longer than 1 second recommend raising limits""" stats = types.SimpleNamespace() stats.avg_evict_freq = 10.0 stats.avg_evict_duration = 60001 stats.last_evict_item_limit = 256000 stats.perc_item_limit = 0.95 reason, rec = recs.analyze_filter_cache_stats(stats) assert reason == "Filter cache evictions are happening too frequently and too slowly." assert rec == "Make more FQ queries uncached. " + \ "Example: change \"fq\":\"status:DELETED\" to \"fq\":\"{!cached=false}status:DELETED\"."
def test_limit_eviction_limit_already_reached(self): """already as low as one can go""" stats = types.SimpleNamespace() stats.avg_evict_freq = 100.0 stats.avg_evict_duration = 1244.0 stats.last_evict_item_limit = 31000 stats.perc_item_limit = 0.95 reason, rec = recs.analyze_filter_cache_stats(stats) self.assertEqual( reason, "Filter cache eviction duration long but limit is already too low." ) self.assertEqual( rec, "Make more FQ queries uncached. " + 'Example: change "fq":"status:DELETED" to "fq":"{!cached=false}status:DELETED".', )
def test_filter_cache_analysis_frequent_long_evictions(self): """when filter cache eviction duration is longer than 1 second recommend raising limits""" stats = types.SimpleNamespace() stats.avg_evict_freq = 10.0 stats.avg_evict_duration = 60001 stats.last_evict_item_limit = 256000 stats.perc_item_limit = 0.95 reason, rec = recs.analyze_filter_cache_stats(stats) self.assertEqual( reason, "Filter cache evictions are happening too frequently and too slowly.", ) self.assertEqual( rec, "Make more FQ queries uncached. " + 'Example: change "fq":"status:DELETED" to "fq":"{!cached=false}status:DELETED".', )
def test_filter_cache_analysis_none_set(self): """when filter cache eviction duration is longer than 1 second recommend raising limits""" stats = types.SimpleNamespace() reason, rec = recs.analyze_filter_cache_stats(stats) self.assertIsNone(rec) self.assertIsNone(reason)