Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion psdash/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,16 @@ def get_process_list(self):
return process_list

def get_process(self, pid):
p = psutil.Process(pid)
p = None
if pid in psutil._pmap:
proc = psutil._pmap[pid]
if proc.is_running():
# use is_running() to check whether PID has been reused by
# another process in which case yield a new Process instance
p = proc
if p is None:
p = psutil.Process(pid)

mem = p.memory_info_ex()
cpu_times = p.cpu_times()
return {
Expand Down
66 changes: 48 additions & 18 deletions psdash/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,28 @@
import psutil
import socket
from datetime import datetime, timedelta
import time
import uuid
import locale
from flask import render_template, request, session, jsonify, Response, Blueprint, current_app, g
from flask import render_template as flask_render_template, request, session, jsonify, Response, Blueprint, current_app, g
from werkzeug.local import LocalProxy
from psdash.helpers import socket_families, socket_types

logger = logging.getLogger('psdash.web')
webapp = Blueprint('psdash', __name__, static_folder='static')


def render_template(template_name_or_list, **context):
if request.args.get('json', None) is not None:
for k in ("page", "is_xhr"):
if k in context:
del context[k]
context["timestamp"] = time.time()
return jsonify(context)

return flask_render_template(template_name_or_list, **context)


def get_current_node():
return current_app.psdash.get_node(g.node)

Expand Down Expand Up @@ -143,43 +155,60 @@ def processes(sort='pid', order='asc'):
@webapp.route('/process/<int:pid>', defaults={'section': 'overview'})
@webapp.route('/process/<int:pid>/<string:section>')
def process(pid, section):
valid_sections = [
'overview',
'threads',
'files',
'connections',
'memory',
'environment',
'children',
'limits'
]
OVERVIEW_SECTION = 0x01
THREADS_SECTION = 0x02
FILES_SECTION = 0x04
CONNECTIONS_SECTION = 0x08
MEMORY_SECTION = 0x10
ENVIRONMENT_SECTION = 0x20
CHILDREN_SECTION = 0x40
LIMITS_SECTION = 0x80
ALL_SECTION = (OVERVIEW_SECTION | THREADS_SECTION | FILES_SECTION |
CONNECTIONS_SECTION | MEMORY_SECTION | ENVIRONMENT_SECTION |
CHILDREN_SECTION | LIMITS_SECTION)
valid_sections = {
'overview': OVERVIEW_SECTION,
'threads': THREADS_SECTION,
'files': FILES_SECTION,
'connections': CONNECTIONS_SECTION,
'memory': MEMORY_SECTION,
'environment': ENVIRONMENT_SECTION,
'children': CHILDREN_SECTION,
'limits': LIMITS_SECTION,
'all': ALL_SECTION,
}

if section not in valid_sections:
errmsg = 'Invalid subsection when trying to view process %d' % pid
return render_template('error.html', error=errmsg), 404

section_flag = valid_sections[section]
context = {
'process': current_service.get_process(pid),
'section': section,
'page': 'processes',
'is_xhr': request.is_xhr
}

if section == 'environment':
if section_flag & ENVIRONMENT_SECTION == ENVIRONMENT_SECTION:
context['process_environ'] = current_service.get_process_environment(pid)
elif section == 'threads':
if section_flag & THREADS_SECTION == THREADS_SECTION:
context['threads'] = current_service.get_process_threads(pid)
elif section == 'files':
if section_flag & FILES_SECTION == FILES_SECTION:
context['files'] = current_service.get_process_open_files(pid)
elif section == 'connections':
if section_flag & CONNECTIONS_SECTION == CONNECTIONS_SECTION:
context['connections'] = current_service.get_process_connections(pid)
elif section == 'memory':
if section_flag & MEMORY_SECTION == MEMORY_SECTION:
context['memory_maps'] = current_service.get_process_memory_maps(pid)
elif section == 'children':
if section_flag & CHILDREN_SECTION == CHILDREN_SECTION:
context['children'] = current_service.get_process_children(pid)
elif section == 'limits':
if section_flag & LIMITS_SECTION == LIMITS_SECTION:
context['limits'] = current_service.get_process_limits(pid)

if section_flag == ALL_SECTION:
# Only return the JSON output for section=all
return jsonify(context)

return render_template(
'process/%s.html' % section,
**context
Expand Down Expand Up @@ -240,6 +269,7 @@ def view_disks():
disks = current_service.get_disks(all_partitions=True)
io_counters = current_service.get_disks_counters().items()
io_counters.sort(key=lambda x: x[1]['read_count'], reverse=True)

return render_template(
'disks.html',
page='disks',
Expand Down