Skip to content
Browse files

[#2401]: Add CLI for time/speed profiling of requests.

  • Loading branch information...
1 parent 968690e commit 112e405d0116bdcf196062520e3474e231337996 @davidread davidread committed
Showing with 65 additions and 1 deletion.
  1. +62 −0 ckan/lib/cli.py
  2. +2 −1 profile_tests.py
  3. +1 −0 setup.py
View
62 ckan/lib/cli.py
@@ -1144,3 +1144,65 @@ def command(self):
raise NotImplementedError
if self.verbose:
print 'Creating %s test data: Complete!' % cmd
+
+class Profile(CkanCommand):
+ '''Code speed profiler
+ Provide a ckan url and it will make the request and record
+ how long each function call took in a file that can be read
+ by runsnakerun.
+
+ Usage:
+ profile {url}
+
+ e.g. profile /data/search
+
+ The result is saved in profile.data.search
+ To view the profile in runsnakerun:
+ runsnakerun ckan.data.search.profile
+
+ You may need to install python module: cProfile
+ '''
+ summary = __doc__.split('\n')[0]
+ usage = __doc__
+ max_args = 1
+ min_args = 1
+
+ def _load_config_into_test_app(self):
+ from paste.deploy import loadapp
+ import paste.fixture
+ if not self.options.config:
+ msg = 'No config file supplied'
+ raise self.BadCommand(msg)
+ self.filename = os.path.abspath(self.options.config)
+ if not os.path.exists(self.filename):
+ raise AssertionError('Config filename %r does not exist.' % self.filename)
+ fileConfig(self.filename)
+
+ wsgiapp = loadapp('config:' + self.filename)
+ self.app = paste.fixture.TestApp(wsgiapp)
+
+ def command(self):
+ self._load_config_into_test_app()
+
+ import paste.fixture
+ import cProfile
+ import re
+
+ url = self.args[0]
+
+ def profile_url(url):
+ try:
+ res = self.app.get(url, status=[200], extra_environ={'REMOTE_USER': 'visitor'})
+ except paste.fixture.AppError:
+ print 'App error: ', url.strip()
+ except KeyboardInterrupt:
+ raise
+ except:
+ import traceback
+ traceback.print_exc()
+ print 'Unknown error: ', url.strip()
+
+ output_filename = 'ckan%s.profile' % re.sub('[/?]', '.', url.replace('/', '.'))
+ profile_command = "profile_url('%s')" % url
+ cProfile.runctx(profile_command, globals(), locals(), filename=output_filename)
+ print 'Written profile to: %s' % output_filename
View
3 profile_tests.py
@@ -1,4 +1,5 @@
+# Runs all the tests and save a speed profile to ckan.tests.profile
import nose
import cProfile
command = """nose.main(argv=['--ckan','--with-pylons=test-core.ini', 'ckan/tests', '-x', '-v'])"""
-cProfile.runctx( command, globals(), locals(), filename="ckan.profile" )
+cProfile.runctx( command, globals(), locals(), filename="ckan.tests.profile" )
View
1 setup.py
@@ -73,6 +73,7 @@
rdf-export = ckan.lib.cli:RDFExport
tracking = ckan.lib.cli:Tracking
plugin-info = ckan.lib.cli:PluginInfo
+ profile = ckan.lib.cli:Profile
[console_scripts]
ckan-admin = bin.ckan_admin:Command

0 comments on commit 112e405

Please sign in to comment.
Something went wrong with that request. Please try again.