| 42 | self.stack_counter[(call_tree, thread_id)] += weight |
| 43 | |
| 44 | def export(self, filename): |
| 45 | lines = [] |
| 46 | for (call_tree, thread_id), count in self.stack_counter.items(): |
| 47 | parts = [f"tid:{thread_id}"] |
| 48 | for file, line, func in call_tree: |
| 49 | # This is what pstats does for "special" frames: |
| 50 | if file == "~" and line == 0: |
| 51 | part = func |
| 52 | else: |
| 53 | part = f"{os.path.basename(file)}:{func}:{line}" |
| 54 | parts.append(part) |
| 55 | stack_str = ";".join(parts) |
| 56 | lines.append((stack_str, count)) |
| 57 | |
| 58 | lines.sort(key=lambda x: (-x[1], x[0])) |
| 59 | |
| 60 | with open(filename, "w") as f: |
| 61 | for stack, count in lines: |
| 62 | f.write(f"{stack} {count}\n") |
| 63 | print(f"Collapsed stack output written to {filename}") |
| 64 | |
| 65 | |
| 66 | class FlamegraphCollector(StackTraceCollector): |