From b40a625283c7f6fe048d6ad03ba07aa0303c5b7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Sch=C3=A4fer?= Date: Thu, 27 May 2021 17:53:42 +0200 Subject: [PATCH] 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). --- snikket_web/__init__.py | 2 + snikket_web/admin.py | 75 +++++++----- snikket_web/templates/admin_home.html | 4 + snikket_web/templates/admin_system.html | 2 + snikket_web/translations/messages.pot | 156 ++++++++++++------------ 5 files changed, 132 insertions(+), 107 deletions(-) diff --git a/snikket_web/__init__.py b/snikket_web/__init__.py index b3c5015..78e5a8d 100644 --- a/snikket_web/__init__.py +++ b/snikket_web/__init__.py @@ -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( diff --git a/snikket_web/admin.py b/snikket_web/admin.py index d7ca471..65445a0 100644 --- a/snikket_web/admin.py +++ b/snikket_web/admin.py @@ -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, ) diff --git a/snikket_web/templates/admin_home.html b/snikket_web/templates/admin_home.html index f76fc03..934b611 100644 --- a/snikket_web/templates/admin_home.html +++ b/snikket_web/templates/admin_home.html @@ -34,7 +34,11 @@
  • {% trans %}System health{% endtrans %}

    {#- -#} + {%- if show_metrics -%}

    {% trans %}View the server status or send a broadcast message to all users.{% endtrans %}

    + {%- else -%} +

    {% trans %}Send a broadcast message to all users.{% endtrans %}

    + {%- endif -%} {#- -#}
    {% call standard_button("insights", url_for(".system"), class="primary") %}{% trans %}Manage system{% endtrans %}{% endcall %}
    {#- -#} diff --git a/snikket_web/templates/admin_system.html b/snikket_web/templates/admin_system.html index 6d57c87..c2360fb 100644 --- a/snikket_web/templates/admin_system.html +++ b/snikket_web/templates/admin_system.html @@ -2,6 +2,7 @@ {% from "library.j2" import form_button %} {% block content %}

    {% trans %}Manage system{% endtrans %}

    +{% if show_metrics %}

    {% trans %}Overall system status{% endtrans %}

    @@ -77,6 +78,7 @@
    +{% endif %}

    {% trans %}Broadcast message{% endtrans %}

    {{ form.csrf_token }}

    {% trans %}This form allows you to send a message to all users currently online on your Snikket server. Use it wisely.{% endtrans %}

    diff --git a/snikket_web/translations/messages.pot b/snikket_web/translations/messages.pot index a513ff1..c705aea 100644 --- a/snikket_web/translations/messages.pot +++ b/snikket_web/translations/messages.pot @@ -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 \n" "Language-Team: LANGUAGE \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."