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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
*.py[co]
cli_log.txt
.project
.pydevproject
1 change: 1 addition & 0 deletions README.textile
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ This project is licensed under the Apache License Version 2.0
h2. Requirements

* Django 1.0+
* zkpython 3.3.1+

h2. Usage

Expand Down
12 changes: 8 additions & 4 deletions css/blueprint/screen.css
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ a img {border:none;}

/* typography.css */
html {font-size:100.01%;}
body {font-size:75%;color:#222;background:#fff;font-family:"Helvetica Neue", Arial, Helvetica, sans-serif;}
body {font-size:75%;color:#222;background:#fff;font-family:"Helvetica Neue", Arial, Helvetica, sans-serif;padding:8px;}
h1, h2, h3, h4, h5, h6 {font-weight:normal;color:#111;}
h1 {font-size:3em;line-height:1;margin-bottom:0.5em;}
h2 {font-size:2em;margin-bottom:0.75em;}
h1 {font-size:3em;line-height:1;margin-bottom:0.5em;border-bottom:1px #ddd solid;}
h2 {font-size:2em;margin-bottom:0.75em;border-bottom:1px #ddd solid;}
h3 {font-size:1.5em;line-height:1;margin-bottom:1em;}
h4 {font-size:1.2em;line-height:1.25;margin-bottom:1.25em;}
h5 {font-size:1em;font-weight:bold;margin-bottom:1.5em;}
Expand Down Expand Up @@ -254,4 +254,8 @@ hr {background:#ddd;color:#ddd;clear:both;float:none;width:100%;height:.1em;marg
hr.space {background:#fff;color:#fff;visibility:hidden;}
.clearfix:after, .container:after {content:"\0020";display:block;height:0;clear:both;visibility:hidden;overflow:hidden;}
.clearfix, .container {display:block;}
.clear {clear:both;}
.clear {clear:both;}

div.section{
padding:8px 0px;
}
4 changes: 4 additions & 0 deletions zkadmin/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@

class Session(object):
def __init__(self, session):
#TODO: Support URLs, Not just IPs
m = re.search('/(\d+\.\d+\.\d+\.\d+):(\d+)\[(\d+)\]\((.*)\)', session)
if not m:
m = re.search('/(0:0:0:0:0:0:0:1):(\d+)\[(\d+)\]\((.*)\)', session)
self.host = m.group(1)
self.port = m.group(2)
self.interest_ops = m.group(3)
Expand All @@ -33,6 +36,7 @@ def __init__(self, server):
line = sio.readline()
m = re.search('.*: (\d+\.\d+\.\d+)-.*', line)
self.version = m.group(1)
#Skip the clients line
sio.readline()
self.sessions = []
for line in sio:
Expand Down
145 changes: 89 additions & 56 deletions zkadmin/templates/zkadmin/detail.html
Original file line number Diff line number Diff line change
@@ -1,60 +1,93 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15">
<link rel="stylesheet" href="/css/blueprint/screen.css" type="text/css" media="screen, projection">
<link rel="stylesheet" href="/css/blueprint/print.css" type="text/css" media="print">
<!--[if lt IE 8]><link rel="stylesheet" href="/css/blueprint/ie.css" type="text/css" media="screen, projection"><![endif]-->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15">
<link rel="stylesheet" href="/css/blueprint/screen.css" type="text/css" media="screen, projection">
<link rel="stylesheet" href="/css/blueprint/print.css" type="text/css" media="print">
<!--[if lt IE 8]><link rel="stylesheet" href="/css/blueprint/ie.css" type="text/css" media="screen, projection"><![endif]-->

<link type="text/css" rel="stylesheet" href="/css/zookeeper_dashboard.css" />
<title>ZooKeeper Server {{server_data.id}}</title>
</head>
<link type="text/css" rel="stylesheet" href="/css/zookeeper_dashboard.css" />
<title>ZooKeeper Server {{server_data.id}}</title>
</head>
<body>
<div class="container">
<a href="/"><h1>ZooKeeper Dashboard</h1></a>
<div class="span-24 last section">
<table class="server_summary">
<tr><th>Server ID</th><td>{{server_data.id}}</td></tr>
<tr><th>Server Address</th><td>{{server_data.host}}:{{server_data.port}}</td></tr>
<tr><th>Server Mode</th><td>{{server_data.mode|capfirst}}</td></tr>
</table>
</div>

<div class="span-24 last section">
<h2>Summary</h2>

<table class="server_summary">
<tr><th>Host</th><td>{{server_data.host}}</td></tr>
<tr><th>Client Port</th><td>{{server_data.port}}</td></tr>
<tr><th>Mode</th><td>{{server_data.mode|capfirst}}</td></tr>
<tr><th>Zxid</th><td>{{server_data.zxid}}</td></tr>
<tr><th>Node Count</th><td>{{server_data.node_count}}</td></tr>
<tr><th>Connection Count</th><td>{{server_data.sessions|length}}</td></tr>
<tr><th>Received</th><td>{{server_data.received}}</td></tr>
<tr><th>Sent</th><td>{{server_data.sent}}</td></tr>
<tr><th>Outstanding</th><td>{{server_data.outstanding}}</td></tr>
<tr><th>Max Latency</th><td>{{server_data.max_latency}}</td></tr>
<tr><th>Avg Latency</th><td>{{server_data.avg_latency}}</td></tr>
<tr><th>Min Latency</th><td>{{server_data.min_latency}}</td></tr>
</table>
</div>

<div class="span-24 last section">
<h2>Connections (Clients)</h2>

<body>
<div class="container">
<h1>ZooKeeper Server {{server_data.host}}:{{server_data.port}}</h1>
<hr/>
<div class="span-24 last">
<h2>Summary</h2>

<table class="server_summary">
<tr><td>Host</td><td>{{server_data.host}}</td></tr>
<tr><td>Client port</td><td>{{server_data.port}}</td></tr>
<tr><td>Mode</td><td>{{server_data.mode|capfirst}}</td></tr>
<tr><td>Zxid</td><td>{{server_data.zxid}}</td></tr>
<tr><td>Node count</td><td>{{server_data.node_count}}</td></tr>
<tr><td>Connection count</td><td>{{server_data.sessions|length}}</td></tr>
<tr><td>Received</td><td>{{server_data.received}}</td></tr>
<tr><td>Sent</td><td>{{server_data.sent}}</td></tr>
<tr><td>Outstanding</td><td>{{server_data.outstanding}}</td></tr>
<tr><td>Max Latency</td><td>{{server_data.max_latency}}</td></tr>
<tr><td>Avg Latency</td><td>{{server_data.avg_latency}}</td></tr>
<tr><td>Min Latency</td><td>{{server_data.min_latency}}</td></tr>
</table>
</div>
<hr/>
<div class="span-24 last">
<h2>Connections (clients)</h2>

<table class="conn_list">
<tr><th>host</th><th>port</th><th>interest ops</th><th>queued#</th><th>recved#</th><th>sent#</th></tr>
{% for s in server_data.sessions %}
<tr class="{% cycle 'oddrow' 'evenrow' %}"><td>{{s.host}}</td><td>{{s.port}}</td><td>{{s.interest_ops}}</td><td>{{s.queued}}</td><td>{{s.recved}}</td><td>{{s.sent}}</td></tr>
{% endfor %}
</table>
</div>
<hr/>
<div class="span-24 last">
<h2>Environment</h2>

<table class="envi_list">
<tr><th>Attribute</th><th>Value</th></tr>
{% for e in server_data.envi %}
<tr class="{% cycle 'oddrow' 'evenrow' %}"><td>{{e.0}}</td><td>{{e.1}}</td></tr>
{% endfor %}
</table>
</div>
<hr/>
</div>

</body> </html>
<table class="conn_list">
<thead>
<tr>
<th>Host</th>
<th>Port</th>
<th>Interest Ops</th>
<th>Queued #</th>
<th>Recved #</th>
<th>Sent #</th>
</tr>
</thead>
<tbody>
{% for s in server_data.sessions %}
<tr class="{% cycle 'oddrow' 'evenrow' %}">
<td>{{s.host}}</td>
<td>{{s.port}}</td>
<td>{{s.interest_ops}}</td>
<td>{{s.queued}}</td>
<td>{{s.recved}}</td>
<td>{{s.sent}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>

<div class="span-24 last section">
<h2>Environment</h2>

<table class="envi_list">
<thead>
<tr>
<th>Attribute</th>
<th>Value</th>
</tr>
</thead>
<tbody>
{% for e in server_data.envi %}
<tr class="{% cycle 'oddrow' 'evenrow' %}">
<td>{{e.0}}</td>
<td>{{e.1}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</body>
</html>
144 changes: 95 additions & 49 deletions zkadmin/templates/zkadmin/index.html
Original file line number Diff line number Diff line change
@@ -1,55 +1,101 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15">
<link rel="stylesheet" href="/css/blueprint/screen.css" type="text/css" media="screen, projection">
<link rel="stylesheet" href="/css/blueprint/print.css" type="text/css" media="print">
<!--[if lt IE 8]><link rel="stylesheet" href="/css/blueprint/ie.css" type="text/css" media="screen, projection"><![endif]-->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15">
<link rel="stylesheet" href="/css/blueprint/screen.css" type="text/css" media="screen, projection">
<link rel="stylesheet" href="/css/blueprint/print.css" type="text/css" media="print">
<!--[if lt IE 8]><link rel="stylesheet" href="/css/blueprint/ie.css" type="text/css" media="screen, projection"><![endif]-->

<link type="text/css" rel="stylesheet" href="/css/zookeeper_dashboard.css" />
<title>ZooKeeper Dashboard</title>
</head>
<link type="text/css" rel="stylesheet" href="/css/zookeeper_dashboard.css" />
<title>ZooKeeper Dashboard</title>
</head>
<body>
<div class="container">
<a href="/"><h1>ZooKeeper Dashboard</h1></a>

<div class="span-24 last section">
<h2>Cluster Information</h2>

<table>
<thead>
<tr>
<th>Server</th>
<th>Mode</th>
<th>#Conn</th>
<th>Version</th>
</tr>
</thead>
<tbody>
{% for sd in server_data %}
<tr class="{% cycle 'oddrow' 'evenrow' %}">
<td><a href="/cluster/server/{{sd.id}}">{{ sd.host }}:{{ sd.port }}</a> </td>
<td> {% ifequal sd.mode "leader" %}<b>{% endifequal %} {{sd.mode|capfirst}} {% ifequal sd.mode "leader" %}</b>{% endifequal %} </td>
<td> {{ sd.sessions|length }} </td>
<td> {{ sd.version }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>

<body>
<div class="container">
<h1>ZooKeeper Dashboard</h1>
<hr/>
<div class="span-24 last">
<h2>Cluster Information</h2>
<div class="span-24 last section">
<h2>ZNode Tree</h2>

<table>
<tr><th>server</th><th>mode</th><th>#conn</th><th>version</th></tr>
{% for sd in server_data %}
<tr class="{% cycle 'oddrow' 'evenrow' %}"><td><a href="cluster/server/{{sd.id}}">{{ sd.host }}:{{ sd.port }}</a> </td><td> {% ifequal sd.mode "leader" %}<b>{% endifequal %} {{sd.mode|capfirst}} {% ifequal sd.mode "leader" %}</b>{% endifequal %} </td><td> {{ sd.sessions|length }} </td><td> {{ sd.version }}</td></tr>
{% endfor %}
</table>
<p>
</div>
<table>
<thead>
<tr>
<th>ZNode</th>
<th>Children</th>
<th>Size</th>
<th>Created</th>
<th>Modified</th>
<th>--</th>
</tr>
</thead>
<tbody>
<tr class="evenrow">
<td><a href="/tree">/</a></td>
<td>{{rootNode.children|length}}</td>
<td>{{rootNode.stat.dataLength}}</td>
<td>{{rootNode.stat.ctime|date:"Y-m-d H:i"}}</td>
<td>{{rootNode.stat.ctime|date:"Y-m-d H:i"}}</td>
<td>&nbsp;</td>
</tr>
{% for child in children %}
<tr class="{% cycle 'oddrow' 'evenrow' %}">
<td>&nbsp;&nbsp;&nbsp;&nbsp;<a href="/tree{{child.path|urlencode}}">{{child.path}}</a></td>
<td>{{child.children|length}}</td>
<td>{{child.stat.dataLength}}</td>
<td>{{child.stat.ctime|date:"Y-m-d H:i"}}</td>
<td>{{child.stat.ctime|date:"Y-m-d H:i"}}</td>
<td>
{% if child.path != "/zookeeper" and not isZKPath %}
<a href="/tree/delete?path={{child.path|urlencode}}" onclick="return confirm('Are you sure you want to delete this?');">Delete</a>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>

<div class="span-24 last section">
<h2>Quota Definition</h2>
{% if quotaNode.data %}
<pre>{{quotaNode.data}}</pre>
{% else %}
<p>No Quota Defined</p>
{% endif %}

<a href="/tree/zookeeper/quota">More Information on the current quota configuration.</a>
</div>

<hr/>

<div class="span-24 last">
<h2>ZNode Tree</h2>

<a href="/tree">Root ZNode of the cluster</a>
<p>
</div>
<hr/>
<div class="span-24 last">
<h2>Quota Definition</h2>

Information on the current quota configuration

<a href="/tree/zookeeper/quota">Quota</a>
<p>
</div>
<hr/>
<div class="span-24 last small quiet">
<address>
<a href="http://github.com/phunt/zookeeper_dashboard#readme">zookeeper_dashboard</a> was created by
<a href="http://twitter.com/phunt">Patrick Hunt</a> and is hosted at GitHub
</address>
</div>
</div>

</body></html>
<div class="span-24 last small quiet section">
<address>
<a href="http://github.com/phunt/zookeeper_dashboard#readme" target="_blank">zookeeper_dashboard</a> was created by
<a href="http://twitter.com/phunt" target="_blank">Patrick Hunt</a> and is hosted at GitHub
</address>
</div>
</div>
</body>
</html>
10 changes: 9 additions & 1 deletion zkadmin/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from django.conf import settings

from zookeeper_dashboard.zkadmin.models import ZKServer
from zookeeper_dashboard.zktree.models import ZNode

ZOOKEEPER_SERVERS = getattr(settings,'ZOOKEEPER_SERVERS').split(',')

Expand All @@ -11,10 +12,17 @@ def index(request):
zkserver = ZKServer(server)
zkserver.id = i
server_data.append(zkserver)

rootNode = ZNode()
children = rootNode.getExtendedChildren()
quotaNode = ZNode("/zookeeper/quota")

return render_to_response('zkadmin/index.html',
{'ZOOKEEPER_SERVERS':ZOOKEEPER_SERVERS,
'server_data':server_data})
'server_data':server_data,
'rootNode':rootNode,
'children':children,
'quotaNode':quotaNode})

def detail(request, server_id):
server_data = ZKServer(ZOOKEEPER_SERVERS[int(server_id)])
Expand Down
Loading