Last active
August 16, 2020 13:07
-
-
Save iambibhas/e0ee436d307b257087d2b79f04212b43 to your computer and use it in GitHub Desktop.
Takes a profile file, a method name and depth, and shows you the chain of callers of the method
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pstats | |
import re | |
import sys | |
from io import StringIO | |
""" | |
E.g. | |
python pstats-chain.py GET.foobar.com.testurl.46689ms.1597427246.prof 'time.sleep' 10 | |
""" | |
pattern = re.compile(r"\/.*") | |
prof_file = sys.argv[1] | |
start_method = sys.argv[2] | |
max_depth = int(sys.argv[3]) | |
class PstatsChainHandler: | |
def __init__(self, prof_file, max_depth=5) -> None: | |
self.prof_file = prof_file | |
self.max_depth = max_depth | |
self.depth_count = 0 | |
def find_caller(self, method): | |
stream = StringIO() | |
stats = pstats.Stats(self.prof_file, stream=stream) | |
stats.sort_stats("time", "calls") | |
stats.print_callers(method) | |
lines = stream.getvalue().splitlines() | |
if len(lines) < 6: | |
print("there are no valid caller details") | |
for caller in lines[5:-2]: | |
try: | |
_, caller_deets = caller.split("<-") | |
matches = re.findall(pattern, caller_deets) | |
if matches: | |
match = re.sub(r"\(\w+\)", "", matches[0]) | |
print(match) | |
self.depth_count += 1 | |
if self.depth_count <= self.max_depth: | |
self.find_caller(match) | |
except ValueError: | |
return | |
handler = PstatsChainHandler(prof_file=prof_file, max_depth=max_depth) | |
handler.find_caller(start_method) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment