8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
# File 'lib/heapscope/report/markdown.rb', line 8
def render(report)
lines = []
lines << "# HeapScope Report"
lines << ""
lines << "- **Version:** #{report.heapscope_version}"
lines << "- **Ruby:** #{report.runtime_info[:ruby]} (#{report.runtime_info[:engine]})"
lines << "- **Result:** #{report.summary[:healthy] ? "HEALTHY" : "ATTENTION"}"
lines << ""
if report.before && report.after
lines << "## Memory"
lines << ""
lines << "| Metric | Before | After | Delta |"
lines << "|--------|--------|-------|-------|"
lines << "| RSS | #{mb(report.before.)} | #{mb(report.after.)} | #{mb(report.diff&.)} |"
lines << "| Live slots | #{report.before.heap_live_slots} | #{report.after.heap_live_slots} | #{report.diff&.heap_live_delta} |"
lines << ""
end
if report.diff
lines << "## Top class growth"
lines << ""
lines << "| Class | Before | After | Delta | Bytes Δ |"
lines << "|-------|--------|-------|-------|---------|"
report.diff.growing_classes(15).each do |c|
lines << "| `#{c[:name]}` | #{c[:before_count]} | #{c[:after_count]} | #{c[:delta_count]} | #{mb(c[:delta_bytes])} |"
end
lines << ""
end
unless report.findings.empty?
lines << "## Findings"
lines << ""
report.findings.each do |f|
lines << "### #{f.code} — #{f.title} (`#{f.severity}`)"
f.facts.each { |fact| lines << "- Fact: #{fact}" }
f.derived.each { |d| lines << "- Derived: #{d}" }
lines << "- Hypothesis: #{f.hypothesis}" if f.hypothesis
lines << "- Suspected cause: #{f.suspected_cause}" if f.suspected_cause
lines << ""
end
end
if report.reproduction
lines << "## Reproduction"
lines << ""
lines << "```bash"
lines << report.reproduction[:command].to_s
lines << "```"
lines << ""
end
steps = Suggest.next_steps(report)
unless steps.empty?
lines << "## Next steps"
lines << ""
steps.each_with_index do |step, i|
tag = step[:code] || "hint"
lines << "#{i + 1}. **[#{tag}]** #{step[:action]}"
end
lines << ""
end
lines << "_Privacy: object values are not serialized by default._"
lines << ""
lines << "_#{Branding.}_"
lines.join("\n")
end
|