public inbox for gentoo-catalyst@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-catalyst] [PATCH 1/2] main: add a --trace option
@ 2015-11-23 12:07 Mike Frysinger
  2015-11-23 12:07 ` [gentoo-catalyst] [PATCH 2/2] main: add a --profile option Mike Frysinger
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Mike Frysinger @ 2015-11-23 12:07 UTC (permalink / raw
  To: gentoo-catalyst

This helps a lot with debugging as you can quickly get a transcript
of the python code paths that are taken by catalyst.
---
 catalyst/main.py | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/catalyst/main.py b/catalyst/main.py
index f48293e..3550809 100644
--- a/catalyst/main.py
+++ b/catalyst/main.py
@@ -170,6 +170,11 @@ $ catalyst -f stage1-specfile.spec"""
 		dest='color', action='store_false',
 		help='never colorize output all the time (default: detect)')
 
+	group = parser.add_argument_group('Developer options')
+	group.add_argument('--trace',
+		default=False, action='store_true',
+		help='trace program output (akin to `sh -x`)')
+
 	group = parser.add_argument_group('Temporary file management')
 	group.add_argument('-a', '--clear-autoresume',
 		default=False, action='store_true',
@@ -203,10 +208,54 @@ $ catalyst -f stage1-specfile.spec"""
 	return parser
 
 
+def trace(func, *args, **kwargs):
+	"""Run |func| through the trace module (akin to `sh -x`)"""
+	import trace
+
+	# Ignore common system modules we use.
+	ignoremods = set((
+		'argparse',
+		'genericpath', 'gettext',
+		'locale',
+		'os',
+		'posixpath',
+		're',
+		'sre_compile', 'sre_parse', 'sys',
+		'tempfile', 'threading',
+		'UserDict',
+	))
+
+	# Ignore all the system modules.
+	ignoredirs = set(sys.path)
+	# But try to strip out the catalyst paths.
+	try:
+		ignoredirs.remove(os.path.dirname(os.path.dirname(
+			os.path.realpath(__file__))))
+	except KeyError:
+		pass
+
+	tracer = trace.Trace(
+		count=False,
+		trace=True,
+		timing=True,
+		ignoremods=ignoremods,
+		ignoredirs=ignoredirs)
+	return tracer.runfunc(func, *args, **kwargs)
+
+
 def main(argv):
+	"""The main entry point for frontends to use"""
 	parser = get_parser()
 	opts = parser.parse_args(argv)
 
+	if opts.trace:
+		return trace(_main, parser, opts)
+	else:
+		return _main(parser, opts)
+
+
+def _main(parser, opts):
+	"""The "main" main function so we can trace/profile."""
 	# Initialize the logger before anything else.
 	log_level = opts.log_level
 	if log_level is None:
-- 
2.6.2



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [gentoo-catalyst] [PATCH 2/2] main: add a --profile option
  2015-11-23 12:07 [gentoo-catalyst] [PATCH 1/2] main: add a --trace option Mike Frysinger
@ 2015-11-23 12:07 ` Mike Frysinger
  2015-11-23 12:15   ` Mike Frysinger
  2015-12-15 17:26   ` Brian Dolbec
  2015-11-23 12:13 ` [gentoo-catalyst] [PATCH 1/2] main: add a --trace option Mike Frysinger
  2015-12-15 17:26 ` Brian Dolbec
  2 siblings, 2 replies; 6+ messages in thread
