# Profile mitmdump with apachebench and
# yappi (https://code.google.com/p/yappi/)
#
# Requirements:
# - Apache Bench "ab" binary
# - pip install click yappi

from mitmproxy.main import mitmdump
from os import system
from threading import Thread
import time

import yappi
import click


class ApacheBenchThread(Thread):

    def __init__(self, concurrency):
        self.concurrency = concurrency
        super().__init__()

    def run(self):
        time.sleep(2)
        system(
            "ab -n 1024 -c {} -X 127.0.0.1:8080 http://example.com/".format(self.concurrency))


@click.command()
@click.option('--profiler', default="none", type=click.Choice(['none', 'yappi']))
@click.option('--clock-type', default="cpu", type=click.Choice(['wall', 'cpu']))
@click.option('--concurrency', default=1, type=click.INT)
def main(profiler, clock_type, concurrency):

    outfile = "callgrind.mitmdump-{}-c{}".format(clock_type, concurrency)
    a = ApacheBenchThread(concurrency)
    a.start()

    if profiler == "yappi":
        yappi.set_clock_type(clock_type)
        yappi.start(addons=True)

    print("Start mitmdump...")
    mitmdump(["-k", "-q", "-S", "1024example"])
    print("mitmdump stopped.")

    print("Save profile information...")
    if profiler == "yappi":
        yappi.stop()
        stats = yappi.get_func_stats()
        stats.save(outfile, type='callgrind')
    print("Done.")


if __name__ == '__main__':
    main()

[((29, 1, 29, 16), 'click.command', 'click.command', ({}, {}), '()', False, 'import click\n'), ((32, 1, 32, 57), 'click.option', 'click.option', (), '', False, 'import click\n'), ((44, 4, 44, 47), 'mitmproxy.main.mitmdump', 'mitmdump', ({(44, 13, 44, 46): "['-k', '-q', '-S', '1024example']"}, {}), "(['-k', '-q', '-S', '1024example'])", False, 'from mitmproxy.main import mitmdump\n'), ((24, 8, 24, 21), 'time.sleep', 'time.sleep', ({(24, 19, 24, 20): '(2)'}, {}), '(2)', False, 'import time\n'), ((40, 8, 40, 40), 'yappi.set_clock_type', 'yappi.set_clock_type', ({(40, 29, 40, 39): 'clock_type'}, {}), '(clock_type)', False, 'import yappi\n'), ((41, 8, 41, 32), 'yappi.start', 'yappi.start', (), '', False, 'import yappi\n'), ((49, 8, 49, 20), 'yappi.stop', 'yappi.stop', ({}, {}), '()', False, 'import yappi\n'), ((50, 16, 50, 38), 'yappi.get_func_stats', 'yappi.get_func_stats', ({}, {}), '()', False, 'import yappi\n'), ((30, 49, 30, 80), 'click.Choice', 'click.Choice', ({(30, 62, 30, 79): "['none', 'yappi']"}, {}), "(['none', 'yappi'])", False, 'import click\n'), ((31, 50, 31, 79), 'click.Choice', 'click.Choice', ({(31, 63, 31, 78): "['wall', 'cpu']"}, {}), "(['wall', 'cpu'])", False, 'import click\n')]