You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ac...@apache.org on 2015/03/06 23:39:57 UTC

svn commit: r1664741 - in /qpid/dispatch/trunk/python: qpid_dispatch/management/qdrouter.json qpid_dispatch_internal/management/agent.py

Author: aconway
Date: Fri Mar  6 22:39:57 2015
New Revision: 1664741

URL: http://svn.apache.org/r1664741
Log:
NO-JIRA: Enable python profiling in agent.

Modified:
    qpid/dispatch/trunk/python/qpid_dispatch/management/qdrouter.json
    qpid/dispatch/trunk/python/qpid_dispatch_internal/management/agent.py

Modified: qpid/dispatch/trunk/python/qpid_dispatch/management/qdrouter.json
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch/management/qdrouter.json?rev=1664741&r1=1664740&r2=1664741&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch/management/qdrouter.json (original)
+++ qpid/dispatch/trunk/python/qpid_dispatch/management/qdrouter.json Fri Mar  6 22:39:57 2015
@@ -377,7 +377,7 @@
             "description": "Qpid dispatch router extensions to the standard org.amqp.management interface.",
             "extends": "org.amqp.management",
             "singleton": true,
-            "operations": ["GET-SCHEMA", "GET-JSON-SCHEMA", "GET-LOG"],
+            "operations": ["GET-SCHEMA", "GET-JSON-SCHEMA", "GET-LOG", "PROFILE"],
             "operationDefs": {
                 "GET-SCHEMA": {
                     "description": "Get the qdrouterd schema for this router in AMQP map format",

Modified: qpid/dispatch/trunk/python/qpid_dispatch_internal/management/agent.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch_internal/management/agent.py?rev=1664741&r1=1664740&r2=1664741&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch_internal/management/agent.py (original)
+++ qpid/dispatch/trunk/python/qpid_dispatch_internal/management/agent.py Fri Mar  6 22:39:57 2015
@@ -65,10 +65,12 @@ Temporary solution is to lock the entire
 Better solution coming soon...
 """
 
-import traceback, json
+import traceback, json, pstats
 from itertools import ifilter, chain
 from traceback import format_exc
 from threading import Lock
+from cProfile import Profile
+from cStringIO import StringIO
 from ctypes import c_void_p, py_object, c_long
 from ..dispatch import IoAdapter, LogAdapter, LOG_INFO, LOG_DEBUG, LOG_ERROR
 from qpid_dispatch.management.error import ManagementError, OK, CREATED, NO_CONTENT, STATUS_TEXT, \
@@ -149,6 +151,7 @@ class EntityAdapter(SchemaEntity):
         super(EntityAdapter, self).__init__(entity_type, attributes or {}, validate=validate)
         # Direct __dict__ access to avoid validation as schema attributes
         self.__dict__['_agent'] = agent
+        self.__dict__['_log'] = agent.log
         self.__dict__['_qd'] = agent.qd
         self.__dict__['_dispatch'] = agent.dispatch
         self.__dict__['_implementations'] = []
@@ -515,6 +518,37 @@ class ManagementEntity(EntityAdapter):
         logs = self._qd.qd_log_recent_py(self._intprop(request, "limit") or -1)
         return (OK, logs)
 
+    def profile(self, request):
+        """Start/stop the python profiler, returns profile results"""
+        profile = self.__dict__.get("_profile")
+        if "start" in request.properties:
+            if not profile:
+                profile = self.__dict__["_profile"] = Profile()
+            profile.enable()
+            self._log(LOG_INFO, "Started python profiler")
+            return (OK, None)
+        if not profile:
+            raise BadRequestStatus("Profiler not started")
+        if "stop" in request.properties:
+            profile.create_stats()
+            self._log(LOG_INFO, "Stopped python profiler")
+            out = StringIO()
+            stats = pstats.Stats(profile, stream=out)
+            try:
+                stop = request.properties["stop"]
+                if stop == "kgrind": # Generate kcachegrind output using pyprof2calltree
+                    from pyprof2calltree import convert
+                    convert(stats, out)
+                elif stop == "visualize": # Start kcachegrind using pyprof2calltree
+                    from pyprof2calltree import visualize
+                    visualize(stats)
+                else:
+                    stats.print_stats() # Plain python profile stats
+                return (OK, out.getvalue())
+            finally:
+                out.close()
+        raise BadRequestStatus("Bad profile request %s" % (request))
+
 class Agent(object):
     """AMQP managment agent. Manages entities, directs requests to the correct entity."""
 



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org