[Checkins] SVN: z3ext.profiler/trunk/ added portlet profiler
Nikolay Kim
fafhrd91 at gmail.com
Mon Jul 13 05:35:34 EDT 2009
Log message for revision 101843:
added portlet profiler
Changed:
U z3ext.profiler/trunk/CHANGES.txt
U z3ext.profiler/trunk/setup.py
A z3ext.profiler/trunk/src/z3ext/profiler/configlet.py
U z3ext.profiler/trunk/src/z3ext/profiler/configure.zcml
A z3ext.profiler/trunk/src/z3ext/profiler/edit.pt
A z3ext.profiler/trunk/src/z3ext/profiler/interfaces.py
A z3ext.profiler/trunk/src/z3ext/profiler/pagelet.py
A z3ext.profiler/trunk/src/z3ext/profiler/portlet.py
A z3ext.profiler/trunk/src/z3ext/profiler/stats.py
-=-
Modified: z3ext.profiler/trunk/CHANGES.txt
===================================================================
--- z3ext.profiler/trunk/CHANGES.txt 2009-07-13 09:33:05 UTC (rev 101842)
+++ z3ext.profiler/trunk/CHANGES.txt 2009-07-13 09:35:33 UTC (rev 101843)
@@ -2,6 +2,15 @@
CHANGES
=======
+
+2.0.0 (Unreleased)
+------------------
+
+- Use configlet for profiler
+
+- Added profiler for pagelets, portlets, pageelements
+
+
1.1.0 (2008-03-28)
------------------
Modified: z3ext.profiler/trunk/setup.py
===================================================================
--- z3ext.profiler/trunk/setup.py 2009-07-13 09:33:05 UTC (rev 101842)
+++ z3ext.profiler/trunk/setup.py 2009-07-13 09:35:33 UTC (rev 101843)
@@ -21,7 +21,7 @@
def read(*rnames):
return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
-version='1.2.0dev'
+version='2.0.0dev'
setup(name = 'z3ext.profiler',
@@ -51,6 +51,12 @@
'zope.app.wsgi',
'zope.app.folder',
'zope.app.publisher',
+ 'z3ext.cache',
+ 'z3ext.layout',
+ 'z3ext.portlet',
+ 'z3ext.pageelement',
+ 'z3ext.controlpanel',
+ 'z3ext.wizard',
],
include_package_data = True,
zip_safe = False
Added: z3ext.profiler/trunk/src/z3ext/profiler/configlet.py
===================================================================
--- z3ext.profiler/trunk/src/z3ext/profiler/configlet.py (rev 0)
+++ z3ext.profiler/trunk/src/z3ext/profiler/configlet.py 2009-07-13 09:35:33 UTC (rev 101843)
@@ -0,0 +1,28 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+
+$Id: 2007-12-12 12:27:02Z fafhrd $
+"""
+from zope.app.component.hooks import getSite
+from zope.traversing.interfaces import IContainmentRoot
+
+
+class ProfilerConfiglet(object):
+
+ def isAvailable(self):
+ if not IContainmentRoot.providedBy(getSite()):
+ return False
+
+ return super(ProfilerConfiglet, self).isAvailable()
Modified: z3ext.profiler/trunk/src/z3ext/profiler/configure.zcml
===================================================================
--- z3ext.profiler/trunk/src/z3ext/profiler/configure.zcml 2009-07-13 09:33:05 UTC (rev 101842)
+++ z3ext.profiler/trunk/src/z3ext/profiler/configure.zcml 2009-07-13 09:35:33 UTC (rev 101843)
@@ -1,14 +1,31 @@
<configure
xmlns="http://namespaces.zope.org/zope"
+ xmlns:z3ext="http://namespaces.zope.org/z3ext"
xmlns:browser="http://namespaces.zope.org/browser">
- <browser:page
- name="z3ext.profiler"
- for="zope.app.folder.interfaces.IRootFolder"
- template="view.pt"
- class=".view.Profiler"
+ <z3ext:configlet
title="Profiler"
- menu="zmi_actions"
+ name="system.profiler"
+ schema=".interfaces.IProfilerConfiglet"
+ class=".configlet.ProfilerConfiglet"
permission="zope.ManageServices" />
+ <!-- browser view -->
+ <z3ext:pagelet
+ name="index.html"
+ for=".interfaces.IProfilerConfiglet"
+ class="z3ext.controlpanel.browser.wizard.ConfigletEditWizard"
+ permission="z3ext.Configure" />
+
+ <z3ext:pagelet
+ name="portlet"
+ type="wizard.step"
+ title="Portlet"
+ label="Portlet Profiler"
+ for=".interfaces.IProfilerConfiglet
+ z3ext.controlpanel.browser.interfaces.IConfigletEditWizard"
+ template="edit.pt"
+ class=".portlet.PortletProfiler"
+ weight="200" />
+
</configure>
Added: z3ext.profiler/trunk/src/z3ext/profiler/edit.pt
===================================================================
--- z3ext.profiler/trunk/src/z3ext/profiler/edit.pt (rev 0)
+++ z3ext.profiler/trunk/src/z3ext/profiler/edit.pt 2009-07-13 09:35:33 UTC (rev 101843)
@@ -0,0 +1,80 @@
+<tal:block content="structure view/@@pagelet/form" />
+
+<div tal:condition="stats" tal:define="stats view/listStats">
+ <h2>Statistics</h2>
+ <br />
+
+ <div class="z-table-container">
+ <table class="z-table">
+ <tbody>
+ <tr class="even">
+ <th>Select request:</th>
+ <td><select name="stats" tal:define="default request/stats|nothing">
+ <option tal:repeat="stat stats"
+ tal:attributes="value stat/uri;
+ selected python:stat['uri'] == default"
+ tal:content="string:${stat/uri} (${stat/calls} calls)"></option>
+ </select>
+ </td>
+ </tr>
+ <tr class="odd">
+ <th>Number of records:</th>
+ <td><input type="text" name="limit:int"
+ tal:attributes="value request/limit|string:500" />
+ </td>
+ </tr>
+ <tr class="even">
+ <th>Mode:</th>
+ <td>
+ <select name="mode"
+ tal:define="default request/mode|string:stats">
+ <option tal:repeat="item python:('stats', 'callees', 'callers')"
+ tal:content="item"
+ tal:attributes="value item; selected python:item == default">
+ </option>
+ </select>
+ </td>
+ </tr>
+ <tr class="odd">
+ <th>Sort on:</th>
+ <td><select name="sorton"
+ tal:define="default request/sorton|string:time">
+ <option tal:repeat="item python:(
+ ('time', 'internal time'),
+ ('cumulative', 'cumulative time'),
+ ('calls', 'call count'),
+ ('pcalls', 'primitive call count'),
+ ('name', 'function name'),
+ ('file', 'file name'),
+ ('module', 'module name'),
+ ('line', 'line number'),
+ ('nfl', 'name/file/line'),
+ ('stdname', 'standard name'))"
+ tal:attributes="value python:item[0];
+ selected python:item[0] == default"
+ tal:content="python:item[1]"></option>
+ </select>
+ </td>
+ </tr>
+ <tr class="even">
+ <th>Stdname regexp:</th>
+ <td><input name="stdnameRe"
+ tal:attributes="value request/stdnameRe|nothing" /></td>
+ </tr>
+ <tr class="odd">
+ <th>Strip dirs:</th>
+ <td><input type="checkbox" name="stripdirs:bool"
+ tal:attributes="checked request/stripdirs|nothing" />
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+ <br />
+ <input class="z-form-button" type="submit" name="view_stats" value="Update"/>
+
+ <br />
+ <br />
+ <pre tal:content="view/viewStats"></pre>
+</div>
Added: z3ext.profiler/trunk/src/z3ext/profiler/interfaces.py
===================================================================
--- z3ext.profiler/trunk/src/z3ext/profiler/interfaces.py (rev 0)
+++ z3ext.profiler/trunk/src/z3ext/profiler/interfaces.py 2009-07-13 09:35:33 UTC (rev 101843)
@@ -0,0 +1,37 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+
+$Id: 2007-12-12 12:27:02Z fafhrd $
+"""
+from zope import interface, schema
+from z3ext.widget.list import SimpleList
+
+
+class IPortletProfiler(interface.Interface):
+ """ portlet profiler """
+
+ pnumber = schema.Int(
+ title = u'Number of calls',
+ default = 1,
+ required = True)
+
+ portlets = SimpleList(
+ title = u'Portlet ids',
+ default = [],
+ required = True)
+
+
+class IProfilerConfiglet(IPortletProfiler):
+ """ profiler """
Added: z3ext.profiler/trunk/src/z3ext/profiler/pagelet.py
===================================================================
--- z3ext.profiler/trunk/src/z3ext/profiler/pagelet.py (rev 0)
+++ z3ext.profiler/trunk/src/z3ext/profiler/pagelet.py 2009-07-13 09:35:33 UTC (rev 101843)
@@ -0,0 +1,19 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+
+$Id: 2007-12-12 12:27:02Z fafhrd $
+"""
+
+pageletNames = []
Added: z3ext.profiler/trunk/src/z3ext/profiler/portlet.py
===================================================================
--- z3ext.profiler/trunk/src/z3ext/profiler/portlet.py (rev 0)
+++ z3ext.profiler/trunk/src/z3ext/profiler/portlet.py 2009-07-13 09:35:33 UTC (rev 101843)
@@ -0,0 +1,108 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+
+$Id: 2007-12-12 12:27:02Z fafhrd $
+"""
+import time, profile
+from zope.component import queryMultiAdapter
+from z3ext.layoutform.interfaces import ISaveAction
+from z3ext.layoutform import button, Fields, PageletEditForm
+from z3ext.wizard.step import WizardStepForm
+from z3ext.portlet.manager import PortletManagerBase
+from z3ext.portlet.interfaces import IPortletManagerView
+from z3ext.statusmessage.interfaces import IStatusMessage
+from z3ext.cache import configlet as cacheconfiglet
+
+from DMstats import Stats
+from stats import ProfilerStatistics
+from interfaces import IPortletProfiler
+
+
+class PortletProfiler(WizardStepForm, PageletEditForm, ProfilerStatistics):
+
+ fields = Fields(IPortletProfiler)
+
+ buttons = PageletEditForm.buttons.copy()
+ handlers = PageletEditForm.handlers.copy()
+
+ def getStats(self):
+ global _stats
+ return _stats
+
+ @button.buttonAndHandler(u'Run Profiler')
+ def handleProfiler(self, action):
+ configlet = self.getContent()
+
+ installProfiler(configlet.pnumber, configlet.portlets)
+ IStatusMessage(self.request).add(u'Profiler has started.')
+
+
+_calls = 1
+_stats = {}
+_portlets = []
+
+originalMethod = PortletManagerBase.render
+
+
+def renderPortletManager(self):
+ if not self.portlets or not self.isAvailable():
+ return u''
+
+ view = queryMultiAdapter((self, self.request), IPortletManagerView)
+ if view is not None:
+ return view.updateAndRender()
+
+ portlets = []
+
+ for portlet in self.portlets:
+ if portlet.__name__ in _portlets:
+ uri = 'portlet: %s'%portlet.__name__
+ prof = profile.Profile(time.time)
+
+ cache = cacheconfiglet.cache
+ cacheconfiglet.cache = None
+
+ response = prof.runcall(portlet.updateAndRender)
+
+ cacheconfiglet.cache = cache
+
+ if _stats.has_key(uri):
+ _stats[uri][0].add(prof)
+ _stats[uri][1] = _stats[uri][1] + 1
+ else:
+ _stats[uri] = ([Stats(prof), 1])
+
+ global _calls
+ if _calls > 0:
+ _calls = _calls - 1
+
+ if _calls <= 0:
+ PortletManagerBase.render = originalMethod
+
+ portlets.append(response)
+ else:
+ portlets.append(portlet.updateAndRender())
+
+ return u'\n'.join(portlets)
+
+
+def installProfiler(calls, portlets):
+ global _calls, _stats, _portlets
+
+ _calls = calls
+ _stats = {}
+ _portlets = tuple(portlets)
+
+ PortletManagerBase.render = renderPortletManager
Added: z3ext.profiler/trunk/src/z3ext/profiler/stats.py
===================================================================
--- z3ext.profiler/trunk/src/z3ext/profiler/stats.py (rev 0)
+++ z3ext.profiler/trunk/src/z3ext/profiler/stats.py 2009-07-13 09:35:33 UTC (rev 101843)
@@ -0,0 +1,76 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+
+$Id: 2007-12-12 12:27:02Z fafhrd $
+"""
+from cStringIO import StringIO
+
+
+class ProfilerStatistics(object):
+
+ def getStats(self):
+ raise NotImplemented()
+
+ def listStats(self):
+ stats = []
+ for uri, info in self.getStats().items():
+ stats.append({'uri': uri, 'calls': info[1]})
+
+ return stats
+
+ def viewStats(self):
+ stats = self.getStats()
+ request = self.request
+
+ if not stats:
+ return u''
+
+ uri = request.get('stats', None)
+
+ info = stats.get(uri)
+ if not info:
+ info = stats.items()[0][1]
+
+ stats = info[0]
+
+ output = StringIO()
+
+ stripdirs = request.get('stripdirs', False)
+ if stripdirs:
+ stats.strip_dirs()
+
+ sorton = request.get('sorton', 'time')
+ stats.sort_stats(sorton)
+
+ mode = request.get('mode', 'stats')
+ stdnameRe = request.get('stdnameRe', '')
+ limit = int(request.get('limit', 500))
+
+ if stdnameRe:
+ stats.setOutputFile(output)
+ getattr(stats, 'show%s' % mode.capitalize())(str(stdnameRe), limit)
+ res = output.getvalue()
+ if not res:
+ res = 'No matching functions'
+ return res
+ else:
+ stats.stream = output
+
+ try:
+ getattr(stats, 'print_%s'%mode)(limit)
+ finally:
+ pass
+
+ return output.getvalue()
More information about the Checkins
mailing list