diff --git a/src/exabgp/application/server.py b/src/exabgp/application/server.py index 6e275460c..29add8928 100755 --- a/src/exabgp/application/server.py +++ b/src/exabgp/application/server.py @@ -200,14 +200,11 @@ def run(comment, configurations, pid=0): exit_code = Reactor(configuration).run() __exit(env.debug.memory, exit_code) - try: - import cProfile as profile - except ImportError: - import profile + import cProfile if env.profile.file == 'stdout': profiled = 'Reactor(configuration).run()' - exit_code = profile.run(profiled) + exit_code = cProfile.run(profiled) __exit(env.debug.memory, exit_code) if pid: @@ -221,37 +218,33 @@ def run(comment, configurations, pid=0): if os.path.exists(profile_name): notice = 'profile can not use this filename as output, it already exists (%s)' % profile_name - if not notice: - cwd = os.getcwd() - log.debug('profiling ....', 'reactor') - profiler = profile.Profile() - profiler.enable() + if notice: + log.debug('-' * len(notice), 'reactor') + log.debug(notice, 'reactor') + log.debug('-' * len(notice), 'reactor') + + cwd = os.getcwd() + log.debug('profiling ....', 'reactor') + + destination = profile_name if profile_name.startswith('/') else os.path.join(cwd, profile_name) + + with cProfile.Profile() as profiler: + exit_code = 0 try: exit_code = Reactor(configuration).run() - except Exception: + except Exception as e: exit_code = Reactor.Exit.unknown - raise - finally: - from exabgp.vendoring import lsprofcalltree + log.critical(str(e)) - profiler.disable() - kprofile = lsprofcalltree.KCacheGrind(profiler) - try: - destination = profile_name if profile_name.startswith('/') else os.path.join(cwd, profile_name) - with open(destination, 'w+') as write: - kprofile.output(write) - except IOError: - notice = 'could not save profiling in formation at: ' + destination - log.debug('-' * len(notice), 'reactor') - log.debug(notice, 'reactor') - log.debug('-' * len(notice), 'reactor') - __exit(env.debug.memory, exit_code) - else: - log.debug('-' * len(notice), 'reactor') - log.debug(notice, 'reactor') - log.debug('-' * len(notice), 'reactor') - Reactor(configuration).run() - __exit(env.debug.memory, 1) + try: + profiler.dump_stats(destination) + except Exception: + notice = 'could not save profiling in formation at: ' + destination + log.debug('-' * len(notice), 'reactor') + log.debug(notice, 'reactor') + log.debug('-' * len(notice), 'reactor') + + __exit(env.debug.memory, exit_code) def main(): diff --git a/src/exabgp/vendoring/lsprofcalltree.py b/src/exabgp/vendoring/lsprofcalltree.py deleted file mode 100644 index aab772e28..000000000 --- a/src/exabgp/vendoring/lsprofcalltree.py +++ /dev/null @@ -1,128 +0,0 @@ -# coding: utf-8 - -# lsprofcalltree.py: lsprof output which is readable by kcachegrind -# David Allouche -# Jp Calderone & Itamar Shtull-Trauring -# Johan Dahlin -# Sébastien Boisgérault - -from __future__ import print_function - -import optparse -import os -import sys - -try: - import cProfile -except ImportError: - raise SystemExit('This script requires cProfile from Python 2.5') - - -def label(code): - if isinstance(code, str): - return ('~', 0, code) # built-in functions ('~' sorts at the end) - else: - return '%s %s:%d' % (code.co_name, code.co_filename, code.co_firstlineno) - - -class KCacheGrind(object): - def __init__(self, profiler): - self.data = profiler.getstats() - self.out_file = None - - def output(self, out_file): - self.out_file = out_file - print('events: Ticks', file=out_file) - self._print_summary() - for entry in self.data: - self._entry(entry) - - def _print_summary(self): - max_cost = 0 - for entry in self.data: - totaltime = int(entry.totaltime * 1000) - max_cost = max(max_cost, totaltime) - print('summary: %d' % (max_cost,), file=self.out_file) - - def _entry(self, entry): - out_file = self.out_file - - code = entry.code - # print(u'ob=%s' % (code.co_filename,), file=out_file) - if isinstance(code, str): - print('fi=~', file=out_file) - else: - print('fi=%s' % (code.co_filename,), file=out_file) - print('fn=%s' % (label(code),), file=out_file) - - inlinetime = int(entry.inlinetime * 1000) - if isinstance(code, str): - print('0 ', inlinetime, file=out_file) - else: - print('%d %d' % (code.co_firstlineno, inlinetime), file=out_file) - - # recursive calls are counted in entry.calls - if entry.calls: - calls = entry.calls - else: - calls = [] - - if isinstance(code, str): - lineno = 0 - else: - lineno = code.co_firstlineno - - for subentry in calls: - self._subentry(lineno, subentry) - print('', file=out_file) - - def _subentry(self, lineno, subentry): - out_file = self.out_file - code = subentry.code - # print(u'cob=%s' % (code.co_filename,), file=out_file) - print('cfn=%s' % (label(code),), file=out_file) - if isinstance(code, str): - print('cfi=~', file=out_file) - print('calls=%d 0' % (subentry.callcount,), file=out_file) - else: - print('cfi=%s' % (code.co_filename,), file=out_file) - print('calls=%d %d' % (subentry.callcount, code.co_firstlineno), file=out_file) - - totaltime = int(subentry.totaltime * 1000) - print('%d %d' % (lineno, totaltime), file=out_file) - - -def main(args): - usage = '%s [-o output_file_path] scriptfile [arg] ...' - parser = optparse.OptionParser(usage=usage % sys.argv[0]) - parser.allow_interspersed_args = False - parser.add_option('-o', '--outfile', dest='outfile', help='Save stats to ', default=None) - - if not sys.argv[1:]: - parser.print_usage() - sys.exit(2) - - options, args = parser.parse_args() - - if not options.outfile: - options.outfile = '%s.log' % os.path.basename(args[0]) - - sys.argv[:] = args - - prof = cProfile.Profile() - try: - try: - prof = prof.run('execfile(%r)' % (sys.argv[0],)) - except SystemExit: - pass - finally: - kg = KCacheGrind(prof) - try: - out_file = open(options.outfile, 'w', encoding='utf-8') - except TypeError: - out_file = open(options.outfile, 'w') - kg.output(out_file) - - -if __name__ == '__main__': - sys.exit(main(sys.argv))