Merge branch 'sajith-3254.01-status-nevow-to-twisted-web'

This commit is contained in:
Sajith Sasidharan 2020-04-21 12:49:42 -04:00
commit bd8bf0f91c
3 changed files with 94 additions and 45 deletions

0
newsfragments/3292.minor Normal file
View File

View File

@ -1,27 +1,27 @@
<html xmlns:n="http://nevow.com/ns/nevow/0.1">
<html xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1">
<head>
<title>Tahoe-LAFS - Operational Statistics</title>
<link href="/tahoe.css" rel="stylesheet" type="text/css"/>
<link href="/icon.png" rel="shortcut icon" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body n:data="get_stats">
<body>
<h1>Operational Statistics</h1>
<h2>General</h2>
<ul>
<li>Load Average: <span n:render="load_average" /></li>
<li>Peak Load: <span n:render="peak_load" /></li>
<li>Files Uploaded (immutable): <span n:render="uploads" /></li>
<li>Files Downloaded (immutable): <span n:render="downloads" /></li>
<li>Files Published (mutable): <span n:render="publishes" /></li>
<li>Files Retrieved (mutable): <span n:render="retrieves" /></li>
</ul>
<ul>
<li>Load Average: <t:transparent t:render="load_average" /></li>
<li>Peak Load: <t:transparent t:render="peak_load" /></li>
<li>Files Uploaded (immutable): <t:transparent t:render="uploads" /></li>
<li>Files Downloaded (immutable): <t:transparent t:render="downloads" /></li>
<li>Files Published (mutable): <t:transparent t:render="publishes" /></li>
<li>Files Retrieved (mutable): <t:transparent t:render="retrieves" /></li>
</ul>
<h2>Raw Stats:</h2>
<pre n:render="raw" />
<pre t:render="raw" />
<div>Return to the <a href="/">Welcome Page</a></div>

View File

@ -2,7 +2,14 @@
import pprint, itertools, hashlib
import json
from twisted.internet import defer
from twisted.python.filepath import FilePath
from twisted.web.resource import Resource
from twisted.web.template import (
Element,
XMLFile,
renderer,
renderElement,
)
from nevow import rend, tags as T
from allmydata.util import base32, idlib
from allmydata.web.common import (
@ -14,6 +21,7 @@ from allmydata.web.common import (
compute_rate,
render_time,
MultiFormatPage,
MultiFormatResource,
)
from allmydata.interfaces import IUploadStatus, IDownloadStatus, \
IPublishStatus, IRetrieveStatus, IServermapUpdaterStatus
@ -1164,52 +1172,93 @@ class HelperStatus(MultiFormatPage):
def render_upload_bytes_encoded(self, ctx, data):
return str(data["chk_upload_helper.encoded_bytes"])
# Render "/statistics" page.
class Statistics(MultiFormatResource):
"""Class that renders "/statistics" page.
class Statistics(MultiFormatPage):
docFactory = getxmlfile("statistics.xhtml")
:param _allmydata.stats.StatsProvider provider: node statistics
provider.
"""
def __init__(self, provider):
rend.Page.__init__(self, provider)
self.provider = provider
super(Statistics, self).__init__()
self._provider = provider
def render_HTML(self, req):
return renderElement(req, StatisticsElement(self._provider))
def render_JSON(self, req):
stats = self.provider.get_stats()
stats = self._provider.get_stats()
req.setHeader("content-type", "text/plain")
return json.dumps(stats, indent=1) + "\n"
def data_get_stats(self, ctx, data):
return self.provider.get_stats()
class StatisticsElement(Element):
def render_load_average(self, ctx, data):
return str(data["stats"].get("load_monitor.avg_load"))
loader = XMLFile(FilePath(__file__).sibling("statistics.xhtml"))
def render_peak_load(self, ctx, data):
return str(data["stats"].get("load_monitor.max_load"))
def __init__(self, provider):
super(StatisticsElement, self).__init__()
# provider.get_stats() returns a dict of the below form, for
# example (there's often more data than this):
#
# {
# 'stats': {
# 'storage_server.disk_used': 809601609728,
# 'storage_server.accepting_immutable_shares': 1,
# 'storage_server.disk_free_for_root': 131486851072,
# 'storage_server.reserved_space': 1000000000,
# 'node.uptime': 0.16520118713378906,
# 'storage_server.disk_total': 941088460800,
# 'cpu_monitor.total': 0.004513999999999907,
# 'storage_server.disk_avail': 82610759168,
# 'storage_server.allocated': 0,
# 'storage_server.disk_free_for_nonroot': 83610759168 },
# 'counters': {
# 'uploader.files_uploaded': 0,
# 'uploader.bytes_uploaded': 0,
# ... }
# }
#
# Note that `counters` can be empty.
self._stats = provider.get_stats()
def render_uploads(self, ctx, data):
files = data["counters"].get("uploader.files_uploaded", 0)
bytes = data["counters"].get("uploader.bytes_uploaded", 0)
return ("%s files / %s bytes (%s)" %
(files, bytes, abbreviate_size(bytes)))
@renderer
def load_average(self, req, tag):
return tag(str(self._stats["stats"].get("load_monitor.avg_load")))
def render_downloads(self, ctx, data):
files = data["counters"].get("downloader.files_downloaded", 0)
bytes = data["counters"].get("downloader.bytes_downloaded", 0)
return ("%s files / %s bytes (%s)" %
(files, bytes, abbreviate_size(bytes)))
@renderer
def peak_load(self, req, tag):
return tag(str(self._stats["stats"].get("load_monitor.max_load")))
def render_publishes(self, ctx, data):
files = data["counters"].get("mutable.files_published", 0)
bytes = data["counters"].get("mutable.bytes_published", 0)
return "%s files / %s bytes (%s)" % (files, bytes,
abbreviate_size(bytes))
@renderer
def uploads(self, req, tag):
files = self._stats["counters"].get("uploader.files_uploaded", 0)
bytes = self._stats["counters"].get("uploader.bytes_uploaded", 0)
return tag(("%s files / %s bytes (%s)" %
(files, bytes, abbreviate_size(bytes))))
def render_retrieves(self, ctx, data):
files = data["counters"].get("mutable.files_retrieved", 0)
bytes = data["counters"].get("mutable.bytes_retrieved", 0)
return "%s files / %s bytes (%s)" % (files, bytes,
abbreviate_size(bytes))
@renderer
def downloads(self, req, tag):
files = self._stats["counters"].get("downloader.files_downloaded", 0)
bytes = self._stats["counters"].get("downloader.bytes_downloaded", 0)
return tag("%s files / %s bytes (%s)" %
(files, bytes, abbreviate_size(bytes)))
def render_raw(self, ctx, data):
raw = pprint.pformat(data)
return ctx.tag[raw]
@renderer
def publishes(self, req, tag):
files = self._stats["counters"].get("mutable.files_published", 0)
bytes = self._stats["counters"].get("mutable.bytes_published", 0)
return tag("%s files / %s bytes (%s)" % (files, bytes,
abbreviate_size(bytes)))
@renderer
def retrieves(self, req, tag):
files = self._stats["counters"].get("mutable.files_retrieved", 0)
bytes = self._stats["counters"].get("mutable.bytes_retrieved", 0)
return tag("%s files / %s bytes (%s)" % (files, bytes,
abbreviate_size(bytes)))
@renderer
def raw(self, req, tag):
raw = pprint.pformat(self._stats)
return tag(raw)