From: Mike Frysinger @ 2015-11-23 12:07 UTC (permalink / raw
  To: gentoo-catalyst

When things get slow, this option helps narrow down where things
are getting hung up.
---
 catalyst/main.py | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/catalyst/main.py b/catalyst/main.py
index 3550809..cb90e66 100644
--- a/catalyst/main.py
+++ b/catalyst/main.py
@@ -174,6 +174,9 @@ $ catalyst -f stage1-specfile.spec"""
 	group.add_argument('--trace',
 		default=False, action='store_true',
 		help='trace program output (akin to `sh -x`)')
+	group.add_argument('--profile',
+		default=False, action='store_true',
+		help='profile program execution')
 
 	group = parser.add_argument_group('Temporary file management')
 	group.add_argument('-a', '--clear-autoresume',
@@ -243,6 +246,25 @@ def trace(func, *args, **kwargs):
 	return tracer.runfunc(func, *args, **kwargs)
 
 
+def profile(func, *args, **kwargs):
+	"""Run |func| through the profile module"""
+	# Should make this an option.
+	sort_keys = ('time',)
+
+	# Collect the profile.
+	import cProfile
+	profiler = cProfile.Profile(subcalls=True, builtins=True)
+	try:
+		ret = profiler.runcall(func, *args, **kwargs)
+	finally:
+		# Then process the results.
+		import pstats
+		stats = pstats.Stats(profiler, stream=sys.stderr)
+		stats.strip_dirs().sort_stats(*sort_keys).print_stats()
+
+	return ret
+
+
 def main(argv):
 	"""The main entry point for frontends to use"""
 	parser = get_parser()
@@ -250,6 +272,8 @@ def main(argv):
 
 	if opts.trace:
 		return trace(_main, parser, opts)
+	elif opts.profile:
+		return profile(_main, parser, opts)
 	else:
 		return _main(parser, opts)
 
-- 
2.6.2



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [gentoo-catalyst] [PATCH 1/2] main: add a --trace option
  2015-11-23 12:07 [gentoo-catalyst] [PATCH 1/2] main: add a --trace option Mike Frysinger
  2015-11-23 12:07 ` [gentoo-catalyst] [PATCH 2/2] main: add a --profile option Mike Frysinger
@ 2015-11-23 12:13 ` Mike Frysinger
  2015-12-15 17:26 ` Brian Dolbec
  2 siblings, 0 replies; 6+ messages in thread
From: Mike Frysinger @ 2015-11-23 12:13 UTC (permalink / raw
  To: gentoo-catalyst

[-- Attachment #1: Type: text/plain, Size: 2814 bytes --]

On 23 Nov 2015 07:07, Mike Frysinger wrote:
> This helps a lot with debugging as you can quickly get a transcript
> of the python code paths that are taken by catalyst.

example output:
$ ./bin/catalyst.git --trace
 --- modulename: main, funcname: _main
0.00 main.py(284): 	log_level = opts.log_level
0.00 main.py(285): 	if log_level is None:
0.00 main.py(286): 		if opts.debug:
0.00 main.py(288): 		elif opts.verbose:
0.00 main.py(291): 			log_level = 'notice'
0.00 main.py(292): 	log.setup_logging(log_level, output=opts.log_file, debug=opts.debug,
0.00 main.py(293): 		color=opts.color)
 --- modulename: log, funcname: setup_logging
0.00 log.py(109): 	level = logging.getLevelName(level.upper())
0.00 log.py(112): 	fmt = '%(asctime)s: %(levelname)-8s: '
0.00 log.py(113): 	if debug:
0.00 log.py(115): 	fmt += '%(message)s'
0.00 log.py(118): 	if output is None:
0.00 log.py(119): 		handler = logging.StreamHandler(stream=sys.stdout)
0.00 log.py(125): 	tzname = time.strftime('%Z', time.localtime())
0.00 log.py(126): 	datefmt = '%d %b %Y %H:%M:%S ' + tzname
0.00 log.py(127): 	formatter = CatalystFormatter(fmt, datefmt, color=color)
 --- modulename: log, funcname: __init__
0.00 log.py(83): 		color = kwargs.pop('color', None)
0.00 log.py(84): 		if color is None:
0.00 log.py(85): 			color = self.detect_color()
 --- modulename: log, funcname: detect_color
0.00 log.py(77): 		if 'NOCOLOR' is os.environ:
0.00 log.py(79): 		return os.isatty(sys.stdout.fileno())
0.00 log.py(86): 		if not color:
0.00 log.py(87): 			self._COLORS = {}
0.00 log.py(89): 		super(CatalystFormatter, self).__init__(*args, **kwargs)
0.00 log.py(128): 	handler.setFormatter(formatter)
0.00 log.py(130): 	logger.addHandler(handler)
0.00 log.py(131): 	logger.setLevel(level)
0.00 main.py(296): 	myconfigs = opts.configs
0.00 main.py(297): 	if not myconfigs:
0.00 main.py(299): 	myspecfile = opts.file
0.00 main.py(300): 	mycmdline = opts.cli[:]
0.00 main.py(302): 	if opts.snapshot:
0.00 main.py(306): 	conf_values['DEBUG'] = opts.debug
0.00 main.py(307): 	conf_values['VERBOSE'] = opts.debug or opts.verbose
0.00 main.py(309): 	options = set()
0.00 main.py(310): 	if opts.fetchonly:
0.00 main.py(312): 	if opts.purge:
0.00 main.py(314): 	if opts.purgeonly:
0.00 main.py(316): 	if opts.purgetmponly:
0.00 main.py(318): 	if opts.clear_autoresume:
0.00 main.py(322): 	if not myspecfile and not mycmdline:
0.00 main.py(323): 		parser.error('please specify one of either -f or -C or -s')
usage: catalyst [-h] [-V] [-d] [-v]
                [--log-level {critical,error,warning,notice,info,debug}]
                [--log-file LOG_FILE] [--color] [--nocolor] [--trace]
                [--profile] [-a] [-p] [-P] [-T] [-F] [-c CONFIGS] [-f FILE]
                [-s SNAPSHOT] [-C ...]
catalyst: error: please specify one of either -f or -C or -s

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [gentoo-catalyst] [PATCH 2/2] main: add a --profile option
  2015-11-23 12:07 ` [gentoo-catalyst] [PATCH 2/2] main: add a --profile option Mike Frysinger
@ 2015-11-23 12:15   ` Mike Frysinger
  2015-12-15 17:26   ` Brian Dolbec
  1 sibling, 0 replies; 6+ messages in thread
From: Mike Frysinger @ 2015-11-23 12:15 UTC (permalink / raw
  To: gentoo-catalyst

[-- Attachment #1: Type: text/plain, Size: 10153 bytes --]

On 23 Nov 2015 07:07, Mike Frysinger wrote:
> When things get slow, this option helps narrow down where things
> are getting hung up.

example output (although not as interesting since it's not a full run):
$ ./bin/catalyst.git --profile
usage: catalyst [-h] [-V] [-d] [-v]
                [--log-level {critical,error,warning,notice,info,debug}]
                [--log-file LOG_FILE] [--color] [--nocolor] [--trace]
                [--profile] [-a] [-p] [-P] [-T] [-F] [-c CONFIGS] [-f FILE]
                [-s SNAPSHOT] [-C ...]
catalyst: error: please specify one of either -f or -C or -s

         2133 function calls (2090 primitive calls) in 0.002 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        6    0.000    0.000    0.001    0.000 argparse.py:384(_format_actions_usage)
     10/7    0.000    0.000    0.000    0.000 sre_parse.py:395(_parse)
        4    0.000    0.000    0.000    0.000 argparse.py:336(get_lines)
       25    0.000    0.000    0.000    0.000 {method 'sub' of '_sre.SRE_Pattern' objects}
     18/5    0.000    0.000    0.000    0.000 sre_compile.py:64(_compile)
       30    0.000    0.000    0.001    0.000 re.py:230(_compile)
        3    0.000    0.000    0.000    0.000 gettext.py:424(find)
       73    0.000    0.000    0.000    0.000 sre_parse.py:193(__next)
    25/12    0.000    0.000    0.000    0.000 sre_parse.py:151(getwidth)
        2    0.000    0.000    0.002    0.001 argparse.py:292(_format_usage)
        6    0.000    0.000    0.000    0.000 gettext.py:132(_expand_lang)
      430    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}
        5    0.000    0.000    0.000    0.000 sre_compile.py:433(_compile_info)
       67    0.000    0.000    0.000    0.000 sre_parse.py:141(__getitem__)
       12    0.000    0.000    0.000    0.000 posixpath.py:61(join)
  399/388    0.000    0.000    0.000    0.000 {len}
      113    0.000    0.000    0.000    0.000 {isinstance}
        6    0.000    0.000    0.000    0.000 sre_compile.py:256(_optimize_charset)
       24    0.000    0.000    0.000    0.000 argparse.py:573(_format_args)
       12    0.000    0.000    0.000    0.000 {posix.stat}
       57    0.000    0.000    0.000    0.000 sre_parse.py:212(get)
       12    0.000    0.000    0.000    0.000 genericpath.py:23(exists)
       24    0.000    0.000    0.000    0.000 argparse.py:557(_metavar_formatter)
      8/5    0.000    0.000    0.000    0.000 sre_parse.py:317(_parse_sub)
       61    0.000    0.000    0.000    0.000 {method 'get' of 'dict' objects}
        4    0.000    0.000    0.000    0.000 {method 'findall' of '_sre.SRE_Pattern' objects}
        3    0.000    0.000    0.000    0.000 sre_parse.py:734(parse_template)
        5    0.000    0.000    0.000    0.000 sre_parse.py:706(parse)
       24    0.000    0.000    0.001    0.000 re.py:148(sub)
        5    0.000    0.000    0.001    0.000 sre_compile.py:567(compile)
       18    0.000    0.000    0.000    0.000 re.py:264(_compile_repl)
        6    0.000    0.000    0.000    0.000 sre_compile.py:228(_compile_charset)
        2    0.000    0.000    0.000    0.000 {method 'write' of 'file' objects}
        1    0.000    0.000    0.000    0.000 log.py:105(setup_logging)
       38    0.000    0.000    0.000    0.000 sre_parse.py:137(__len__)
        6    0.000    0.000    0.000    0.000 locale.py:363(normalize)
        6    0.000    0.000    0.000    0.000 {sorted}
        5    0.000    0.000    0.000    0.000 sre_compile.py:552(_code)
        1    0.000    0.000    0.000    0.000 argparse.py:154(__init__)
       20    0.000    0.000    0.000    0.000 argparse.py:566(format)
       40    0.000    0.000    0.000    0.000 sre_parse.py:206(match)
       18    0.000    0.000    0.000    0.000 sre_parse.py:92(__init__)
       18    0.000    0.000    0.000    0.000 re.py:284(_subx)
        1    0.000    0.000    0.002    0.002 argparse.py:205(format_help)
       40    0.000    0.000    0.000    0.000 {min}
        7    0.000    0.000    0.000    0.000 sre_compile.py:428(_simple)
        1    0.000    0.000    0.002    0.002 main.py:281(_main)
        1    0.000    0.000    0.000    0.000 {time.localtime}
       29    0.000    0.000    0.000    0.000 {method 'join' of 'str' objects}
        3    0.000    0.000    0.000    0.000 gettext.py:530(dgettext)
       12    0.000    0.000    0.000    0.000 UserDict.py:58(get)
       26    0.000    0.000    0.000    0.000 {method 'find' of 'bytearray' objects}
        3    0.000    0.000    0.000    0.000 locale.py:347(_replace_encoding)
        3    0.000    0.000    0.000    0.000 gettext.py:464(translation)
        7    0.000    0.000    0.000    0.000 sre_parse.py:268(_escape)
        4    0.000    0.000    0.000    0.000 re.py:173(findall)
       25    0.000    0.000    0.000    0.000 {method 'upper' of 'str' objects}
       10    0.000    0.000    0.000    0.000 sre_compile.py:546(isstring)
        4    0.000    0.000    0.000    0.000 sre_parse.py:236(_class_escape)
        1    0.000    0.000    0.000    0.000 {time.strftime}
       21    0.000    0.000    0.000    0.000 sre_parse.py:149(append)
        1    0.000    0.000    0.000    0.000 __init__.py:644(_addHandlerRef)
       18    0.000    0.000    0.000    0.000 {method 'find' of 'str' objects}
        3    0.000    0.000    0.000    0.000 __init__.py:49(normalize_encoding)
        9    0.000    0.000    0.000    0.000 {method 'split' of 'str' objects}
        5    0.000    0.000    0.000    0.000 {_sre.compile}
        2    0.000    0.000    0.000    0.000 threading.py:147(acquire)
        8    0.000    0.000    0.000    0.000 sre_parse.py:189(__init__)
       36    0.000    0.000    0.000    0.000 {method 'endswith' of 'str' objects}
       36    0.000    0.000    0.000    0.000 {method 'startswith' of 'str' objects}
        3    0.000    0.000    0.000    0.000 sre_parse.py:85(closegroup)
        1    0.000    0.000    0.000    0.000 log.py:81(__init__)
        3    0.000    0.000    0.000    0.000 gettext.py:568(gettext)
        1    0.000    0.000    0.000    0.000 __init__.py:154(getLevelName)
        1    0.000    0.000    0.000    0.000 __init__.py:825(__init__)
        9    0.000    0.000    0.000    0.000 {method 'translate' of 'str' objects}
       12    0.000    0.000    0.000    0.000 UserDict.py:70(__contains__)
        1    0.000    0.000    0.002    0.002 argparse.py:2364(error)
        2    0.000    0.000    0.000    0.000 __init__.py:183(_checkLevel)
        1    0.000    0.000    0.000    0.000 argparse.py:250(add_usage)
        1    0.000    0.000    0.000    0.000 log.py:74(detect_color)
        5    0.000    0.000    0.000    0.000 sre_parse.py:67(__init__)
        1    0.000    0.000    0.000    0.000 threading.py:132(__init__)
        7    0.000    0.000    0.000    0.000 {method 'strip' of 'str' objects}
        1    0.000    0.000    0.000    0.000 argparse.py:2326(_get_formatter)
        4    0.000    0.000    0.000    0.000 UserDict.py:18(__getitem__)
        2    0.000    0.000    0.000    0.000 argparse.py:2350(_print_message)
        1    0.000    0.000    0.000    0.000 __init__.py:663(__init__)
        1    0.000    0.000    0.002    0.002 argparse.py:2332(print_usage)
        4    0.000    0.000    0.000    0.000 {hasattr}
        1    0.000    0.000    0.000    0.000 __init__.py:692(createLock)
        2    0.000    0.000    0.000    0.000 threading.py:187(release)
        2    0.000    0.000    0.000    0.000 re.py:192(compile)
        1    0.000    0.000    0.002    0.002 argparse.py:2287(format_usage)
        3    0.000    0.000    0.000    0.000 sre_parse.py:74(opengroup)
        2    0.000    0.000    0.000    0.000 argparse.py:287(_join_parts)
        6    0.000    0.000    0.000    0.000 {method 'replace' of 'str' objects}
       18    0.000    0.000    0.000    0.000 {ord}
        1    0.000    0.000    0.002    0.002 argparse.py:280(format_help)
        3    0.000    0.000    0.000    0.000 {method 'index' of 'str' objects}
        2    0.000    0.000    0.000    0.000 {method 'acquire' of 'thread.lock' objects}
        1    0.000    0.000    0.000    0.000 {posix.isatty}
        6    0.000    0.000    0.000    0.000 {method 'reverse' of 'list' objects}
        1    0.000    0.000    0.000    0.000 {method 'fileno' of 'file' objects}
        1    0.000    0.000    0.000    0.000 argparse.py:199(__init__)
        6    0.000    0.000    0.000    0.000 {method 'extend' of 'list' objects}
        1    0.000    0.000    0.000    0.000 threading.py:114(RLock)
        2    0.000    0.000    0.000    0.000 __init__.py:220(_releaseLock)
        4    0.000    0.000    0.000    0.000 {max}
        1    0.000    0.000    0.000    0.000 __init__.py:585(__init__)
        7    0.000    0.000    0.000    0.000 sre_parse.py:145(__setitem__)
        1    0.000    0.000    0.000    0.000 __init__.py:1137(setLevel)
        1    0.000    0.000    0.000    0.000 argparse.py:2359(exit)
        1    0.000    0.000    0.000    0.000 {sys.exit}
        1    0.000    0.000    0.000    0.000 __init__.py:397(__init__)
        2    0.000    0.000    0.000    0.000 {method 'release' of 'thread.lock' objects}
        1    0.000    0.000    0.000    0.000 __init__.py:762(setFormatter)
        2    0.000    0.000    0.000    0.000 __init__.py:211(_acquireLock)
        1    0.000    0.000    0.000    0.000 __init__.py:1296(addHandler)
        6    0.000    0.000    0.000    0.000 {range}
        1    0.000    0.000    0.000    0.000 {method 'pop' of 'dict' objects}
        4    0.000    0.000    0.000    0.000 {thread.get_ident}
        5    0.000    0.000    0.000    0.000 {method 'items' of 'dict' objects}
        1    0.000    0.000    0.000    0.000 argparse.py:230(_add_item)
        1    0.000    0.000    0.000    0.000 {thread.allocate_lock}
        3    0.000    0.000    0.000    0.000 {method 'remove' of 'list' objects}
        1    0.000    0.000    0.000    0.000 threading.py:80(__init__)
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
-mike

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [gentoo-catalyst] [PATCH 1/2] main: add a --trace option
  2015-11-23 12:07 [gentoo-catalyst] [PATCH 1/2] main: add a --trace option Mike Frysinger
  2015-11-23 12:07 ` [gentoo-catalyst] [PATCH 2/2] main: add a --profile option Mike Frysinger
  2015-11-23 12:13 ` [gentoo-catalyst] [PATCH 1/2] main: add a --trace option Mike Frysinger
@ 2015-12-15 17:26 ` Brian Dolbec
  2 siblings, 0 replies; 6+ messages in thread
From: Brian Dolbec @ 2015-12-15 17:26 UTC (permalink / raw
  To: gentoo-catalyst

On Mon, 23 Nov 2015 07:07:40 -0500
Mike Frysinger <vapier@gentoo.org> wrote:

> This helps a lot with debugging as you can quickly get a transcript
> of the python code paths that are taken by catalyst.
> ---
>  catalyst/main.py | 49
> +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49
> insertions(+)
> 
> diff --git a/catalyst/main.py b/catalyst/main.py
> index f48293e..3550809 100644
> --- a/catalyst/main.py
> +++ b/catalyst/main.py
> @@ -170,6 +170,11 @@ $ catalyst -f stage1-specfile.spec"""
>  		dest='color', action='store_false',
>  		help='never colorize output all the time (default:
> detect)') 
> +	group = parser.add_argument_group('Developer options')
> +	group.add_argument('--trace',
> +		default=False, action='store_true',
> +		help='trace program output (akin to `sh -x`)')
> +
>  	group = parser.add_argument_group('Temporary file
> management') group.add_argument('-a', '--clear-autoresume',
>  		default=False, action='store_true',
> @@ -203,10 +208,54 @@ $ catalyst -f stage1-specfile.spec"""
>  	return parser
>  
>  
> +def trace(func, *args, **kwargs):
> +	"""Run |func| through the trace module (akin to `sh -x`)"""
> +	import trace
> +
> +	# Ignore common system modules we use.
> +	ignoremods = set((
> +		'argparse',
> +		'genericpath', 'gettext',
> +		'locale',
> +		'os',
> +		'posixpath',
> +		're',
> +		'sre_compile', 'sre_parse', 'sys',
> +		'tempfile', 'threading',
> +		'UserDict',
> +	))
> +
> +	# Ignore all the system modules.
> +	ignoredirs = set(sys.path)
> +	# But try to strip out the catalyst paths.
> +	try:
> +		ignoredirs.remove(os.path.dirname(os.path.dirname(
> +			os.path.realpath(__file__))))
> +	except KeyError:
> +		pass
> +
> +	tracer = trace.Trace(
> +		count=False,
> +		trace=True,
> +		timing=True,
> +		ignoremods=ignoremods,
> +		ignoredirs=ignoredirs)
> +	return tracer.runfunc(func, *args, **kwargs)
> +
> +
>  def main(argv):
> +	"""The main entry point for frontends to use"""
>  	parser = get_parser()
>  	opts = parser.parse_args(argv)
>  
> +	if opts.trace:
> +		return trace(_main, parser, opts)
> +	else:
> +		return _main(parser, opts)
> +
> +
> +def _main(parser, opts):
> +	"""The "main" main function so we can trace/profile."""
>  	# Initialize the logger before anything else.
>  	log_level = opts.log_level
>  	if log_level is None:


Yeah, looks good.  Not sure I'll use it yet, but...
-- 
Brian Dolbec <dolsen>



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [gentoo-catalyst] [PATCH 2/2] main: add a --profile option
  2015-11-23 12:07 ` [gentoo-catalyst] [PATCH 2/2] main: add a --profile option Mike Frysinger
  2015-11-23 12:15   ` Mike Frysinger
@ 2015-12-15 17:26   ` Brian Dolbec
  1 sibling, 0 replies; 6+ messages in thread
From: Brian Dolbec @ 2015-12-15 17:26 UTC (permalink / raw
  To: gentoo-catalyst

On Mon, 23 Nov 2015 07:07:41 -0500
Mike Frysinger <vapier@gentoo.org> wrote:

> When things get slow, this option helps narrow down where things
> are getting hung up.
> ---
>  catalyst/main.py | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/catalyst/main.py b/catalyst/main.py
> index 3550809..cb90e66 100644
> --- a/catalyst/main.py
> +++ b/catalyst/main.py
> @@ -174,6 +174,9 @@ $ catalyst -f stage1-specfile.spec"""
>  	group.add_argument('--trace',
>  		default=False, action='store_true',
>  		help='trace program output (akin to `sh -x`)')
> +	group.add_argument('--profile',
> +		default=False, action='store_true',
> +		help='profile program execution')
>  
>  	group = parser.add_argument_group('Temporary file
> management') group.add_argument('-a', '--clear-autoresume',
> @@ -243,6 +246,25 @@ def trace(func, *args, **kwargs):
>  	return tracer.runfunc(func, *args, **kwargs)
>  
>  
> +def profile(func, *args, **kwargs):
> +	"""Run |func| through the profile module"""
> +	# Should make this an option.
> +	sort_keys = ('time',)
> +
> +	# Collect the profile.
> +	import cProfile
> +	profiler = cProfile.Profile(subcalls=True, builtins=True)
> +	try:
> +		ret = profiler.runcall(func, *args, **kwargs)
> +	finally:
> +		# Then process the results.
> +		import pstats
> +		stats = pstats.Stats(profiler, stream=sys.stderr)
> +
> stats.strip_dirs().sort_stats(*sort_keys).print_stats() +
> +	return ret
> +
> +
>  def main(argv):
>  	"""The main entry point for frontends to use"""
>  	parser = get_parser()
> @@ -250,6 +272,8 @@ def main(argv):
>  
>  	if opts.trace:
>  		return trace(_main, parser, opts)
> +	elif opts.profile:
> +		return profile(_main, parser, opts)
>  	else:
>  		return _main(parser, opts)
>  

Profiling is good :)


-- 
Brian Dolbec <dolsen>



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2015-12-15 17:27 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-11-23 12:07 [gentoo-catalyst] [PATCH 1/2] main: add a --trace option Mike Frysinger
2015-11-23 12:07 ` [gentoo-catalyst] [PATCH 2/2] main: add a --profile option Mike Frysinger
2015-11-23 12:15   ` Mike Frysinger
2015-12-15 17:26   ` Brian Dolbec
2015-11-23 12:13 ` [gentoo-catalyst] [PATCH 1/2] main: add a --trace option Mike Frysinger
2015-12-15 17:26 ` Brian Dolbec

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox