[Checkins] SVN: Sandbox/jens/zmi.core/trunk/src/zmi/core/browser/database/ Add chart functionality - no images required.
Charlie Clark
charlie at begeistert.org
Sun Dec 4 17:11:33 UTC 2011
Log message for revision 123569:
Add chart functionality - no images required.
Changed:
U Sandbox/jens/zmi.core/trunk/src/zmi/core/browser/database/activity.py
U Sandbox/jens/zmi.core/trunk/src/zmi/core/browser/database/templates/activity.pt
-=-
Modified: Sandbox/jens/zmi.core/trunk/src/zmi/core/browser/database/activity.py
===================================================================
--- Sandbox/jens/zmi.core/trunk/src/zmi/core/browser/database/activity.py 2011-12-03 23:56:02 UTC (rev 123568)
+++ Sandbox/jens/zmi.core/trunk/src/zmi/core/browser/database/activity.py 2011-12-04 17:11:33 UTC (rev 123569)
@@ -15,6 +15,9 @@
ZODB Activity
"""
+from Acquisition import aq_inner
+from DateTime import DateTime
+
class View(object):
# dummy variables for bootstrapping view
@@ -33,4 +36,111 @@
self.request = request
def __call__(self):
- return self.index()
\ No newline at end of file
+ return self.index()
+
+ @property
+ def _db(self):
+ """Return the database connection"""
+ return aq_inner(self.context)._p_jar.db()
+
+ def _getActivityMonitor(self):
+ if not hasattr(self._db, 'getActivityMonitor'):
+ return None
+ am = self._db.getActivityMonitor()
+ if am is None:
+ return None
+ return am
+
+ def getHistoryLength(self):
+ am = self._getActivityMonitor()
+ if am is None:
+ return 0
+ return am.getHistoryLength()
+
+ def getActivityChartData(self, segment_height=200, REQUEST=None):
+ """Returns information for generating an activity chart.
+ Default height is 200 pixels
+ """
+ am = self._getActivityMonitor()
+ if am is None:
+ return None
+
+ if REQUEST is not None:
+ start = float(REQUEST.get('chart_start', 0))
+ end = float(REQUEST.get('chart_end', 0))
+ divisions = int(REQUEST.get('chart_divisions', 10))
+ analysis = am.getActivityAnalysis(start, end, divisions)
+ else:
+ analysis = am.getActivityAnalysis()
+
+ total_load_count = 0
+ total_store_count = 0
+ total_connections = 0
+ limit = 0
+ divs = []
+ for div in analysis:
+ total_store_count = total_store_count + div['stores']
+ total_load_count = total_load_count + div['loads']
+ total_connections = total_connections + div['connections']
+ sum = div['stores'] + div['loads']
+ if sum > limit:
+ limit = sum
+
+ if analysis:
+ segment_time = analysis[0]['end'] - analysis[0]['start']
+ else:
+ segment_time = 0
+
+ for div in analysis:
+ stores = div['stores']
+ if stores > 0:
+ store_len = max(int(segment_height * stores / limit), 1)
+ else:
+ store_len = 0
+ loads = div['loads']
+ if loads > 0:
+ load_len = max(int(segment_height * loads / limit), 1)
+ else:
+ load_len = 0
+
+ t = div['end'] - analysis[-1]['end'] # Show negative numbers.
+ if segment_time >= 3600:
+ # Show hours.
+ time_offset = '%dh' % (t / 3600)
+ elif segment_time >= 60:
+ # Show minutes.
+ time_offset = '%dm' % (t / 60)
+ elif segment_time >= 1:
+ # Show seconds.
+ time_offset = '%ds' % t
+ else:
+ # Show fractions.
+ time_offset = '%.2fs' % t
+ divs.append({
+ 'store_len': store_len,
+ 'load_len': load_len,
+ 'trans_len': max(segment_height - store_len - load_len, 0),
+ 'store_count': div['stores'],
+ 'load_count': div['loads'],
+ 'connections': div['connections'],
+ 'start': div['start'],
+ 'end': div['end'],
+ 'time_offset': time_offset,
+ })
+
+ if analysis:
+ start_time = DateTime(divs[0]['start']).aCommonZ()
+ end_time = DateTime(divs[-1]['end']).aCommonZ()
+ else:
+ start_time = ''
+ end_time = ''
+
+ res = {'start_time': start_time,
+ 'end_time': end_time,
+ 'divs': divs,
+ 'total_store_count': total_store_count,
+ 'total_load_count': total_load_count,
+ 'total_connections': total_connections,
+ }
+ return res
+
Modified: Sandbox/jens/zmi.core/trunk/src/zmi/core/browser/database/templates/activity.pt
===================================================================
--- Sandbox/jens/zmi.core/trunk/src/zmi/core/browser/database/templates/activity.pt 2011-12-03 23:56:02 UTC (rev 123568)
+++ Sandbox/jens/zmi.core/trunk/src/zmi/core/browser/database/templates/activity.pt 2011-12-04 17:11:33 UTC (rev 123569)
@@ -1,6 +1,59 @@
<html>
+<head>
<title>Recent Database Activity</title>
+<style>
+div#chart table {
+border: 1px solid gray;
+ font-size:75%;
+ }
+
+ tr td a {
+ text-decoration: none;
+ }
+
+ .red,
+ tr.red a {
+ color: #F00;
+ }
+
+ .blue,
+ tr.blue a{
+ color: #000080;
+ }
+
+ td {
+ width: 3.5em;
+ text-align: right;
+ }
+
+ td.title {
+ text-align: left;
+ width: auto;
+ }
+
+ td.total,
+ td.title {
+ font-weight: bold;
+ }
+
+
+ span.bar {
+ display:block;
+ float: left;
+ width: 3em;
+ }
+
+ span.blue {
+ background-color: #000080;
+ }
+
+ span.red {
+ background-color: #F00;
+ }
+
+</style>
+</head>
<body>
<nav>
@@ -14,12 +67,10 @@
<h1>Recent Database Activity</h1>
-<!--<dtml-with expr="getActivityChartData(200, REQUEST)" mapping>-->
-
<h2>Keep History (seconds)</h2>
<form method="POST" action="./">
- <input type="text" name="length" value="&dtml-getHistoryLength;"
+ <input type="text" name="length"
tal:attributes="value view/getHistoryLength" />
<input type="submit" name="set_history" value="Save changes" />
</form>
@@ -32,67 +83,62 @@
<input type="submit" name="current_chart" value="Show current chart" />
</form>
-<!--<dtml-with expr="getActivityChartData(200, REQUEST)" mapping>-->
-<div define="mapping python:view.getActivityChartData(200, REQUEST)">
+<div id="chart" tal:define="activity view/getActivityChartData">
-<tal:loop repeat="mapping view/divs">
- <a href=""
- tal:attributes="href python:request['URL'] + ('?chart_start=%s&chart_end=%s'
- % (start, end))">
- <tal:if tal:condition="view/trans_len">
- <img src="transparent_bar" width="32" height="" border="0"
- tal:attributes="height view/trans_len"/><br />
- </tal:if>
- <tal:if tal:condition="view/store_len">
- <img src="store_bar" width="32" height="" border="0"
- tal:attributes="height view/store_len"/><br />
- </tal:if>
- <tal:if tal:condition="view/load_len">
- <img src="store_bar" width="32" height="" border="0"
- tal:attributes="height view/load_len"/><br />
- </tal:if>
-</a>
-</tal:loop>
+<table id="chart">
- <dl>
- <dt color="red">Object stores</dt>
- <dd tal:repeat="mapping view/divs">
- <a href="" color="red" tal:content="store_count"
- tal:attributes="href python: request['URL'] + ('?chart_start=%s&chart_end=%s' % (mapping['start'], mapping['end']))"></a>
-</dd>
- <dt>Total:</dt>
- <dd color="red" tal:content="view/total_store_count">total_store_count</dd>
- </dl>
+ <tr>
+ <td></td>
+ <td tal:repeat="result activity/divs">
+ <a href=""
+ tal:attributes="href python: request['URL'] + ('?chart_start=%s&chart_end=%s' % (result['start'], result['end']))">
+ <span class="bar" tal:attributes="style string:height: ${result/trans_len}"></span>
+ <span class="bar red" tal:attributes="style string:height: ${result/store_len}"></span>
+ <span class="bar blue" tal:attributes="style string:height: ${result/load_len}"></span>
+ </a>
+ </td>
+</tr>
- <dl>
- <dt color="red">Object loads</dt>
- <dd tal:repeat="mapping view/divs">
- <a href="" color="blue" tal:content="load_count"
- tal:attributes="href python: request['URL'] + '?chart_start=%s&chart_end=%s' % (mapping['start'], mapping['end'])"></a>
-</dd>
- <dt>Total:</dt>
- <dd color="blue" tal:content="view/total_store_count">total_load_count</dd>
- </dl>
+ <tr>
+ <td colspan="11"></td>
+ <td class="total">Total</td>
+ </tr>
+ <tr class="red">
+ <td class="title">Object stores</td>
+ <td tal:repeat="result activity/divs">
+ <a href="" tal:content="result/store_count"
+ tal:attributes="href python: request['URL'] + ('?chart_start=%s&chart_end=%s' % (result['start'], result['end']))"></a>
+ </td>
+ <td class="total" tal:content="activity/total_store_count">total_store_count</td>
+</tr>
- <dl>
- <dt>Connections</dt>
- <dd tal:repeat="mapping view/divs">
- <a href="" tal:content="connections"
- tal:attributes="href python: request['URL']+ '?chart_start=%s&chart_end=%s' % (mapping['start'], mapping['end'])"></a>
-</dd>
- <dt>Total:</dt>
- <dd tal:content="view/connections">connections</dd>
- </dl>
+ <tr class="blue">
+ <td class="title">Object loads</td>
+ <td tal:repeat="result activity/divs">
+ <a href="" tal:content="result/load_count"
+ tal:attributes="href python: request['URL'] + ('?chart_start=%s&chart_end=%s' % (result['start'], result['end']))"></a>
+ </td>
+ <td class="total" tal:content="activity/total_load_count">total_load_count</td>
+</tr>
- <dl>
- <dt></dt>
- <dd tal:repeat="mapping view/divs">
- <a href="" tal:content="time_offset"
- tal:attributes="href python: request['URL'] + '?chart_start=%s&chart_end=%s' % (mapping['start'], mapping['end'])"></a>
-</dd>
- <dt>Total:</dt>
- </dl>
+ <tr>
+ <td class="title">Connections</td>
+ <td tal:repeat="result activity/divs">
+ <a href="" tal:content="result/connections"
+ tal:attributes="href python: request['URL'] + ('?chart_start=%s&chart_end=%s' % (result['start'], result['end']))"></a>
+ </td>
+ <td class="total" tal:content="activity/total_connections">total_connections</td>
+</tr>
+ <tr>
+ <td>Time offset</td>
+ <td tal:repeat="result activity/divs">
+ <a href="" tal:content="result/time_offset"
+ tal:attributes="href python: request['URL'] + ('?chart_start=%s&chart_end=%s' % (result['start'], result['end']))"></a>
+ </td>
+</tr>
+</table>
+
</div>
</body>
More information about the checkins
mailing list