Commit d3528e96 authored by Luke Macken's avatar Luke Macken

Use a WebKit widget to render our Info tab

parent 1d44ebdc
...@@ -23,13 +23,14 @@ ...@@ -23,13 +23,14 @@
import os import os
import sys import sys
import time import time
import socket
import psutil import psutil
import logging import logging
import keyword import keyword
import tokenize import tokenize
from meliae import loader from meliae import loader
from gi.repository import GLib, GObject, Pango, Gtk from gi.repository import GLib, GObject, Pango, Gtk, WebKit
import pyrasite import pyrasite
from pyrasite.utils import setup_logger, run from pyrasite.utils import setup_logger, run
...@@ -94,10 +95,16 @@ class PyrasiteWindow(Gtk.Window): ...@@ -94,10 +95,16 @@ class PyrasiteWindow(Gtk.Window):
main_vbox.pack_end(self.progress, False, False, 0) main_vbox.pack_end(self.progress, False, False, 0)
hbox.pack_start(main_vbox, True, True, 0) hbox.pack_start(main_vbox, True, True, 0)
(text_widget, info_buffer) = self.create_text(False) self.info_html = ''
notebook.append_page(text_widget, Gtk.Label.new_with_mnemonic('_Info')) self.info_view = WebKit.WebView()
self.info_buffer = info_buffer self.info_view.load_string(self.info_html, "text/html", "utf-8", '#')
self.info_buffer.create_tag('title', font = 'Sans 18')
info_window = Gtk.ScrolledWindow(hadjustment = None,
vadjustment = None)
info_window.set_policy(Gtk.PolicyType.AUTOMATIC,
Gtk.PolicyType.AUTOMATIC)
info_window.add(self.info_view)
notebook.append_page(info_window, Gtk.Label.new_with_mnemonic('_Info'))
(stacks_widget, source_buffer) = self.create_text(True) (stacks_widget, source_buffer) = self.create_text(True)
notebook.append_page(stacks_widget, Gtk.Label.new_with_mnemonic('_Stacks')) notebook.append_page(stacks_widget, Gtk.Label.new_with_mnemonic('_Stacks'))
...@@ -251,64 +258,105 @@ class PyrasiteWindow(Gtk.Window): ...@@ -251,64 +258,105 @@ class PyrasiteWindow(Gtk.Window):
log.debug("obj_row_activated_cb(%s, %s)" % (args, kw)) log.debug("obj_row_activated_cb(%s, %s)" % (args, kw))
def generate_description(self, proc, title): def generate_description(self, proc, title):
d = ''
p = psutil.Process(proc.pid) p = psutil.Process(proc.pid)
cputimes = p.get_cpu_times() cputimes = p.get_cpu_times()
d += '\nCPU usage: %0.2f%% (%s user, %s system)\n' % (
p.get_cpu_percent(interval=1.0),
cputimes.user, cputimes.system)
meminfo = p.get_memory_info() meminfo = p.get_memory_info()
d += 'Memory usage: %0.2f%% (%s RSS, %s VMS)\n\n' % ( io = p.get_io_counters()
p.get_memory_percent(),
meminfo.rss, meminfo.vms)
d += '[ Open Files ]'
for open_file in p.get_open_files():
d += '\n' + str(open_file)
d += '\n\n[ Connections ]'
for conn in p.get_connections():
d += '\n' + str(conn)
d += '\n\n[ Threads ]' self.info_html = """
for thread in p.get_threads(): <h2>%(title)s</h2>
d += '\n' + str(thread) <h3>Resource Usage</h3>
<ul>
<li><b>CPU:</b> %(cpu)0.2f%% (%(cpu_user)s user, %(cpu_sys)s system)</li>
<li><b>Memory:</b> %(mem)0.2f%% (%(mem_rss)s RSS, %(mem_vms)s VMS)</li>
<li><b>Read count:</b> %(read_count)s</li>
<li><b>Read bytes:</b> %(read_bytes)s</li>
<li><b>Write count:</b> %(write_count)s</li>
<li><b>Write bytes:</b> %(write_bytes)s</li>
</ul>
""" % dict(
title = proc.title,
cpu = p.get_cpu_percent(interval=1.0),
cpu_user = cputimes.user,
cpu_sys = cputimes.system,
mem = p.get_memory_percent(),
mem_rss = meminfo.rss,
mem_vms = meminfo.vms,
read_count = io.read_count,
read_bytes = io.read_bytes,
write_count = io.write_count,
write_bytes = io.write_bytes,
)
open_files = p.get_open_files()
if open_files:
self.info_html += """
<h3>Open Files</h3>
<table border="1">
<thead><tr><th>fd</th><th>Path</th></tr></thead>
%(open_files)s
</table>
""" % dict(
open_files = ''.join(['<tr><td>%s</td><td>%s</td></tr>' %
(f.fd, f.path) for f in open_files]))
conns = p.get_connections()
if conns:
self.info_html += """
<h3>Connections</h3>
<table border="1">
<thead><tr><th>fd</th><th>Family</th><th>Type</th>
<th>Local</th><th>Remote</th><th>Status</th></tr></thead>
"""
families = dict([(getattr(socket, k), k) for k in dir(socket)
if k.startswith('AF_')])
types = dict([(getattr(socket, k), k) for k in dir(socket)
if k.startswith('SOCK_')])
for c in conns:
self.info_html += """
<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td>
<td>%s</td></tr>
""" % (c.fd, families[c.family], types[c.type],
':'.join(map(str, c.local_address)),
':'.join(map(str, c.remote_address)),
c.status)
self.info_html += """
</table>
"""
io = p.get_io_counters() threads = p.get_threads()
d += '\n\n[ IO ]\nread count: %s\n' % io.read_count if threads:
d += 'read bytes: %s\n' % io.read_bytes self.info_html += """
d += 'write count: %s\n' % io.write_count <h3>Threads</h3>
d += 'write bytes: %s\n' % io.write_bytes <table border="1">
<thead><tr><th>ID</th><th>User Time</th><th>System Time</th>
d += '\n[ Details ]\n' </tr></thead>
d += 'status: %s\n' % p.status """
d += 'cwd: %s\n' % p.getcwd() for thread in threads:
d += 'cmdline: %s\n' % ' '.join(p.cmdline) self.info_html += """
d += 'terminal: %s\n' % p.terminal <tr><td>%s</td><td>%s</td><td>%s</td></tr>
d += 'created: %s\n' % time.ctime(p.create_time) """ % (thread.id, thread.user_time, thread.system_time)
d += 'username: %s\n' % p.username self.info_html += "</table>"
d += 'uid: %s\n' % p.uids.real
d += 'gid: %s\n' % p.gids.real self.info_html += """
d += 'nice: %s\n\n' % p.nice <h3>Details</h3>
<ul>
# output and style the title <li><b>status:</b> %s</li>
(start, end) = self.info_buffer.get_bounds() <li><b>cwd:</b> %s</li>
self.info_buffer.delete(start, end) <li><b>cmdline:</b> %s</li>
(start, end) = self.source_buffer.get_bounds() <li><b>terminal:</b> %s</li>
self.source_buffer.delete(start, end) <li><b>created:</b> %s</li>
<li><b>username:</b> %s</li>
start = self.info_buffer.get_iter_at_offset(0) <li><b>uid:</b> %s</li>
end = start.copy() <li><b>gid:</b> %s</li>
self.info_buffer.insert(end, title) <li><b>nice:</b> %s</li>
start = end.copy() </ul>
start.backward_chars(len(title)) """ % (p.status, p.getcwd(), ' '.join(p.cmdline),
self.info_buffer.apply_tag_by_name('title', start, end) p.terminal, time.ctime(p.create_time),
self.info_buffer.insert(end, '\n') p.username, p.uids.real, p.gids.real, p.nice)
# output the description self.info_view.load_string(self.info_html, "text/html", "utf-8", '#')
self.info_buffer.insert(end, d)
def update_progress(self, fraction, text=None): def update_progress(self, fraction, text=None):
if text: if text:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment