mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Add a memdump page to the admin controller, makes heapy output slightly
browsable and provides an entry point to heapy (via editing the template) while the server is running.
This commit is contained in:
@@ -35,6 +35,7 @@ class UniverseApplication( object ):
|
||||
self.job_queue = jobs.JobQueue( self, job_dispatcher )
|
||||
self.job_stop_queue = jobs.JobStopQueue( self, job_dispatcher )
|
||||
self.heartbeat = None
|
||||
self.memdump = None
|
||||
# Start the heartbeat process if configured and available
|
||||
if self.config.use_heartbeat:
|
||||
from galaxy.util import heartbeat
|
||||
|
||||
@@ -22,22 +22,29 @@ else:
|
||||
self.fname = fname
|
||||
signal.signal( signum, self.dump )
|
||||
self.heapy = guppy.hpy()
|
||||
self.heap = None
|
||||
def dump( self, signum, stack ):
|
||||
file = open( self.fname, "a" )
|
||||
print >> file, "Memdump for pid %d at %s" % ( os.getpid(), time.asctime() )
|
||||
print >> file
|
||||
try:
|
||||
h = self.heapy.heap()
|
||||
self.heap = self.heapy.heap()
|
||||
print >> file, "heap():"
|
||||
print >> file, h
|
||||
print >> file, self.heap
|
||||
print >> file, "\nbyrcs:"
|
||||
print >> file, h.byrcs
|
||||
print >> file, self.heap.byrcs
|
||||
print >> file, "\nbyrcs[0].byid:"
|
||||
print >> file, h.byrcs[0].byid
|
||||
print >> file, self.heap.byrcs[0].byid
|
||||
print >> file, "\nget_rp():"
|
||||
print >> file, h.get_rp()
|
||||
print >> file, self.heap.get_rp()
|
||||
self.heapy.setref()
|
||||
except AssertionError:
|
||||
pass
|
||||
print >> file, "\nEnd dump\n"
|
||||
file.close()
|
||||
def setref( self ):
|
||||
self.heapy.setref()
|
||||
def get( self, update=False ):
|
||||
if update:
|
||||
self.heap = self.heapy.heap()
|
||||
return self.heap
|
||||
|
||||
@@ -22,3 +22,42 @@ class Admin( BaseController ):
|
||||
else:
|
||||
msg = 'Invalid password'
|
||||
return msg
|
||||
@web.expose
|
||||
def memdump( self, trans, ids = 'None', sorts = 'None', pages = 'None', new_id = None, new_sort = None, **kwd ):
|
||||
if self.app.memdump is None:
|
||||
return trans.show_error_message( "Memdump is not enabled (set <code>use_memdump = True</code> in universe_wsgi.ini)" )
|
||||
heap = self.app.memdump.get()
|
||||
p = util.Params( kwd )
|
||||
msg = None
|
||||
if p.dump:
|
||||
heap = self.app.memdump.get( update = True )
|
||||
msg = "Heap dump complete"
|
||||
elif p.setref:
|
||||
self.app.memdump.setref()
|
||||
msg = "Reference point set (dump to see delta from this point)"
|
||||
ids = ids.split( ',' )
|
||||
sorts = sorts.split( ',' )
|
||||
if new_id is not None:
|
||||
ids.append( new_id )
|
||||
sorts.append( 'None' )
|
||||
elif new_sort is not None:
|
||||
sorts[-1] = new_sort
|
||||
breadcrumb = "<a href='%s' class='breadcrumb'>heap</a>" % web.url_for()
|
||||
# new lists so we can assemble breadcrumb links
|
||||
new_ids = []
|
||||
new_sorts = []
|
||||
for id, sort in zip( ids, sorts ):
|
||||
new_ids.append( id )
|
||||
if id != 'None':
|
||||
breadcrumb += "<a href='%s' class='breadcrumb'>[%s]</a>" % ( web.url_for( ids=','.join( new_ids ), sorts=','.join( new_sorts ) ), id )
|
||||
heap = heap[int(id)]
|
||||
new_sorts.append( sort )
|
||||
if sort != 'None':
|
||||
breadcrumb += "<a href='%s' class='breadcrumb'>.by('%s')</a>" % ( web.url_for( ids=','.join( new_ids ), sorts=','.join( new_sorts ) ), sort )
|
||||
heap = heap.by( sort )
|
||||
ids = ','.join( new_ids )
|
||||
sorts = ','.join( new_sorts )
|
||||
if p.theone:
|
||||
breadcrumb += ".theone"
|
||||
heap = heap.theone
|
||||
return trans.fill_template( '/admin/memdump.mako', heap = heap, ids = ids, sorts = sorts, breadcrumb = breadcrumb, msg = msg )
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
<%inherit file="/base.mako"/>
|
||||
|
||||
<%def name="title()">Memory Profiling</%def>
|
||||
<%
|
||||
import re
|
||||
from xml.sax.saxutils import escape, unescape
|
||||
%>
|
||||
|
||||
<style type="text/css">
|
||||
a.breadcrumb:link,
|
||||
a.breadcrumb:visited,
|
||||
a.breadcrumb:active {
|
||||
text-decoration: none;
|
||||
}
|
||||
a.breadcrumb:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
|
||||
<h2>Memory Profiling</h2>
|
||||
|
||||
<ul class="manage-table-actions">
|
||||
<li><a class="action-button" href="${h.url_for( controller='admin', action='memdump', dump=True )}">Dump memory (warning: hangs server!)</a></li>
|
||||
<li><a class="action-button" href="${h.url_for( controller='admin', action='memdump', setref=True )}">Set reference point</a></li>
|
||||
</ul>
|
||||
|
||||
<%def name="htmlize( heap )">
|
||||
<%
|
||||
s = escape( str( heap ) )
|
||||
new_s = ""
|
||||
id_re = re.compile('^(\s+)([0-9]+)')
|
||||
for line in s.split( '\n' ):
|
||||
try:
|
||||
id = id_re.search( line ).group( 2 )
|
||||
except:
|
||||
id = None
|
||||
new_s += re.sub( id_re, r'\1<a href="' + h.url_for( controller='admin', action='memdump', ids=ids, sorts=sorts, new_id=id ) + r'">\2</a>', line )
|
||||
if id and heap[int(id)].count == 1:
|
||||
new_s += " <a href='%s'>theone</a>\n" % h.url_for( ids=ids, sorts=sorts, new_id=id, theone=True )
|
||||
else:
|
||||
new_s += "\n"
|
||||
return new_s
|
||||
%>
|
||||
</%def>
|
||||
|
||||
%if msg:
|
||||
<div class="donemessage">${msg}</div>
|
||||
%endif
|
||||
|
||||
%if heap is None:
|
||||
No memory dump available. Click "Dump memory" to create one.
|
||||
%else:
|
||||
<pre>
|
||||
<br/>
|
||||
You are here: ${breadcrumb}<br/>
|
||||
%if breadcrumb.endswith( 'theone' ):
|
||||
${heap}
|
||||
%else:
|
||||
<nobr>
|
||||
Sort:
|
||||
<a href="${h.url_for( controller='admin', action='memdump', ids=ids, sorts=sorts, new_sort='Class')}">Class</a> |
|
||||
<a href="${h.url_for( controller='admin', action='memdump', ids=ids, sorts=sorts, new_sort='Clodo' )}">Clodo</a> |
|
||||
<a href="${h.url_for( controller='admin', action='memdump', ids=ids, sorts=sorts, new_sort='Id' )}">Id</a> |
|
||||
<a href="${h.url_for( controller='admin', action='memdump', ids=ids, sorts=sorts, new_sort='Idset' )}">Idset</a> |
|
||||
<a href="${h.url_for( controller='admin', action='memdump', ids=ids, sorts=sorts, new_sort='Module' )}">Module</a> |
|
||||
<a href="${h.url_for( controller='admin', action='memdump', ids=ids, sorts=sorts, new_sort='Unity' )}">Unity</a> |
|
||||
<a href="${h.url_for( controller='admin', action='memdump', ids=ids, sorts=sorts, new_sort='Rcs' )}">Rcs</a> |
|
||||
<a href="${h.url_for( controller='admin', action='memdump', ids=ids, sorts=sorts, new_sort='Size' )}">Size</a> |
|
||||
<a href="${h.url_for( controller='admin', action='memdump', ids=ids, sorts=sorts, new_sort='Type' )}">Type</a> |
|
||||
<a href="${h.url_for( controller='admin', action='memdump', ids=ids, sorts=sorts, new_sort='Via' )}">Via</a>
|
||||
</nobr>
|
||||
${htmlize( heap )}
|
||||
%endif
|
||||
</pre>
|
||||
%endif
|
||||
Reference in New Issue
Block a user