[Repoze-checkins] r681 - in repoze.profile/trunk: . repoze/profile
Tres Seaver
tseaver at palladion.com
Fri Feb 8 19:16:02 UTC 2008
Author: Tres Seaver <tseaver at palladion.com>
Date: Fri Feb 8 14:16:01 2008
New Revision: 681
Log:
Eggify the accumulating profiler.
Added:
repoze.profile/trunk/repoze/profile/
repoze.profile/trunk/repoze/profile/__init__.py
repoze.profile/trunk/repoze/profile/profiler.py (contents, props changed)
Modified:
repoze.profile/trunk/CHANGES.txt
repoze.profile/trunk/README.txt
repoze.profile/trunk/TODO.txt
repoze.profile/trunk/setup.py
Modified: repoze.profile/trunk/CHANGES.txt
==============================================================================
--- repoze.profile/trunk/CHANGES.txt (original)
+++ repoze.profile/trunk/CHANGES.txt Fri Feb 8 14:16:01 2008
@@ -1,4 +1,3 @@
-0.1
+repoze.profile 0.1 (2008-02-08)
Initial release.
-
Modified: repoze.profile/trunk/README.txt
==============================================================================
--- repoze.profile/trunk/README.txt (original)
+++ repoze.profile/trunk/README.txt Fri Feb 8 14:16:01 2008
@@ -1 +1,4 @@
-A readme file.
+repoze.profile README
+
+ This package provides a WSGI middleware component which aggregates
+ profiling data across *all* requests to the WSGI application.
Modified: repoze.profile/trunk/TODO.txt
==============================================================================
--- repoze.profile/trunk/TODO.txt (original)
+++ repoze.profile/trunk/TODO.txt Fri Feb 8 14:16:01 2008
@@ -1 +1 @@
-List todo items here.
+- [_] Package up the profile component into an egg.
Added: repoze.profile/trunk/repoze/profile/__init__.py
==============================================================================
--- (empty file)
+++ repoze.profile/trunk/repoze/profile/__init__.py Fri Feb 8 14:16:01 2008
@@ -0,0 +1,9 @@
+from paste.debug.profile import profile_decorator
+
+class OKView:
+ def __init__(self, context, request):
+ self.context = context
+ self.request = request
+
+ def __call__(self):
+ return 'OK'
Added: repoze.profile/trunk/repoze/profile/profiler.py
==============================================================================
--- (empty file)
+++ repoze.profile/trunk/repoze/profile/profiler.py Fri Feb 8 14:16:01 2008
@@ -0,0 +1,78 @@
+""" Middleware that profiles all requests, accumulating timings.
+
+o Insprired by the paste.debug.profile version, which profiles single requests.
+"""
+import profile
+import threading
+
+DEFAULT_PROFILE_LOG = 'wsgi.prof'
+
+class AccumulatingProfileMiddleware(object):
+
+ def __init__(self, app,
+ global_conf=None,
+ log_filename=DEFAULT_PROFILE_LOG,
+ discard_first_request=True,
+ ):
+ self.app = app
+ self.profiler = profile.Profile()
+ self.log_filename = log_filename
+ self.first_request = discard_first_request
+ self.lock = threading.Lock()
+
+ def __call__(self, environ, start_response):
+ catch_response = []
+ body = []
+
+ def replace_start_response(status, headers, exc_info=None):
+ catch_response.extend([status, headers])
+ start_response(status, headers, exc_info)
+ return body.append
+
+ def run_app():
+ app_iter = self.app(environ, replace_start_response)
+ try:
+ body.extend(app_iter)
+ finally:
+ if hasattr(app_iter, 'close'):
+ app_iter.close()
+
+ self.lock.acquire()
+ try:
+ self.profiler.runctx('run_app()', globals(), locals())
+
+ if self.first_request: # discard to avoid timing warm-up
+ self.profiler = profile.Profile()
+ self.first_request = False
+ else:
+ self.profiler.dump_stats(self.log_filename)
+
+ body = ''.join(body)
+ return [body]
+ finally:
+ self.lock.release()
+
+
+def make_profile_middleware(app,
+ global_conf,
+ log_filename=DEFAULT_PROFILE_LOG,
+ discard_first_request=True,
+ ):
+ """Wrap the application in a component that will profile each
+ request, appending data from each request to an aggregate
+ file.
+
+ Nota bene
+ ---------
+
+ o This middleware serializes all requests (i.e., removing concurrency).
+
+ o The Python profiler is seriously SLOW (maybe an order of magnitude!).
+
+ o Ergo, NEVER USE THIS MIDDLEWARE IN PRODUCTION.
+ """
+ return AccumulatingProfileMiddleware(
+ app,
+ log_filename=log_filename,
+ discard_first_request=discard_first_request
+ )
Modified: repoze.profile/trunk/setup.py
==============================================================================
--- repoze.profile/trunk/setup.py (original)
+++ repoze.profile/trunk/setup.py Fri Feb 8 14:16:01 2008
@@ -24,9 +24,9 @@
here = os.path.abspath(os.path.dirname(__file__))
README = open(os.path.join(here, 'README.txt')).read()
-setup(name='repoze.atemplate',
+setup(name='repoze.profile',
version=__version__,
- description='A template for repoze projects',
+ description='Aggregate profiling for WSGI requests',
long_description=README,
classifiers=[
"Development Status :: 1 - Planning",
@@ -51,14 +51,8 @@
install_requires=[],
#test_suite="repoze.",
entry_points = """\
- #[console_scripts]
- #addzope2user = repoze.atemplate.scripts.adduser:main
-
- #[repoze.project]
- #initialize = repoze.atemplate.instance:mkinstance
-
- #[paste.filter_app_factory]
- #middleware = repoze.atemplate:constructor
+ [paste.filter_app_factory]
+ profile = repoze.profile.profiler:make_profile_middleware
"""
)
More information about the Repoze-checkins
mailing list