admin: allow disabling display of metrics

This is useful in situations where the admins of the Snikket
server (i.e. those who care for the docker containers) are not the
same people as the people who are admins of the Snikket service
(i.e. those who care for the users).
This commit is contained in:
Jonas Schäfer
2021-05-27 17:53:42 +02:00
parent 8a293985ca
commit b40a625283
5 changed files with 132 additions and 107 deletions

View File

@@ -160,6 +160,7 @@ class AppConfig:
# Future versions may change this default, and the standard deployment
# tools may also very well override it.
max_avatar_size = environ.var(1024*1024, converter=int)
show_metrics = environ.bool_var(True)
_UPPER_CASE = "".join(map(chr, range(ord("A"), ord("Z")+1)))
@@ -191,6 +192,7 @@ def create_app() -> quart.Quart:
app.config["AVATAR_CACHE_TTL"] = config.avatar_cache_ttl
app.config["APPLE_STORE_URL"] = config.apple_store_url
app.config["MAX_AVATAR_SIZE"] = config.max_avatar_size
app.config["SHOW_METRICS"] = config.show_metrics
app.context_processor(proc)
app.register_error_handler(

View File

@@ -20,6 +20,7 @@ from quart import (
request,
abort,
flash,
current_app,
)
from flask_babel import lazy_gettext as _l, _
@@ -33,7 +34,11 @@ bp = Blueprint("admin", __name__, url_prefix="/admin")
@bp.route("/")
@client.require_admin_session()
async def index() -> str:
return await render_template("admin_home.html")
show_metrics = current_app.config["SHOW_METRICS"]
return await render_template(
"admin_home.html",
show_metrics=show_metrics,
)
class PasswordResetLinkPost(BaseForm):
@@ -575,7 +580,9 @@ def get_system_stats() -> typing.MutableMapping[
(time.monotonic() - _MONOTONIC_EPOCH)
)
mem_total, mem_available = None, None
load5: typing.Optional[float] = None
try:
with open("/proc/loadavg") as f:
stats = f.read().split()
@@ -583,7 +590,6 @@ def get_system_stats() -> typing.MutableMapping[
except (ValueError, IndexError, TypeError, OSError):
pass
mem_total, mem_available = None, None
try:
with open("/proc/meminfo") as f:
for line in f:
@@ -650,37 +656,43 @@ async def system() -> typing.Union[str, quart.Response]:
# redirect only if not previewing
return redirect(url_for(".system"))
version = await client.get_server_version()
now = time.time()
try:
prosody_metrics = await client.get_system_metrics()
except quart.exceptions.NotFound:
# server does not offer the endpoint for whatever reason -- ignore
prosody_metrics = {}
version = None
now = None
show_metrics = current_app.config["SHOW_METRICS"]
if show_metrics:
version = await client.get_server_version()
now = time.time()
try:
prosody_metrics = await client.get_system_metrics()
except quart.exceptions.NotFound:
# server does not offer the endpoint for whatever reason -- ignore
prosody_metrics = {}
metrics = get_system_stats()
try:
prosody_cpu_metrics = prosody_metrics["cpu"]
except KeyError:
pass
metrics = get_system_stats()
try:
prosody_cpu_metrics = prosody_metrics["cpu"]
except KeyError:
pass
else:
metrics["prosody_cpu"] = (prosody_cpu_metrics["value"] /
(now - prosody_cpu_metrics["since"]))
try:
metrics["prosody_rss"] = prosody_metrics["memory"]
except KeyError:
pass
try:
metrics["prosody_devices"] = prosody_metrics["c2s"]
except KeyError:
pass
for k in list(metrics.keys()):
if metrics[k] is None:
# so that defaulting in jinja works
del metrics[k]
else:
metrics["prosody_cpu"] = (prosody_cpu_metrics["value"] /
(now - prosody_cpu_metrics["since"]))
try:
metrics["prosody_rss"] = prosody_metrics["memory"]
except KeyError:
pass
try:
metrics["prosody_devices"] = prosody_metrics["c2s"]
except KeyError:
pass
for k in list(metrics.keys()):
if metrics[k] is None:
# so that defaulting in jinja works
del metrics[k]
metrics = {}
return await render_template(
"admin_system.html",
@@ -688,4 +700,5 @@ async def system() -> typing.Union[str, quart.Response]:
version=_version.version,
prosody_version=version,
form=form,
show_metrics=show_metrics,
)

View File

@@ -34,7 +34,11 @@
<li>
<h2>{% trans %}System health{% endtrans %}</h2>
{#- -#}
{%- if show_metrics -%}
<p>{% trans %}View the server status or send a broadcast message to all users.{% endtrans %}</p>
{%- else -%}
<p>{% trans %}Send a broadcast message to all users.{% endtrans %}</p>
{%- endif -%}
{#- -#}
<div>{% call standard_button("insights", url_for(".system"), class="primary") %}{% trans %}Manage system{% endtrans %}{% endcall %}</div>
{#- -#}

View File

@@ -2,6 +2,7 @@
{% from "library.j2" import form_button %}
{% block content %}
<h1>{% trans %}Manage system{% endtrans %}</h1>
{% if show_metrics %}
<h2>{% trans %}Overall system status{% endtrans %}</h2>
<div class="elevated el-2">
<dl>
@@ -77,6 +78,7 @@
</dd>
</dl>
</div>
{% endif %}
<h2>{% trans %}Broadcast message{% endtrans %}</h2>
<form method="POST">{{ form.csrf_token }}<div class="form layout-expanded">
<p class="form-desc">{% trans %}This form allows you to send a message to all users currently online on your Snikket server. Use it wisely.{% endtrans %}</p>

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2021-05-27 17:21+0200\n"
"POT-Creation-Date: 2021-05-27 17:59+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,193 +17,193 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.1\n"
#: snikket_web/admin.py:61
#: snikket_web/admin.py:66
msgid "Limited"
msgstr ""
#: snikket_web/admin.py:66 snikket_web/templates/admin_delete_user.html:10
#: snikket_web/admin.py:71 snikket_web/templates/admin_delete_user.html:10
#: snikket_web/templates/admin_users.html:8
msgid "Login name"
msgstr ""
#: snikket_web/admin.py:70 snikket_web/templates/admin_delete_user.html:12
#: snikket_web/admin.py:75 snikket_web/templates/admin_delete_user.html:12
#: snikket_web/templates/admin_users.html:9 snikket_web/user.py:61
msgid "Display name"
msgstr ""
#: snikket_web/admin.py:74 snikket_web/templates/admin_edit_user.html:32
#: snikket_web/admin.py:79 snikket_web/templates/admin_edit_user.html:32
msgid "Access Level"
msgstr ""
#: snikket_web/admin.py:79
#: snikket_web/admin.py:84
msgid "Normal user"
msgstr ""
#: snikket_web/admin.py:80
#: snikket_web/admin.py:85
msgid "Administrator"
msgstr ""
#: snikket_web/admin.py:85
#: snikket_web/admin.py:90
msgid "Update user"
msgstr ""
#: snikket_web/admin.py:89
#: snikket_web/admin.py:94
msgid "Create password reset link"
msgstr ""
#: snikket_web/admin.py:107
#: snikket_web/admin.py:112
msgid "Password reset link created"
msgstr ""
#: snikket_web/admin.py:122
#: snikket_web/admin.py:127
msgid "User information updated."
msgstr ""
#: snikket_web/admin.py:144
#: snikket_web/admin.py:149
msgid "Delete user permanently"
msgstr ""
#: snikket_web/admin.py:157
#: snikket_web/admin.py:162
msgid "User deleted"
msgstr ""
#: snikket_web/admin.py:195
#: snikket_web/admin.py:200
msgid "Password reset link not found"
msgstr ""
#: snikket_web/admin.py:207
#: snikket_web/admin.py:212
msgid "Password reset link deleted"
msgstr ""
#: snikket_web/admin.py:227
#: snikket_web/admin.py:232
msgid "Invite to circle"
msgstr ""
#: snikket_web/admin.py:233
#: snikket_web/admin.py:238
msgid "At least one circle must be selected"
msgstr ""
#: snikket_web/admin.py:238
#: snikket_web/admin.py:243
msgid "Valid for"
msgstr ""
#: snikket_web/admin.py:240
#: snikket_web/admin.py:245
msgid "One hour"
msgstr ""
#: snikket_web/admin.py:241
#: snikket_web/admin.py:246
msgid "Twelve hours"
msgstr ""
#: snikket_web/admin.py:242
#: snikket_web/admin.py:247
msgid "One day"
msgstr ""
#: snikket_web/admin.py:243
#: snikket_web/admin.py:248
msgid "One week"
msgstr ""
#: snikket_web/admin.py:244
#: snikket_web/admin.py:249
msgid "Four weeks"
msgstr ""
#: snikket_web/admin.py:250 snikket_web/templates/admin_edit_invite.html:17
#: snikket_web/admin.py:255 snikket_web/templates/admin_edit_invite.html:17
msgid "Invitation type"
msgstr ""
#: snikket_web/admin.py:252 snikket_web/templates/library.j2:116
#: snikket_web/admin.py:257 snikket_web/templates/library.j2:116
msgid "Individual"
msgstr ""
#: snikket_web/admin.py:253 snikket_web/templates/library.j2:114
#: snikket_web/admin.py:258 snikket_web/templates/library.j2:114
msgid "Group"
msgstr ""
#: snikket_web/admin.py:259
#: snikket_web/admin.py:264
msgid "New invitation link"
msgstr ""
#: snikket_web/admin.py:321
#: snikket_web/admin.py:326
msgid "Revoke"
msgstr ""
#: snikket_web/admin.py:345
#: snikket_web/admin.py:350
msgid "Invitation created"
msgstr ""
#: snikket_web/admin.py:361
#: snikket_web/admin.py:366
msgid "No such invitation exists"
msgstr ""
#: snikket_web/admin.py:376
#: snikket_web/admin.py:381
msgid "Invitation revoked"
msgstr ""
#: snikket_web/admin.py:393 snikket_web/admin.py:441
#: snikket_web/admin.py:398 snikket_web/admin.py:446
msgid "Name"
msgstr ""
#: snikket_web/admin.py:398 snikket_web/templates/admin_circles.html:47
#: snikket_web/admin.py:403 snikket_web/templates/admin_circles.html:47
msgid "Create circle"
msgstr ""
#: snikket_web/admin.py:428
#: snikket_web/admin.py:433
msgid "Circle created"
msgstr ""
#: snikket_web/admin.py:446
#: snikket_web/admin.py:451
msgid "Select user"
msgstr ""
#: snikket_web/admin.py:451
#: snikket_web/admin.py:456
msgid "Update circle"
msgstr ""
#: snikket_web/admin.py:455
#: snikket_web/admin.py:460
msgid "Delete circle permanently"
msgstr ""
#: snikket_web/admin.py:461
#: snikket_web/admin.py:466
msgid "Add user"
msgstr ""
#: snikket_web/admin.py:477
#: snikket_web/admin.py:482
msgid "No such circle exists"
msgstr ""
#: snikket_web/admin.py:514
#: snikket_web/admin.py:519
msgid "Circle data updated"
msgstr ""
#: snikket_web/admin.py:520
#: snikket_web/admin.py:525
msgid "Circle deleted"
msgstr ""
#: snikket_web/admin.py:531
#: snikket_web/admin.py:536
msgid "User added to circle"
msgstr ""
#: snikket_web/admin.py:540
#: snikket_web/admin.py:545
msgid "User removed from circle"
msgstr ""
#: snikket_web/admin.py:610
#: snikket_web/admin.py:616
msgid "Message contents"
msgstr ""
#: snikket_web/admin.py:616
#: snikket_web/admin.py:622
msgid "Only send to online users"
msgstr ""
#: snikket_web/admin.py:620
#: snikket_web/admin.py:626
msgid "Post to all users"
msgstr ""
#: snikket_web/admin.py:624
#: snikket_web/admin.py:630
msgid "Send preview to yourself"
msgstr ""
#: snikket_web/admin.py:646
#: snikket_web/admin.py:652
msgid "Announcement sent!"
msgstr ""
@@ -780,20 +780,24 @@ msgstr ""
msgid "System health"
msgstr ""
#: snikket_web/templates/admin_home.html:37
#: snikket_web/templates/admin_home.html:38
msgid "View the server status or send a broadcast message to all users."
msgstr ""
#: snikket_web/templates/admin_home.html:39
#: snikket_web/templates/admin_home.html:40
msgid "Send a broadcast message to all users."
msgstr ""
#: snikket_web/templates/admin_home.html:43
#: snikket_web/templates/admin_system.html:4
msgid "Manage system"
msgstr ""
#: snikket_web/templates/admin_home.html:44
#: snikket_web/templates/admin_home.html:48
msgid "Go back to your user's web portal page."
msgstr ""
#: snikket_web/templates/admin_home.html:46
#: snikket_web/templates/admin_home.html:50
msgid "Exit admin panel"
msgstr ""
@@ -844,72 +848,72 @@ msgstr ""
msgid "Destroy link"
msgstr ""
#: snikket_web/templates/admin_system.html:5
#: snikket_web/templates/admin_system.html:6
msgid "Overall system status"
msgstr ""
#: snikket_web/templates/admin_system.html:8
#: snikket_web/templates/admin_system.html:9
msgid "System load (5 minute average)"
msgstr ""
#: snikket_web/templates/admin_system.html:13
#: snikket_web/templates/admin_system.html:21
#: snikket_web/templates/admin_system.html:36
#: snikket_web/templates/admin_system.html:44
#: snikket_web/templates/admin_system.html:59
#: snikket_web/templates/admin_system.html:67
#: snikket_web/templates/admin_system.html:75
#: snikket_web/templates/admin_system.html:14
#: snikket_web/templates/admin_system.html:22
#: snikket_web/templates/admin_system.html:37
#: snikket_web/templates/admin_system.html:45
#: snikket_web/templates/admin_system.html:60
#: snikket_web/templates/admin_system.html:68
#: snikket_web/templates/admin_system.html:76
msgid "unknown"
msgstr ""
#: snikket_web/templates/admin_system.html:16
#: snikket_web/templates/admin_system.html:17
msgid "Memory use"
msgstr ""
#: snikket_web/templates/admin_system.html:19
#: snikket_web/templates/admin_system.html:20
#, python-format
msgid ""
"%(percentage_global)s of %(mem_available)s. Of that, Snikket uses "
"%(percentage_snikket)s."
msgstr ""
#: snikket_web/templates/admin_system.html:26
#: snikket_web/templates/admin_system.html:27
msgid "Web portal status"
msgstr ""
#: snikket_web/templates/admin_system.html:29
#: snikket_web/templates/admin_system.html:52
msgid "Version"
msgstr ""
#: snikket_web/templates/admin_system.html:30
#: snikket_web/templates/admin_system.html:53
msgid "View all versions"
msgid "Version"
msgstr ""
#: snikket_web/templates/admin_system.html:31
#: snikket_web/templates/admin_system.html:54
msgid "View all versions"
msgstr ""
#: snikket_web/templates/admin_system.html:32
#: snikket_web/templates/admin_system.html:55
msgid "Average CPU use"
msgstr ""
#: snikket_web/templates/admin_system.html:39
#: snikket_web/templates/admin_system.html:62
#: snikket_web/templates/admin_system.html:40
#: snikket_web/templates/admin_system.html:63
msgid "Current memory use"
msgstr ""
#: snikket_web/templates/admin_system.html:49
#: snikket_web/templates/admin_system.html:50
msgid "Snikket server status"
msgstr ""
#: snikket_web/templates/admin_system.html:70
#: snikket_web/templates/admin_system.html:71
msgid "Connected devices"
msgstr ""
#: snikket_web/templates/admin_system.html:80
#: snikket_web/templates/admin_system.html:82
msgid "Broadcast message"
msgstr ""
#: snikket_web/templates/admin_system.html:82
#: snikket_web/templates/admin_system.html:84
msgid ""
"This form allows you to send a message to all users currently online on "
"your Snikket server. Use it wisely."