From 2c360a99fe4a66afad6dc03a298bfc80a8769eb3 Mon Sep 17 00:00:00 2001 From: Michael Hollister Date: Mon, 22 Jul 2024 17:38:34 -0500 Subject: [PATCH 01/18] Added MMR metrics proxying support --- group_vars/matrix_servers | 11 +- .../matrix-media-repo/defaults/main.yml | 17 +++ .../templates/grafana/media-repo.json | 121 +++++++++--------- .../templates/media-repo/labels.j2 | 38 ++++++ 4 files changed, 121 insertions(+), 66 deletions(-) diff --git a/group_vars/matrix_servers b/group_vars/matrix_servers index 1ccaacf1d..5dbe7bc83 100755 --- a/group_vars/matrix_servers +++ b/group_vars/matrix_servers @@ -3611,6 +3611,12 @@ matrix_media_repo_container_labels_traefik_internal_media_entrypoints: "{{ matri matrix_media_repo_container_labels_traefik_internal_matrix_client_media_enabled: "{{ matrix_playbook_internal_matrix_client_api_traefik_entrypoint_enabled }}" matrix_media_repo_container_labels_traefik_internal_matrix_client_media_entrypoints: "{{ matrix_playbook_internal_matrix_client_api_traefik_entrypoint_name }}" +matrix_media_repo_metrics_proxying_enabled: "{{ matrix_media_repo_metrics_enabled and matrix_metrics_exposure_enabled }}" +matrix_media_repo_metrics_proxying_hostname: "{{ matrix_metrics_exposure_hostname }}" +matrix_media_repo_metrics_proxying_path: "{{ matrix_metrics_exposure_path_prefix }}/matrix-media-repo" +matrix_media_repo_container_labels_traefik_metrics_middleware_basic_auth_enabled: "{{ matrix_metrics_exposure_http_basic_auth_enabled }}" +matrix_media_repo_container_labels_traefik_metrics_middleware_basic_auth_users: "{{ matrix_metrics_exposure_http_basic_auth_users }}" + matrix_media_repo_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" matrix_media_repo_database_username: matrix_media_repo matrix_media_repo_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mediarepo.db', rounds=655555) | to_uuid }}" @@ -4880,11 +4886,6 @@ grafana_provisioning_dashboard_template_files: | 'path': 'roles/custom/matrix-prometheus-nginxlog-exporter/templates/grafana/nginx-proxy.json', 'name': 'nginx-proxy.json', }] if matrix_prometheus_nginxlog_exporter_enabled else []) - + - ([{ - 'path': 'roles/custom/matrix-media-repo/templates/grafana/media-repo.json', - 'name': 'media-repo.json', - }] if matrix_media_repo_metrics_enabled else []) }} grafana_default_home_dashboard_path: |- diff --git a/roles/custom/matrix-media-repo/defaults/main.yml b/roles/custom/matrix-media-repo/defaults/main.yml index 1ac4d6b56..1c5bfd665 100755 --- a/roles/custom/matrix-media-repo/defaults/main.yml +++ b/roles/custom/matrix-media-repo/defaults/main.yml @@ -44,6 +44,11 @@ matrix_media_repo_container_network: "{{ matrix_media_repo_identifier }}" # Use this to expose this container to another reverse proxy, which runs in a different container network. matrix_media_repo_container_additional_networks: [] +# Controls whether media repo metrics should be proxied (exposed) on `matrix.DOMAIN/metrics/matrix-media-repo` +matrix_media_repo_metrics_proxying_enabled: false +matrix_media_repo_metrics_proxying_hostname: "" +matrix_media_repo_metrics_proxying_path: "/metrics/matrix-media-repo" + # Controls whether the matrix-media-repo container exposes its HTTP port (tcp/8000 in the container). # # Takes an ":" or "" value (e.g. "127.0.0.1:8000"), or empty string to not expose. @@ -134,6 +139,18 @@ matrix_media_repo_container_labels_traefik_t2bot_entrypoints: "{{ matrix_media_r matrix_media_repo_container_labels_traefik_t2bot_tls: "{{ matrix_media_repo_container_labels_traefik_t2bot_entrypoints != 'web' }}" matrix_media_repo_container_labels_traefik_t2bot_tls_certResolver: default # noqa var-naming +# Controls whether labels will be added that expose the media repo metrics endpoint +matrix_media_repo_container_labels_traefik_metrics_enabled: "{{ matrix_media_repo_metrics_enabled and matrix_media_repo_metrics_proxying_enabled }}" +matrix_media_repo_container_labels_traefik_metrics_rule: "Host(`{{ matrix_media_repo_metrics_proxying_hostname }}`) && PathPrefix(`{{ matrix_media_repo_metrics_proxying_path }}`)" +matrix_media_repo_container_labels_traefik_metrics_priority: 0 +matrix_media_repo_container_labels_traefik_metrics_entrypoints: "{{ matrix_media_repo_container_labels_traefik_entrypoints }}" +matrix_media_repo_container_labels_traefik_metrics_tls: "{{ matrix_media_repo_container_labels_traefik_t2bot_entrypoints != 'web' }}" +matrix_media_repo_container_labels_traefik_metrics_tls_certResolver: default # noqa var-naming + +matrix_media_repo_container_labels_traefik_metrics_middleware_basic_auth_enabled: false +# See: https://doc.traefik.io/traefik/middlewares/http/basicauth/#users +matrix_media_repo_container_labels_traefik_metrics_middleware_basic_auth_users: '' + # Traefik labels handling the old `/_matrix/media` endpoints on the federation entrypint. # These are being superseded by `/_matrix/federation/VERSION/media` endpoints - see `matrix_media_repo_container_labels_traefik_federation_matrix_federation_media_*`. matrix_media_repo_container_labels_traefik_media_federation_enabled: true diff --git a/roles/custom/matrix-media-repo/templates/grafana/media-repo.json b/roles/custom/matrix-media-repo/templates/grafana/media-repo.json index feee5bace..b2c2eadfa 100644 --- a/roles/custom/matrix-media-repo/templates/grafana/media-repo.json +++ b/roles/custom/matrix-media-repo/templates/grafana/media-repo.json @@ -1,59 +1,16 @@ { - "__inputs": [ - { - "name": "DS_PROMETHEUS", - "label": "Prometheus", - "description": "", - "type": "datasource", - "pluginId": "prometheus", - "pluginName": "Prometheus" - } - ], - "__elements": {}, - "__requires": [ - { - "type": "grafana", - "id": "grafana", - "name": "Grafana", - "version": "10.1.0" - }, - { - "type": "panel", - "id": "heatmap", - "name": "Heatmap", - "version": "" - }, - { - "type": "datasource", - "id": "prometheus", - "name": "Prometheus", - "version": "1.0.0" - }, - { - "type": "panel", - "id": "timeseries", - "name": "Time series", - "version": "" - } - ], "annotations": { "list": [ { "builtIn": 1, "datasource": { - "type": "datasource", - "uid": "grafana" + "type": "grafana", + "uid": "${DS_PROMETHEUS}" }, "enable": true, "hide": true, "iconColor": "rgba(0, 211, 255, 1)", "name": "Annotations & Alerts", - "target": { - "limit": 100, - "matchAny": false, - "tags": [], - "type": "dashboard" - }, "type": "dashboard" } ] @@ -153,7 +110,7 @@ "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "rate(media_http_requests_total[2m])", + "expr": "rate(media_http_requests_total{host=\"$host\"}[2m])", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{ '{{host}}: {{method}} {{action}}' }}", @@ -166,7 +123,7 @@ "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "rate(media_invalid_http_requests_total[2m])", + "expr": "rate(media_invalid_http_requests_total{host=\"$host\"}[2m])", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{ 'Invalid Host: {{method}} {{action}}' }}", @@ -265,7 +222,7 @@ "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "rate(media_http_responses_total[2m])", + "expr": "rate(media_http_responses_total{host=\"$host\"}[2m])", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{ '{{host}}: {{method}} {{action}} {{statusCode}}' }}", @@ -278,7 +235,7 @@ "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "rate(media_invalid_http_requests_total[2m])", + "expr": "rate(media_invalid_http_requests_total{host=\"$host\"}[2m])", "format": "time_series", "hide": false, "intervalFactor": 1, @@ -369,7 +326,7 @@ }, "editorMode": "code", "exemplar": false, - "expr": "sum(rate(media_http_response_time_seconds_bucket{action=~\"download|thumbnail\"}[2m])) by (le)", + "expr": "sum(rate(media_http_response_time_seconds_bucket{action=~\"download|thumbnail\", host=\"$host\"}[2m])) by (le)", "format": "heatmap", "instant": false, "interval": "", @@ -460,7 +417,7 @@ }, "editorMode": "code", "exemplar": false, - "expr": "sum(rate(media_http_response_time_seconds_bucket{action=\"upload\"}[2m])) by (le)", + "expr": "sum(rate(media_http_response_time_seconds_bucket{action=\"upload\", host=\"$host\"}[2m])) by (le)", "format": "heatmap", "instant": false, "legendFormat": "{{ '{{method}} {{action}} - {{le}}' }}", @@ -560,7 +517,7 @@ }, "editorMode": "code", "exemplar": true, - "expr": "go_memstats_alloc_bytes{job=\"media_repo\"}", + "expr": "go_memstats_alloc_bytes", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -574,7 +531,7 @@ "uid": "${DS_PROMETHEUS}" }, "exemplar": true, - "expr": "go_memstats_sys_bytes{job=\"media_repo\"}", + "expr": "go_memstats_sys_bytes", "interval": "", "legendFormat": "memory usage (sys)", "refId": "C" @@ -585,7 +542,7 @@ "uid": "${DS_PROMETHEUS}" }, "exemplar": true, - "expr": "go_memstats_heap_alloc_bytes{job=\"media_repo\"}", + "expr": "go_memstats_heap_alloc_bytes", "interval": "", "legendFormat": "heap usage (alloc)", "refId": "A" @@ -596,7 +553,7 @@ "uid": "${DS_PROMETHEUS}" }, "exemplar": true, - "expr": "go_memstats_heap_idle_bytes{job=\"media_repo\"}", + "expr": "go_memstats_heap_idle_bytes", "interval": "", "legendFormat": "heap usage (idle)", "refId": "D" @@ -607,7 +564,7 @@ "uid": "${DS_PROMETHEUS}" }, "exemplar": true, - "expr": "go_memstats_heap_inuse_bytes{job=\"media_repo\"}", + "expr": "go_memstats_heap_inuse_bytes", "interval": "", "legendFormat": "heap usage (used)", "refId": "E" @@ -619,7 +576,7 @@ }, "editorMode": "code", "exemplar": true, - "expr": "go_memstats_heap_released_bytes{job=\"media_repo\"}", + "expr": "go_memstats_heap_released_bytes", "hide": false, "legendFormat": "heap usage (released)", "range": true, @@ -718,7 +675,7 @@ }, "editorMode": "code", "exemplar": true, - "expr": "go_goroutines{job=\"media_repo\"}", + "expr": "go_goroutines", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -733,7 +690,7 @@ }, "editorMode": "code", "exemplar": true, - "expr": "go_threads{job=\"media_repo\"}", + "expr": "go_threads", "format": "time_series", "hide": false, "interval": "", @@ -1263,9 +1220,51 @@ "refresh": "1m", "schemaVersion": 38, "style": "dark", - "tags": [], + "tags": [ + "matrix" + ], "templating": { - "list": [] + "list": [ + { + "current": {}, + "hide": 0, + "includeAll": false, + "label": "Datasource", + "multi": false, + "name": "DS_PROMETHEUS", + "options": [], + "query": "prometheus", + "queryValue": "", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "current": {}, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "label_values(media_http_response_time_seconds_bucket,host)", + "hide": 0, + "includeAll": false, + "label": "Host", + "multi": false, + "name": "host", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(media_http_response_time_seconds_bucket,host)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + } + ] }, "time": { "from": "now-1h", diff --git a/roles/custom/matrix-media-repo/templates/media-repo/labels.j2 b/roles/custom/matrix-media-repo/templates/media-repo/labels.j2 index e6b675880..57b21d897 100755 --- a/roles/custom/matrix-media-repo/templates/media-repo/labels.j2 +++ b/roles/custom/matrix-media-repo/templates/media-repo/labels.j2 @@ -6,6 +6,7 @@ traefik.docker.network={{ matrix_media_repo_container_labels_traefik_docker_netw {% endif %} traefik.http.services.matrix-media-repo.loadbalancer.server.port={{ matrix_media_repo_port }} +traefik.http.services.matrix-media-repo-metrics.loadbalancer.server.port={{ matrix_media_repo_metrics_port }} {% set middlewares = [] %} @@ -243,6 +244,43 @@ traefik.http.routers.matrix-media-repo-public-t2bot.tls.certResolver={{ matrix_m {% endif %} +{% if matrix_media_repo_container_labels_traefik_metrics_enabled %} +############################################################ +# # +# Metrics # +# # +############################################################ + +{% set metricsMiddlewares = ['matrix-media-repo-metrics-replace-path'] %} +traefik.http.middlewares.matrix-media-repo-metrics-replace-path.replacepath.path=/metrics + +{% if matrix_media_repo_container_labels_traefik_metrics_middleware_basic_auth_enabled %} +{% set metricsMiddlewares = metricsMiddlewares + ['matrix-media-repo-metrics-basic-auth'] %} +traefik.http.middlewares.matrix-media-repo-metrics-basic-auth.basicauth.users={{ matrix_media_repo_container_labels_traefik_metrics_middleware_basic_auth_users }} +{% endif %} + +traefik.http.routers.matrix-media-repo-metrics.rule={{ matrix_media_repo_container_labels_traefik_metrics_rule }} +traefik.http.routers.matrix-media-repo-metrics.middlewares={{ metricsMiddlewares | join(',') }} + +{% if matrix_media_repo_container_labels_traefik_metrics_priority | int > 0 %} +traefik.http.routers.matrix-media-repo-metrics.priority={{ matrix_media_repo_container_labels_traefik_metrics_priority }} +{% endif %} + +traefik.http.routers.matrix-media-repo-metrics.service=matrix-media-repo-metrics +traefik.http.routers.matrix-media-repo-metrics.entrypoints={{ matrix_media_repo_container_labels_traefik_metrics_entrypoints }} + +traefik.http.routers.matrix-media-repo-metrics.tls={{ matrix_media_repo_container_labels_traefik_metrics_tls | to_json }} +{% if matrix_media_repo_container_labels_traefik_metrics_tls %} +traefik.http.routers.matrix-media-repo-metrics.tls.certResolver={{ matrix_media_repo_container_labels_traefik_metrics_tls_certResolver }} +{% endif %} + +############################################################ +# # +# /Metrics # +# # +############################################################ +{% endif %} + {% if matrix_media_repo_homeserver_federation_enabled %} # Matrix Federation From 98a2810fa2672da4ae7befc74cb5d25ccc4682c9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 10:22:47 +0000 Subject: [PATCH 02/18] chore(deps): update registry.gitlab.com/etke.cc/postmoogle docker tag to v0.9.19 --- roles/custom/matrix-bot-postmoogle/defaults/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/custom/matrix-bot-postmoogle/defaults/main.yml b/roles/custom/matrix-bot-postmoogle/defaults/main.yml index 7673d85e6..1aca94d04 100644 --- a/roles/custom/matrix-bot-postmoogle/defaults/main.yml +++ b/roles/custom/matrix-bot-postmoogle/defaults/main.yml @@ -10,7 +10,7 @@ matrix_bot_postmoogle_docker_repo_version: "{{ 'main' if matrix_bot_postmoogle_v matrix_bot_postmoogle_docker_src_files_path: "{{ matrix_base_data_path }}/postmoogle/docker-src" # renovate: datasource=docker depName=registry.gitlab.com/etke.cc/postmoogle -matrix_bot_postmoogle_version: v0.9.18 +matrix_bot_postmoogle_version: v0.9.19 matrix_bot_postmoogle_docker_image: "{{ matrix_bot_postmoogle_docker_image_name_prefix }}etke.cc/postmoogle:{{ matrix_bot_postmoogle_version }}" matrix_bot_postmoogle_docker_image_name_prefix: "{{ 'localhost/' if matrix_bot_postmoogle_container_image_self_build else 'registry.gitlab.com/' }}" matrix_bot_postmoogle_docker_image_force_pull: "{{ matrix_bot_postmoogle_docker_image.endswith(':latest') }}" From 98f5f1c20022153b92284d573424d433ac4a03bd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 11:21:13 +0000 Subject: [PATCH 03/18] chore(deps): update registry.gitlab.com/etke.cc/honoroit docker tag to v0.9.23 --- roles/custom/matrix-bot-honoroit/defaults/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/custom/matrix-bot-honoroit/defaults/main.yml b/roles/custom/matrix-bot-honoroit/defaults/main.yml index 630c90dbd..013b68499 100644 --- a/roles/custom/matrix-bot-honoroit/defaults/main.yml +++ b/roles/custom/matrix-bot-honoroit/defaults/main.yml @@ -21,7 +21,7 @@ matrix_bot_honoroit_docker_repo_version: "{{ matrix_bot_honoroit_version }}" matrix_bot_honoroit_docker_src_files_path: "{{ matrix_base_data_path }}/honoroit/docker-src" # renovate: datasource=docker depName=registry.gitlab.com/etke.cc/honoroit -matrix_bot_honoroit_version: v0.9.22 +matrix_bot_honoroit_version: v0.9.23 matrix_bot_honoroit_docker_image: "{{ matrix_bot_honoroit_docker_image_name_prefix }}etke.cc/honoroit:{{ matrix_bot_honoroit_version }}" matrix_bot_honoroit_docker_image_name_prefix: "{{ 'localhost/' if matrix_bot_honoroit_container_image_self_build else 'registry.gitlab.com/' }}" matrix_bot_honoroit_docker_image_force_pull: "{{ matrix_bot_honoroit_docker_image.endswith(':latest') }}" From 91f5731287d0482d41a8e085a439165ace657401 Mon Sep 17 00:00:00 2001 From: Aine <97398200+etkecc@users.noreply.github.com> Date: Tue, 23 Jul 2024 11:21:32 +0000 Subject: [PATCH 04/18] buscarron v1.4.2 (#3437) * buscarron v1.4.2 * Add more spaces before comments --------- Co-authored-by: Slavi Pantaleev --- roles/custom/matrix-bot-buscarron/defaults/main.yml | 13 ++++++++++++- roles/custom/matrix-bot-buscarron/templates/env.j2 | 7 +++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/roles/custom/matrix-bot-buscarron/defaults/main.yml b/roles/custom/matrix-bot-buscarron/defaults/main.yml index 56defb34f..d99400700 100644 --- a/roles/custom/matrix-bot-buscarron/defaults/main.yml +++ b/roles/custom/matrix-bot-buscarron/defaults/main.yml @@ -6,7 +6,7 @@ matrix_bot_buscarron_enabled: true # renovate: datasource=docker depName=registry.gitlab.com/etke.cc/buscarron -matrix_bot_buscarron_version: v1.4.1 +matrix_bot_buscarron_version: v1.4.2 # The hostname at which Buscarron is served. matrix_bot_buscarron_hostname: '' @@ -50,6 +50,17 @@ matrix_bot_buscarron_metrics_password: '' # /metrics allowed ips matrix_bot_buscarron_metrics_ips: [] +# healthchecks.io integration +matrix_bot_buscarron_hc_url: '' # default is https://hc-ping.com (healthchecks.io) +matrix_bot_buscarron_hc_uuid: '' # check UUID + +# redmine integration +matrix_bot_buscarron_redmine_host: '' # e.g. https://redmine.example.com +matrix_bot_buscarron_redmine_apikey: '' +matrix_bot_buscarron_redmine_project: '' # project identifier (e.g., my-project) +matrix_bot_buscarron_redmine_trackerid: '' # task tracker ID (e.g., 1) +matrix_bot_buscarron_redmine_statusid: '' # task status ID (e.g., 1) + # matrix_bot_buscarron_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. # See `../templates/labels.j2` for details. diff --git a/roles/custom/matrix-bot-buscarron/templates/env.j2 b/roles/custom/matrix-bot-buscarron/templates/env.j2 index acfe99eba..11a4f6bd6 100644 --- a/roles/custom/matrix-bot-buscarron/templates/env.j2 +++ b/roles/custom/matrix-bot-buscarron/templates/env.j2 @@ -5,6 +5,8 @@ BUSCARRON_DB_DSN={{ matrix_bot_buscarron_database_connection_string }} BUSCARRON_DB_DIALECT={{ matrix_bot_buscarron_database_dialect }} BUSCARRON_SPAMLIST={{ matrix_bot_buscarron_spamlist|join(" ") }} BUSCARRON_SENTRY={{ matrix_bot_buscarron_sentry }} +BUSCARRON_HC_URL={{ matrix_bot_buscarron_hc_url }} +BUSCARRON_HC_UUID={{ matrix_bot_buscarron_hc_uuid }} BUSCARRON_LOGLEVEL={{ matrix_bot_buscarron_loglevel }} BUSCARRON_BAN_SIZE={{ matrix_bot_buscarron_ban_size }} BUSCARRON_BAN_LIST={{ matrix_bot_buscarron_ban_list|default('')|join(' ') }} @@ -16,6 +18,11 @@ BUSCARRON_SMTP_VALIDATION={{ matrix_bot_buscarron_smtp_validation }} BUSCARRON_METRICS_LOGIN={{ matrix_bot_buscarron_metrics_login }} BUSCARRON_METRICS_PASSWORD={{ matrix_bot_buscarron_metrics_password }} BUSCARRON_METRICS_IPS={{ matrix_bot_buscarron_metrics_ips|default([])|join(" ") }} +BUSCARRON_REDMINE_HOST={{ matrix_bot_buscarron_redmine_host }} +BUSCARRON_REDMINE_APIKEY={{ matrix_bot_buscarron_redmine_apikey }} +BUSCARRON_REDMINE_PROJECT={{ matrix_bot_buscarron_redmine_project }} +BUSCARRON_REDMINE_TRACKERID={{ matrix_bot_buscarron_redmine_trackerid }} +BUSCARRON_REDMINE_STATUSID={{ matrix_bot_buscarron_redmine_statusid }} {% set forms = [] %} {% for form in matrix_bot_buscarron_forms -%}{{- forms.append(form.name) -}} BUSCARRON_{{ form.name|upper }}_ROOM={{ form.room|default('') }} From f1dbbd31068af63c5c335a368d1a7afd8a03aec4 Mon Sep 17 00:00:00 2001 From: Michael Hollister Date: Tue, 23 Jul 2024 11:29:19 -0500 Subject: [PATCH 05/18] Added new fields to MMR config template --- .../configuring-playbook-matrix-media-repo.md | 6 ++-- group_vars/matrix_servers | 5 +++ .../matrix-media-repo/defaults/main.yml | 30 +++++++++++++++++ .../templates/media-repo/media-repo.yaml.j2 | 33 +++++++++++++++++++ 4 files changed, 72 insertions(+), 2 deletions(-) diff --git a/docs/configuring-playbook-matrix-media-repo.md b/docs/configuring-playbook-matrix-media-repo.md index 713384c45..20a0aae0e 100644 --- a/docs/configuring-playbook-matrix-media-repo.md +++ b/docs/configuring-playbook-matrix-media-repo.md @@ -23,9 +23,11 @@ matrix_media_repo_enabled: true # matrix_media_repo_metrics_enabled: true ``` -The repo is pre-configured for integrating with the Postgres database, NGINX proxy and [Prometheus/Grafana](configuring-playbook-prometheus-grafana.md) (if metrics enabled) from this playbook for all the available homeserver roles. When the media repo is enabled, other media store roles should be disabled (if using Synapse with other media store roles). +The repo is pre-configured for integrating with the Postgres database, Traefik proxy and [Prometheus/Grafana](configuring-playbook-prometheus-grafana.md) (if metrics enabled) from this playbook for all the available homeserver roles. When the media repo is enabled, other media store roles should be disabled (if using Synapse with other media store roles). -By default, the media-repo will use the local filesystem for data storage. Additional options include `s3` and `IPFS` (experimental). Access token caching is also enabled by default since the logout endpoints are proxied through the media repo. +By default, the media-repo will use the local filesystem for data storage. You can alternatively use a `s3` cloud backend as well. Access token caching is also enabled by default since the logout endpoints are proxied through the media repo. + +**Note:** If you want to use authenticated media endpoints ([MSC3916](https://github.com/matrix-org/matrix-spec-proposals/pull/3916)), you must configure a signing key for your MMR instance to authorize outbound federation requests. See https://docs.t2bot.io/matrix-media-repo/v1.3.5/installation/signing-key/ for more details on how to configure your server with a signing key. ## Configuring the media-repo diff --git a/group_vars/matrix_servers b/group_vars/matrix_servers index 5dbe7bc83..a22e32de6 100755 --- a/group_vars/matrix_servers +++ b/group_vars/matrix_servers @@ -3650,6 +3650,11 @@ matrix_media_repo_homeservers_auto: # to "matrix", most functionality requiring the admin API will not work. adminApiKind: "{{ 'synapse' if matrix_homeserver_implementation == 'synapse' else ('dendrite' if matrix_homeserver_implementation == 'dendrite' else 'matrix') }}" + # The signing key to use for authorizing outbound federation requests. If not specified, + # requests will not be authorized. See https://docs.t2bot.io/matrix-media-repo/v1.3.5/installation/signing-key/ + # for details. + signingKeyPath: "" + matrix_media_repo_homeserver_federation_enabled: "{{ matrix_homeserver_federation_enabled }}" ###################################################################### diff --git a/roles/custom/matrix-media-repo/defaults/main.yml b/roles/custom/matrix-media-repo/defaults/main.yml index 1c5bfd665..8d903d11d 100755 --- a/roles/custom/matrix-media-repo/defaults/main.yml +++ b/roles/custom/matrix-media-repo/defaults/main.yml @@ -467,6 +467,11 @@ matrix_media_repo_datastore_s3_opts_bucket_name: "your-media-bucket" # before redirection if present). matrix_media_repo_datastore_s3_opts_redirect_when_cached: true +# The size of the prefix (path component) to use when storing media in S3. This can +# help improve download speeds in some S3 providers. Should not be set to higher than +# 16 to avoid future incompatibilities with MMR. Defaults to zero (no prefix). +matrix_media_repo_datastore_s3_opts_prefix_length: 0 + # Options for controlling archives. Archives are exports of a particular user's content for # the purpose of GDPR or moving media to a different server. @@ -742,6 +747,31 @@ matrix_media_repo_rate_limit_requests_per_second: 1 # The number of requests an IP can send at once before the rate limit is actually considered. matrix_media_repo_rate_limit_burst: 10 +# The 'leaky bucket' configurations for MMR. Leaky buckets are limited in size and have a slow +# drain rate, minimizing the ability for a user to consume large amounts of resources. +# +# Buckets are checked and applied after the requests per second configuration above. Buckets are +# disabled when rate limiting is disabled. +# +# Note: buckets are *not* shared across processes. If download requests could end up at two different +# processes, two different buckets may be filled. This behaviour may change in the future. + +# The download bucket applies to both download requests and thumbnail requests. Each anonymous +# user is assigned a single bucket from their IP address. Authenticated requests (when supported) +# will use the authenticated entity as the subject - either a user or remote server. + +# The maximum size of each bucket. +matrix_media_repo_rate_limit_buckets_download_capacity_bytes: 524288000 # 500mb default + +# The number of bytes to "drain" from the bucket every minute. +matrix_media_repo_rate_limit_buckets_download_drain_bytes_per_minute: 5242880 # 5mb default + +# The number of bytes a requester can go over the capacity, once. This is used to give some +# buffer to allow a single file to be downloaded when the caller is near the limit. This +# should be set to either your max remote download size or 30% of the capacityBytes, whichever +# is smaller. +matrix_media_repo_rate_limit_buckets_download_overflow_limit_bytes: 104857600 # 100mb default (the same as the default remote download maxBytes) + # Identicons are generated avatars for a given username. Some clients use these to give users a # default avatar after signing up. Identicons are not part of the official matrix spec, therefore # this feature is completely optional. diff --git a/roles/custom/matrix-media-repo/templates/media-repo/media-repo.yaml.j2 b/roles/custom/matrix-media-repo/templates/media-repo/media-repo.yaml.j2 index ee7d151b6..f8597f265 100644 --- a/roles/custom/matrix-media-repo/templates/media-repo/media-repo.yaml.j2 +++ b/roles/custom/matrix-media-repo/templates/media-repo/media-repo.yaml.j2 @@ -97,6 +97,11 @@ database: # # admin status. This should be set to one of "synapse", "dendrite", or "matrix". When set # # to "matrix", most functionality requiring the admin API will not work. # adminApiKind: "synapse" +# +# # The signing key to use for authorizing outbound federation requests. If not specified, +# # requests will not be authorized. See https://docs.t2bot.io/matrix-media-repo/v1.3.5/installation/signing-key/ +# # for details. +# #signingKeyPath: "/data/example.org.key" homeservers: {{ matrix_media_repo_homeservers | to_json | from_json | to_nice_yaml(indent=2, width=999999, sort_keys=false) | indent(width=2, first=true) }} @@ -253,6 +258,10 @@ datastores: # when `publicBaseUrl` is unset. Defaults to false (cached media will be served by MMR # before redirection if present). redirectWhenCached: {{ matrix_media_repo_datastore_s3_opts_redirect_when_cached | to_json }} + # The size of the prefix (path component) to use when storing media in S3. This can + # help improve download speeds in some S3 providers. Should not be set to higher than + # 16 to avoid future incompatibilities with MMR. Defaults to zero (no prefix). + prefixLength: {{ matrix_media_repo_datastore_s3_opts_prefix_length | to_json }} {% endif %} # Options for controlling archives. Archives are exports of a particular user's content for @@ -483,6 +492,30 @@ rateLimit: # The number of requests an IP can send at once before the rate limit is actually considered. burst: {{ matrix_media_repo_rate_limit_burst | to_json }} + # The 'leaky bucket' configurations for MMR. Leaky buckets are limited in size and have a slow + # drain rate, minimizing the ability for a user to consume large amounts of resources. + # + # Buckets are checked and applied after the requests per second configuration above. Buckets are + # disabled when rate limiting is disabled. + # + # Note: buckets are *not* shared across processes. If download requests could end up at two different + # processes, two different buckets may be filled. This behaviour may change in the future. + buckets: + # The download bucket applies to both download requests and thumbnail requests. Each anonymous + # user is assigned a single bucket from their IP address. Authenticated requests (when supported) + # will use the authenticated entity as the subject - either a user or remote server. + downloads: + # The maximum size of each bucket. + capacityBytes: {{ matrix_media_repo_rate_limit_buckets_download_capacity_bytes | to_json }} # 500mb default + # The number of bytes to "drain" from the bucket every minute. + drainBytesPerMinute: {{ matrix_media_repo_rate_limit_buckets_download_drain_bytes_per_minute | to_json }} # 5mb default + # The number of bytes a requester can go over the capacity, once. This is used to give some + # buffer to allow a single file to be downloaded when the caller is near the limit. This + # should be set to either your max remote download size or 30% of the capacityBytes, whichever + # is smaller. + overflowLimitBytes: {{ matrix_media_repo_rate_limit_buckets_download_overflow_limit_bytes | to_json }} # 100mb default (the same as the default remote download maxBytes) + + # Identicons are generated avatars for a given username. Some clients use these to give users a # default avatar after signing up. Identicons are not part of the official matrix spec, therefore # this feature is completely optional. From 90e3f4cba8a2c88ecf726dcfe7b31a77317b3fc2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 24 Jul 2024 13:11:41 +0000 Subject: [PATCH 06/18] chore(deps): update dependency grafana to v11.1.2-0 --- requirements.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.yml b/requirements.yml index 5930cf21f..9aebc0bd3 100644 --- a/requirements.yml +++ b/requirements.yml @@ -22,7 +22,7 @@ version: v4.98-r0-0-0 name: exim_relay - src: git+https://gitlab.com/etke.cc/roles/grafana.git - version: v11.1.0-0 + version: v11.1.2-0 name: grafana - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-jitsi.git version: v9584-1 From 57eeb1be332d0f73f882dc88179671aed86b67e7 Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Wed, 24 Jul 2024 21:49:26 +0300 Subject: [PATCH 07/18] Upgrade Cinny (v3.2.0 -> v4.0.0) and adapt our custom nginx configuration with the new URL rewrites Cinny includes nginx configuration which does URL rewrites now, as seen here: https://raw.githubusercontent.com/cinnyapp/cinny/dev/docker-nginx.conf That said, we have our own nginx configuration for Cinny, because we'd like to run ngin as non-root and on a non-privileged port (80 -> 8080). For this reason, we override `/etc/nginx/nginx.conf` and need to duplicate what we see in `/etc/nginx/conf.d/default.conf` with our own `server` block (which listens on port 8080). --- .../matrix-client-cinny/defaults/main.yml | 2 +- .../templates/nginx.conf.j2 | 20 +++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/roles/custom/matrix-client-cinny/defaults/main.yml b/roles/custom/matrix-client-cinny/defaults/main.yml index bd3da6166..9c829044d 100644 --- a/roles/custom/matrix-client-cinny/defaults/main.yml +++ b/roles/custom/matrix-client-cinny/defaults/main.yml @@ -7,7 +7,7 @@ matrix_client_cinny_container_image_self_build: false matrix_client_cinny_container_image_self_build_repo: "https://github.com/ajbura/cinny.git" # renovate: datasource=docker depName=ajbura/cinny -matrix_client_cinny_version: v3.2.0 +matrix_client_cinny_version: v4.0.0 matrix_client_cinny_docker_image: "{{ matrix_client_cinny_docker_image_name_prefix }}ajbura/cinny:{{ matrix_client_cinny_version }}" matrix_client_cinny_docker_image_name_prefix: "{{ 'localhost/' if matrix_client_cinny_container_image_self_build else matrix_container_global_registry_prefix }}" matrix_client_cinny_docker_image_force_pull: "{{ matrix_client_cinny_docker_image.endswith(':latest') }}" diff --git a/roles/custom/matrix-client-cinny/templates/nginx.conf.j2 b/roles/custom/matrix-client-cinny/templates/nginx.conf.j2 index fba16bbdc..3ae9cae7d 100644 --- a/roles/custom/matrix-client-cinny/templates/nginx.conf.j2 +++ b/roles/custom/matrix-client-cinny/templates/nginx.conf.j2 @@ -51,16 +51,20 @@ http { root /usr/share/nginx/html; location / { - index index.html index.htm; - } - - location ~* ^/(config(.+)?\.json$|(.+)\.html$|i18n) { - expires -1; - } + # Inspired by: https://raw.githubusercontent.com/cinnyapp/cinny/dev/docker-nginx.conf - error_page 500 502 503 504 /50x.html; - location = /50x.html { root /usr/share/nginx/html; + + rewrite ^/config.json$ /config.json break; + rewrite ^/manifest.json$ /manifest.json break; + + rewrite ^.*/olm.wasm$ /olm.wasm break; + rewrite ^/pdf.worker.min.js$ /pdf.worker.min.js break; + + rewrite ^/public/(.*)$ /public/$1 break; + rewrite ^/assets/(.*)$ /assets/$1 break; + + rewrite ^(.+)$ /index.html break; } } } From e29b5323df130bce9969d6b637798f15b3a68f22 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Jul 2024 11:31:33 +0000 Subject: [PATCH 08/18] chore(deps): update ajbura/cinny docker tag to v4.0.3 --- roles/custom/matrix-client-cinny/defaults/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/custom/matrix-client-cinny/defaults/main.yml b/roles/custom/matrix-client-cinny/defaults/main.yml index 9c829044d..fb2db9fe2 100644 --- a/roles/custom/matrix-client-cinny/defaults/main.yml +++ b/roles/custom/matrix-client-cinny/defaults/main.yml @@ -7,7 +7,7 @@ matrix_client_cinny_container_image_self_build: false matrix_client_cinny_container_image_self_build_repo: "https://github.com/ajbura/cinny.git" # renovate: datasource=docker depName=ajbura/cinny -matrix_client_cinny_version: v4.0.0 +matrix_client_cinny_version: v4.0.3 matrix_client_cinny_docker_image: "{{ matrix_client_cinny_docker_image_name_prefix }}ajbura/cinny:{{ matrix_client_cinny_version }}" matrix_client_cinny_docker_image_name_prefix: "{{ 'localhost/' if matrix_client_cinny_container_image_self_build else matrix_container_global_registry_prefix }}" matrix_client_cinny_docker_image_force_pull: "{{ matrix_client_cinny_docker_image.endswith(':latest') }}" From 55f869254b81cad0804a34f68827bfb3e1de6a12 Mon Sep 17 00:00:00 2001 From: Michael Hollister Date: Thu, 25 Jul 2024 12:19:08 -0500 Subject: [PATCH 09/18] Created role for synapse-usage-exporter (#3442) * Created role for synapse-usage-exporter * Apply suggestions from code review Co-authored-by: Slavi Pantaleev * Renaming docker variables and moving synapse stats config location * Respect devture_systemd_docker_base_docker_service_name --------- Co-authored-by: Slavi Pantaleev --- README.md | 1 + ...iguring-playbook-synapse-usage-exporter.md | 25 + group_vars/matrix_servers | 37 + .../defaults/main.yml | 20 + .../defaults/main.yml | 76 + .../tasks/main.yml | 17 + .../tasks/setup_install.yml | 77 + .../tasks/setup_uninstall.yml | 24 + .../templates/env.j2 | 3 + .../grafana/synapse-usage-exporter.json | 2746 +++++++++++++++++ .../templates/labels.j2 | 38 + .../matrix-synapse-usage-exporter.service.j2 | 47 + roles/custom/matrix-synapse/defaults/main.yml | 3 + .../templates/synapse/homeserver.yaml.j2 | 1 + setup.yml | 1 + 15 files changed, 3116 insertions(+) create mode 100644 docs/configuring-playbook-synapse-usage-exporter.md create mode 100644 roles/custom/matrix-synapse-usage-exporter/defaults/main.yml create mode 100644 roles/custom/matrix-synapse-usage-exporter/tasks/main.yml create mode 100644 roles/custom/matrix-synapse-usage-exporter/tasks/setup_install.yml create mode 100644 roles/custom/matrix-synapse-usage-exporter/tasks/setup_uninstall.yml create mode 100644 roles/custom/matrix-synapse-usage-exporter/templates/env.j2 create mode 100644 roles/custom/matrix-synapse-usage-exporter/templates/grafana/synapse-usage-exporter.json create mode 100755 roles/custom/matrix-synapse-usage-exporter/templates/labels.j2 create mode 100644 roles/custom/matrix-synapse-usage-exporter/templates/systemd/matrix-synapse-usage-exporter.service.j2 diff --git a/README.md b/README.md index 880d9e772..499419fa6 100644 --- a/README.md +++ b/README.md @@ -157,6 +157,7 @@ Services that help you in administrating and monitoring your matrix installation | Metrics and Graphs | x | Consists of the [Prometheus](https://prometheus.io) time-series database server, the Prometheus [node-exporter](https://prometheus.io/docs/guides/node-exporter/) host metrics exporter, and the [Grafana](https://grafana.com/) web UI | [Link](docs/configuring-playbook-prometheus-grafana.md) | | [Borg](https://borgbackup.org) | x | Backups | [Link](docs/configuring-playbook-backup-borg.md) | | [Rageshake](https://github.com/matrix-org/rageshake) | x | Bug report server | [Link](docs/configuring-playbook-rageshake.md) | +| [synapse-usage-exporter](https://github.com/loelkes/synapse-usage-exporter) | x | Export the usage statistics of a Synapse homeserver to be scraped by Prometheus. | [Link](docs/configuring-playbook-synapse-usage-exporter.md) | ### Misc diff --git a/docs/configuring-playbook-synapse-usage-exporter.md b/docs/configuring-playbook-synapse-usage-exporter.md new file mode 100644 index 000000000..9f962a7c5 --- /dev/null +++ b/docs/configuring-playbook-synapse-usage-exporter.md @@ -0,0 +1,25 @@ +# Setting up synapse-usage-exporter (optional) + +[synapse-usage-exporter](https://github.com/loelkes/synapse-usage-exporter) allows you to export the usage statistics of a Synapse homeserver to this container service and for the collected metrics to later be scraped by Prometheus. + +Synapse does not include usage statistics in its Prometheus metrics. They can be reported to an HTTP `PUT` endpoint 5 minutes after startup and from then on at a fixed interval of once every three hours. This role integrates a simple [Flask](https://flask.palletsprojects.com) project that offers an HTTP `PUT` endpoint and holds the most recent received record available to be scraped by Prometheus. + +Enabling this service will automatically: + +- install the synapse-usage-exporter service +- re-configure Synapse to push (via HTTP `PUT`) usage statistics information to synapse-usage-exporter +- re-configure [Prometheus](./configuring-playbook-prometheus-grafana.md) (if Grafana is enabled), to periodically scrape metrics from synapse-usage-exporter +- add a new [Grafana](./configuring-playbook-prometheus-grafana.md) dashboard (if Grafana is enabled) containing Synapse usage statistics + +## Quickstart + +Add the following configuration to your `inventory/host_vars/matrix.DOMAIN/vars.yml` file and [re-run the installation process](./installing.md) for the playbook: + +```yaml +matrix_synapse_usage_exporter_enabled: true + +# (Optional) Expose endpoint if you want to collect statistics from outside (from other homeservers). +# If enabled, synapse-usage-exporter will be exposed publicly at `matrix.DOMAIN/report-usage-stats/push`. +# When collecting usage statistics for Synapse running on the same host, you don't need to enable this. +# matrix_synapse_usage_exporter_proxying_enabled: true +``` diff --git a/group_vars/matrix_servers b/group_vars/matrix_servers index a22e32de6..46b9ef5b1 100755 --- a/group_vars/matrix_servers +++ b/group_vars/matrix_servers @@ -441,6 +441,8 @@ devture_systemd_service_manager_services_list_auto: | + ([{'name': 'matrix-synapse-admin.service', 'priority': 4000, 'groups': ['matrix', 'synapse-admin']}] if matrix_synapse_admin_enabled else []) + + ([{'name': (matrix_synapse_usage_exporter_identifier + '.service'), 'priority': 4000, 'groups': ['matrix', 'synapse-usage-exporter']}] if matrix_synapse_usage_exporter_enabled else []) + + ([{'name': 'matrix-synapse-reverse-proxy-companion.service', 'priority': 1500, 'groups': ['matrix', 'homeservers', 'synapse', 'synapse-reverse-proxy-companion', 'reverse-proxies']}] if matrix_synapse_reverse_proxy_companion_enabled else []) + ([{'name': 'matrix-user-verification-service.service', 'priority': 800, 'groups': ['matrix', 'matrix-user-verification-service']}] if matrix_user_verification_service_enabled else []) @@ -4465,6 +4467,10 @@ matrix_synapse_app_service_config_files_auto: "{{ matrix_homeserver_app_service_ # Disable creation of media repository Synapse worker when using media-repo matrix_synapse_ext_media_repo_enabled: "{{ matrix_media_repo_enabled }}" +# Enable Synapse statistics reporting when using synapse-usage-exporter +matrix_synapse_report_stats: "{{ matrix_synapse_usage_exporter_enabled }}" +matrix_synapse_report_stats_endpoint: "http://{{ matrix_synapse_usage_exporter_identifier }}:{{ matrix_synapse_usage_exporter_container_port | string }}/report-usage-stats/push" + ###################################################################### # # /matrix-synapse @@ -4597,6 +4603,28 @@ matrix_synapse_admin_container_labels_traefik_tls_certResolver: "{{ devture_trae # ###################################################################### +###################################################################### +# +# matrix-synapse-usage-exporter +# +###################################################################### + +matrix_synapse_usage_exporter_enabled: false + +matrix_synapse_usage_exporter_container_network: "{{ matrix_monitoring_container_network }}" + +matrix_synapse_usage_exporter_container_additional_networks: "{{ [matrix_playbook_reverse_proxyable_services_additional_network] if matrix_playbook_reverse_proxyable_services_additional_network else [] }}" + +matrix_synapse_usage_exporter_container_labels_traefik_enabled: "{{ matrix_synapse_usage_exporter_proxying_enabled }}" +matrix_synapse_usage_exporter_container_labels_traefik_docker_network: "{{ matrix_playbook_reverse_proxyable_services_additional_network }}" +matrix_synapse_usage_exporter_container_labels_traefik_entrypoints: "{{ devture_traefik_entrypoint_primary }}" +matrix_synapse_usage_exporter_container_labels_traefik_tls_certResolver: "{{ devture_traefik_certResolver_primary }}" + +###################################################################### +# +# /matrix-synapse-usage-exporter +# +###################################################################### ###################################################################### # @@ -4755,6 +4783,8 @@ prometheus_container_additional_networks_auto: | ([matrix_prometheus_nginxlog_exporter_container_network] if matrix_prometheus_services_connect_scraper_nginxlog_enabled and matrix_prometheus_nginxlog_exporter_container_network != prometheus_container_network else []) + ([matrix_media_repo_container_network] if matrix_prometheus_services_connect_scraper_media_repo_enabled and matrix_media_repo_container_network != prometheus_container_network else []) + + + ([matrix_synapse_usage_exporter_container_network] if matrix_prometheus_services_connect_scraper_synapse_usage_exporter_enabled and matrix_synapse_usage_exporter_container_network != prometheus_container_network else []) ) | unique }} @@ -4779,6 +4809,8 @@ prometheus_config_scrape_configs_auto: | (matrix_prometheus_services_connect_scraper_nginxlog_scrape_configs if matrix_prometheus_services_connect_scraper_nginxlog_enabled else []) + (matrix_prometheus_services_connect_scraper_media_repo_scrape_configs if matrix_prometheus_services_connect_scraper_media_repo_enabled else []) + + + (matrix_prometheus_services_connect_scraper_synapse_usage_exporter_scrape_configs if matrix_prometheus_services_connect_scraper_synapse_usage_exporter_enabled else []) }} ###################################################################### @@ -4817,6 +4849,9 @@ matrix_prometheus_services_connect_scraper_nginxlog_static_configs_target: "{{ m matrix_prometheus_services_connect_scraper_media_repo_enabled: "{{ matrix_media_repo_enabled and matrix_media_repo_metrics_enabled }}" matrix_prometheus_services_connect_scraper_media_repo_static_configs_target: "{{ matrix_media_repo_identifier }}:{{ matrix_media_repo_metrics_port }}" +matrix_prometheus_services_connect_scraper_synapse_usage_exporter_enabled: "{{ matrix_synapse_usage_exporter_enabled }}" +matrix_prometheus_services_connect_scraper_synapse_usage_exporter_static_configs_target: "{{ matrix_synapse_usage_exporter_identifier }}:{{ matrix_synapse_usage_exporter_container_port | string }}" + ###################################################################### # # /matrix-prometheus-services-connect @@ -4883,6 +4918,8 @@ grafana_dashboard_download_urls: | (matrix_prometheus_nginxlog_exporter_dashboard_urls if matrix_prometheus_nginxlog_exporter_enabled else []) + (matrix_media_repo_dashboard_urls if matrix_media_repo_metrics_enabled else []) + + + (matrix_synapse_usage_exporter_dashboard_urls if matrix_synapse_usage_exporter_enabled else []) }} grafana_provisioning_dashboard_template_files: | diff --git a/roles/custom/matrix-prometheus-services-connect/defaults/main.yml b/roles/custom/matrix-prometheus-services-connect/defaults/main.yml index 62fb40c4b..f9d12e7f4 100644 --- a/roles/custom/matrix-prometheus-services-connect/defaults/main.yml +++ b/roles/custom/matrix-prometheus-services-connect/defaults/main.yml @@ -162,3 +162,23 @@ matrix_prometheus_services_connect_scraper_media_repo_scrape_configs: | 'static_configs': matrix_prometheus_services_connect_scraper_media_repo_static_configs, }] }} + +# Controls whether synapse-usage-exporter shall be scraped +matrix_prometheus_services_connect_scraper_synapse_usage_exporter_enabled: false +matrix_prometheus_services_connect_scraper_synapse_usage_exporter_job_name: synapse-usage-exporter +matrix_prometheus_services_connect_scraper_synapse_usage_exporter_metrics_path: /metrics +matrix_prometheus_services_connect_scraper_synapse_usage_exporter_scrape_interval: 300s +matrix_prometheus_services_connect_scraper_synapse_usage_exporter_scrape_timeout: 300s +matrix_prometheus_services_connect_scraper_synapse_usage_exporter_static_configs: "{{ [{'targets': [matrix_prometheus_services_connect_scraper_synapse_usage_exporter_static_configs_target]}] }}" +matrix_prometheus_services_connect_scraper_synapse_usage_exporter_static_configs_target: '' +# The final scrape config for the synapse-usage-exporter scraper +matrix_prometheus_services_connect_scraper_synapse_usage_exporter_scrape_configs: | + {{ + [{ + 'job_name': matrix_prometheus_services_connect_scraper_synapse_usage_exporter_job_name, + 'metrics_path': matrix_prometheus_services_connect_scraper_synapse_usage_exporter_metrics_path, + 'scrape_interval': matrix_prometheus_services_connect_scraper_synapse_usage_exporter_scrape_interval, + 'scrape_timeout': matrix_prometheus_services_connect_scraper_synapse_usage_exporter_scrape_timeout, + 'static_configs': matrix_prometheus_services_connect_scraper_synapse_usage_exporter_static_configs, + }] + }} diff --git a/roles/custom/matrix-synapse-usage-exporter/defaults/main.yml b/roles/custom/matrix-synapse-usage-exporter/defaults/main.yml new file mode 100644 index 000000000..991218645 --- /dev/null +++ b/roles/custom/matrix-synapse-usage-exporter/defaults/main.yml @@ -0,0 +1,76 @@ +--- + +# Synapse Usage Exporter +# Project source code URL: https://github.com/loelkes/synapse-usage-exporter + +matrix_synapse_usage_exporter_enabled: false + +# matrix_synapse_usage_exporter_identifier controls the identifier of this synapse-usage-exporter instance, which influences: +# - the default storage path +# - the names of systemd services and containers +matrix_synapse_usage_exporter_identifier: matrix-synapse-usage-exporter +matrix_synapse_usage_exporter_container_port: 5000 + +# No docker images are currently hosted for the repo, so defaulting to true +matrix_synapse_usage_exporter_container_image_self_build: true +matrix_synapse_usage_exporter_container_image_self_build_repo: "https://github.com/loelkes/synapse-usage-exporter.git" + +matrix_synapse_usage_exporter_container_image_path: "loelkes/synapse-usage-exporter" +matrix_synapse_usage_exporter_container_image: "{{ matrix_synapse_usage_exporter_container_image_name_prefix }}{{ matrix_synapse_usage_exporter_container_image_path }}:{{ matrix_synapse_usage_exporter_container_image_tag }}" +matrix_synapse_usage_exporter_container_image_name_prefix: "{{ 'localhost/' if matrix_synapse_usage_exporter_container_image_self_build else matrix_container_global_registry_prefix }}" +matrix_synapse_usage_exporter_container_image_tag: "{{ 'main' if matrix_synapse_usage_exporter_container_image_self_build else 'latest' }}" +matrix_synapse_usage_exporter_container_image_force_pull: "{{ matrix_synapse_usage_exporter_container_image.endswith(':latest') }}" + +matrix_synapse_usage_exporter_base_path: "{{ matrix_base_data_path }}/{{ matrix_synapse_usage_exporter_identifier }}" +matrix_synapse_usage_exporter_docker_src_files_path: "{{ matrix_synapse_usage_exporter_base_path }}/docker-src" + +# List of systemd services that synapse-usage-exporter.service depends on +matrix_synapse_usage_exporter_systemd_required_services_list: "{{ matrix_synapse_usage_exporter_systemd_required_services_list_default + matrix_synapse_usage_exporter_systemd_required_services_list_auto + matrix_synapse_usage_exporter_systemd_required_services_list_custom }}" +matrix_synapse_usage_exporter_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_synapse_usage_exporter_systemd_required_services_list_auto: [] +matrix_synapse_usage_exporter_systemd_required_services_list_custom: [] + +# List of systemd services that synapse-usage-exporter.service wants +matrix_synapse_usage_exporter_systemd_wanted_services_list: [] + +# The base container network. It will be auto-created by this role if it doesn't exist already. +matrix_synapse_usage_exporter_container_network: "{{ matrix_synapse_usage_exporter_identifier }}" + +# A list of additional container networks that the container would be connected to. +# The role does not create these networks, so make sure they already exist. +# Use this to expose this container to another reverse proxy, which runs in a different container network. +matrix_synapse_usage_exporter_container_additional_networks: [] + +# Extra arguments for the Docker container +matrix_synapse_usage_exporter_container_extra_arguments: [] + +# Controls whether the synapse usage exporter should be proxied (exposed) on `matrix.DOMAIN/report-usage-stats/push` +matrix_synapse_usage_exporter_proxying_enabled: false + +# matrix_synapse_usage_exporter_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. +# See `../templates/labels.j2` for details. +# +# To inject your own other container labels, see `matrix_synapse_usage_exporter_container_labels_additional_labels`. +matrix_synapse_usage_exporter_container_labels_traefik_enabled: "{{ matrix_synapse_usage_exporter_proxying_enabled }}" +matrix_synapse_usage_exporter_container_labels_traefik_docker_network: "{{ matrix_synapse_usage_exporter_container_network }}" + +matrix_synapse_usage_exporter_container_labels_traefik_path_prefix: "/report-usage-stats/push" +matrix_synapse_usage_exporter_container_labels_traefik_rule: "Host(`{{ matrix_server_fqn_matrix }}`) && PathPrefix(`{{ matrix_synapse_usage_exporter_container_labels_traefik_path_prefix | quote }}`)" +matrix_synapse_usage_exporter_container_labels_traefik_priority: 0 +matrix_synapse_usage_exporter_container_labels_traefik_entrypoints: "web-secure" +matrix_synapse_usage_exporter_container_labels_traefik_tls: "{{ matrix_synapse_usage_exporter_container_labels_traefik_entrypoints != 'web' }}" +matrix_synapse_usage_exporter_container_labels_traefik_tls_certResolver: default # noqa var-naming + +# matrix_synapse_usage_exporter_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. +# See `../templates/labels.j2` for details. +# +# Example: +# matrix_synapse_usage_exporter_container_labels_additional_labels: | +# my.label=1 +# another.label="here" +matrix_synapse_usage_exporter_container_labels_additional_labels: '' + +# matrix_synapse_usage_exporter_dashboard_urls contains a list of URLs with Grafana dashboard definitions. +# If the Grafana role is enabled, these dashboards will be downloaded. +matrix_synapse_usage_exporter_dashboard_urls: + - https://raw.githubusercontent.com/spantaleev/matrix-docker-ansible-deploy/master/roles/custom/matrix-synapse-usage-exporter/templates/grafana/synapse-usage-exporter.json diff --git a/roles/custom/matrix-synapse-usage-exporter/tasks/main.yml b/roles/custom/matrix-synapse-usage-exporter/tasks/main.yml new file mode 100644 index 000000000..0ac9c1f50 --- /dev/null +++ b/roles/custom/matrix-synapse-usage-exporter/tasks/main.yml @@ -0,0 +1,17 @@ +--- + +- tags: + - setup-all + - setup-synapse-usage-exporter + - install-all + - install-synapse-usage-exporter + block: + - when: matrix_synapse_usage_exporter_enabled | bool + ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" + +- tags: + - setup-all + - setup-synapse-usage-exporter + block: + - when: not matrix_synapse_usage_exporter_enabled | bool + ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" diff --git a/roles/custom/matrix-synapse-usage-exporter/tasks/setup_install.yml b/roles/custom/matrix-synapse-usage-exporter/tasks/setup_install.yml new file mode 100644 index 000000000..06945a56e --- /dev/null +++ b/roles/custom/matrix-synapse-usage-exporter/tasks/setup_install.yml @@ -0,0 +1,77 @@ +--- + +- name: Ensure synapse-usage-exporter paths exist + ansible.builtin.file: + path: "{{ item.path }}" + state: directory + mode: 0750 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" + with_items: + - path: "{{ matrix_synapse_usage_exporter_base_path }}" + when: true + - path: "{{ matrix_synapse_usage_exporter_docker_src_files_path }}" + when: "{{ matrix_synapse_usage_exporter_container_image_self_build }}" + when: "item.when | bool" + +- name: Ensure synapse-usage-exporter support files installed + ansible.builtin.template: + src: "{{ role_path }}/templates/{{ item }}.j2" + dest: "{{ matrix_synapse_usage_exporter_base_path }}/{{ item }}" + mode: 0640 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" + with_items: + - env + - labels + +- name: Ensure synapse-usage-exporter Docker image is pulled + community.docker.docker_image: + name: "{{ matrix_synapse_usage_exporter_container_image }}" + source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" + force_source: "{{ matrix_synapse_usage_exporter_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" + force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_synapse_usage_exporter_container_image_force_pull }}" + when: "not matrix_synapse_usage_exporter_container_image_self_build | bool" + register: result + retries: "{{ devture_playbook_help_container_retries_count }}" + delay: "{{ devture_playbook_help_container_retries_delay }}" + until: result is not failed + +- when: "matrix_synapse_usage_exporter_container_image_self_build | bool" + block: + - name: Ensure synapse-usage-exporter repository is present on self-build + ansible.builtin.git: + repo: "{{ matrix_synapse_usage_exporter_container_image_self_build_repo }}" + dest: "{{ matrix_synapse_usage_exporter_docker_src_files_path }}" + version: "{{ matrix_synapse_usage_exporter_container_image.split(':')[1] }}" + force: "yes" + become: true + become_user: "{{ matrix_user_username }}" + register: matrix_synapse_usage_exporter_git_pull_results + + - name: Check if synapse-usage-exporter Docker image exists + ansible.builtin.command: "{{ devture_systemd_docker_base_host_command_docker }} images --quiet --filter 'reference={{ matrix_synapse_usage_exporter_container_image }}'" + register: matrix_synapse_usage_exporter_container_image_check_result + changed_when: false + + # Invoking the `docker build` command here, instead of calling the `docker_image` Ansible module, + # because the latter does not support BuildKit. + # See: https://github.com/ansible-collections/community.general/issues/514 + - name: Ensure synapse-usage-exporter Docker image is built + ansible.builtin.command: + cmd: "{{ devture_systemd_docker_base_host_command_docker }} build -t {{ matrix_synapse_usage_exporter_container_image }} -f {{ matrix_synapse_usage_exporter_docker_src_files_path }}/docker/Dockerfile {{ matrix_synapse_usage_exporter_docker_src_files_path }}" + environment: + DOCKER_BUILDKIT: 1 + changed_when: true + when: "matrix_synapse_usage_exporter_git_pull_results.changed | bool or matrix_synapse_usage_exporter_container_image_check_result.stdout == ''" + +- name: Ensure synapse-usage-exporter container network is created + community.general.docker_network: + name: "{{ matrix_synapse_usage_exporter_container_network }}" + driver: bridge + +- name: Ensure synapse-usage-exporter service installed + ansible.builtin.template: + src: "{{ role_path }}/templates/systemd/matrix-synapse-usage-exporter.service.j2" + dest: "{{ devture_systemd_docker_base_systemd_path }}/{{ matrix_synapse_usage_exporter_identifier }}.service" + mode: 0640 diff --git a/roles/custom/matrix-synapse-usage-exporter/tasks/setup_uninstall.yml b/roles/custom/matrix-synapse-usage-exporter/tasks/setup_uninstall.yml new file mode 100644 index 000000000..1b1492bb4 --- /dev/null +++ b/roles/custom/matrix-synapse-usage-exporter/tasks/setup_uninstall.yml @@ -0,0 +1,24 @@ +--- + +- name: Check existence of synapse-usage-exporter service + ansible.builtin.stat: + path: "{{ devture_systemd_docker_base_systemd_path }}/{{ matrix_synapse_usage_exporter_identifier }}.service" + register: matrix_synapse_usage_exporter_service_stat + +- when: matrix_synapse_usage_exporter_service_stat.stat.exists | bool + block: + - name: Ensure synapse-usage-exporter is stopped + ansible.builtin.systemd: + name: "{{ matrix_synapse_usage_exporter_identifier }}" + state: stopped + daemon_reload: true + + - name: Ensure synapse-usage-exporter service doesn't exist + ansible.builtin.file: + path: "{{ devture_systemd_docker_base_systemd_path }}/{{ matrix_synapse_usage_exporter_identifier }}.service" + state: absent + + - name: Ensure synapse-usage-exporter files deleted + ansible.builtin.file: + path: "{{ matrix_synapse_usage_exporter_base_path }}" + state: absent diff --git a/roles/custom/matrix-synapse-usage-exporter/templates/env.j2 b/roles/custom/matrix-synapse-usage-exporter/templates/env.j2 new file mode 100644 index 000000000..e3f1e814d --- /dev/null +++ b/roles/custom/matrix-synapse-usage-exporter/templates/env.j2 @@ -0,0 +1,3 @@ +PROMETHEUS_MULTIPROC_DIR=/tmp/prometheus +WERKZEUG_LOG_LEVEL=INFO +APP_LOG_LEVEL=INFO diff --git a/roles/custom/matrix-synapse-usage-exporter/templates/grafana/synapse-usage-exporter.json b/roles/custom/matrix-synapse-usage-exporter/templates/grafana/synapse-usage-exporter.json new file mode 100644 index 000000000..23226919d --- /dev/null +++ b/roles/custom/matrix-synapse-usage-exporter/templates/grafana/synapse-usage-exporter.json @@ -0,0 +1,2746 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "${DS_PROMETHEUS}" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 4, + "links": [], + "liveNow": false, + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 11, + "panels": [], + "title": "General", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The memory usage of the process (in kilobytes on Unix-based systems, bytes on MacOS)", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": 21600000, + "lineInterpolation": "linear", + "lineStyle": { + "fill": "solid" + }, + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "deckbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 1 + }, + "id": 8, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "synapse_usage_memory_rss{homeserver=~\"$homeserver\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{homeserver}}", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Memory Usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "CPU time in % of a single core (not % of all cores)", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": 21600000, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 1 + }, + "id": 12, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "synapse_usage_cpu_average{homeserver=~\"$homeserver\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{homeserver}}", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "CPU Average Utilization (Single Core)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The current time, represented as the number of seconds since the epoch", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 9 + }, + "id": 13, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.4.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "synapse_usage_timestamp{homeserver=~\"$homeserver\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{homeserver}}", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Time Since Epoch ", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The number of seconds since the homeserver was last started", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 9 + }, + "id": 14, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.4.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "synapse_usage_uptime_seconds{homeserver=~\"$homeserver\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{homeserver}}", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Uptime", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The number of registered users on the homeserver", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": 21600000, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 17 + }, + "id": 17, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "10.4.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "synapse_usage_total_users{homeserver=~\"$homeserver\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{homeserver}}", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sum(synapse_usage_total_users{homeserver=~\"$homeserver\"})", + "fullMetaSearch": false, + "hide": true, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Total", + "range": true, + "refId": "B", + "useBackend": false + } + ], + "title": "Total Users", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The number of users, excluding those created by an Application Service", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": 21600000, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 17 + }, + "id": 18, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "synapse_usage_total_nonbridged_users{homeserver=~\"$homeserver\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{homeserver}}", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sum(synapse_usage_total_nonbridged_users{homeserver=~\"$homeserver\"})", + "fullMetaSearch": false, + "hide": true, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Total", + "range": true, + "refId": "B", + "useBackend": false + } + ], + "title": "Total Non-bridged Users", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The total number of rooms present on the homeserver", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": 21600000, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 25 + }, + "id": 19, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "synapse_usage_total_room_count{homeserver=~\"$homeserver\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{homeserver}}", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sum(synapse_usage_total_room_count{homeserver=~\"$homeserver\"})", + "fullMetaSearch": false, + "hide": true, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Total", + "range": true, + "refId": "B", + "useBackend": false + } + ], + "title": "Total Rooms", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The configured global factor value for caching", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 25 + }, + "id": 15, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.4.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "synapse_usage_cache_factor{homeserver=~\"$homeserver\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{homeserver}}", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Cache Factor", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The configured event_cache_size value for caching", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 33 + }, + "id": 16, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.4.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "synapse_usage_event_cache_size{homeserver=~\"$homeserver\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{homeserver}}", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Event Cache Size", + "type": "stat" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 41 + }, + "id": 10, + "panels": [], + "title": "Daily", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The number of native users created in the last 24 hours", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": 21600000, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 42 + }, + "id": 20, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "synapse_usage_daily_user_type_native{homeserver=~\"$homeserver\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{homeserver}}", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sum(synapse_usage_daily_user_type_native{homeserver=~\"$homeserver\"})", + "fullMetaSearch": false, + "hide": true, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Total", + "range": true, + "refId": "B", + "useBackend": false + } + ], + "title": "Daily Registered Users", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The number of guest users created in the last 24 hours", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": 21600000, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 42 + }, + "id": 21, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "synapse_usage_daily_user_type_guest{homeserver=~\"$homeserver\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{homeserver}}", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sum(synapse_usage_daily_user_type_guest{homeserver=~\"$homeserver\"})", + "fullMetaSearch": false, + "hide": true, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Total", + "range": true, + "refId": "B", + "useBackend": false + } + ], + "title": "Daily Registered Guest Users", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The number of users created by Application Services in the last 24 hours", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": 21600000, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 50 + }, + "id": 22, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "synapse_usage_daily_user_type_bridged{homeserver=~\"$homeserver\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{homeserver}}", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sum(synapse_usage_daily_user_type_bridged{homeserver=~\"$homeserver\"})", + "fullMetaSearch": false, + "hide": true, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Total", + "range": true, + "refId": "B", + "useBackend": false + } + ], + "title": "Daily Registered Bridged Users", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The number of unique users that have used the homeserver in the last 24 hours", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": 21600000, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 50 + }, + "id": 23, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "synapse_usage_daily_active_users{homeserver=~\"$homeserver\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{homeserver}}", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sum(synapse_usage_daily_active_users{homeserver=~\"$homeserver\"})", + "fullMetaSearch": false, + "hide": true, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Total", + "range": true, + "refId": "B", + "useBackend": false + } + ], + "title": "Daily Active Users", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The number of rooms that have had a (state) event with the type m.room.message sent in them in the last 24 hours", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": 21600000, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 58 + }, + "id": 25, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "synapse_usage_daily_active_rooms{homeserver=~\"$homeserver\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{homeserver}}", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sum(synapse_usage_daily_active_rooms{homeserver=~\"$homeserver\"})", + "fullMetaSearch": false, + "hide": true, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Total", + "range": true, + "refId": "B", + "useBackend": false + } + ], + "title": "Daily Active Rooms", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The number of rooms that have had a (state) event with the type m.room.encrypted sent in them in the last 24 hours", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": 21600000, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 58 + }, + "id": 26, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "synapse_usage_daily_active_e2ee_rooms{homeserver=~\"$homeserver\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{homeserver}}", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sum(synapse_usage_daily_active_e2ee_rooms{homeserver=~\"$homeserver\"})", + "fullMetaSearch": false, + "hide": true, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Total", + "range": true, + "refId": "B", + "useBackend": false + } + ], + "title": "Daily Active E2EE Rooms", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The number of (state) events with the type m.room.message seen in the last 24 hours", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": 21600000, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 66 + }, + "id": 27, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "synapse_usage_daily_messages{homeserver=~\"$homeserver\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{homeserver}}", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sum(synapse_usage_daily_messages{homeserver=~\"$homeserver\"})", + "fullMetaSearch": false, + "hide": true, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Total", + "range": true, + "refId": "B", + "useBackend": false + } + ], + "title": "Daily Messages", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The number of (state) events sent by a local user with the type m.room.encrypted seen in the last 24 hours", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": 21600000, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 66 + }, + "id": 28, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "synapse_usage_daily_e2ee_messages{homeserver=~\"$homeserver\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{homeserver}}", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sum(synapse_usage_daily_e2ee_messages{homeserver=~\"$homeserver\"})", + "fullMetaSearch": false, + "hide": true, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Total", + "range": true, + "refId": "B", + "useBackend": false + } + ], + "title": "Daily E2EE Messages", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The number of (state) events sent by a local user with the type m.room.message seen in the last 24 hours", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": 21600000, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 74 + }, + "id": 29, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "synapse_usage_daily_sent_messages{homeserver=~\"$homeserver\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{homeserver}}", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sum(synapse_usage_daily_sent_messages{homeserver=~\"$homeserver\"})", + "fullMetaSearch": false, + "hide": true, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Total", + "range": true, + "refId": "B", + "useBackend": false + } + ], + "title": "Daily Sent Messages", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The number of (state) events sent by a local user with the type m.room.encrypted seen in the last 24 hours", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": 21600000, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 74 + }, + "id": 30, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "synapse_usage_daily_sent_e2ee_messages{homeserver=~\"$homeserver\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{homeserver}}", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sum(synapse_usage_daily_sent_e2ee_messages{homeserver=~\"$homeserver\"})", + "fullMetaSearch": false, + "hide": true, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Total", + "range": true, + "refId": "B", + "useBackend": false + } + ], + "title": "Daily Sent E2EE Messages", + "type": "timeseries" + }, + { + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 82 + }, + "id": 9, + "title": "Monthly", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The number of unique users that have used the homeserver in the last 30 days", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": 21600000, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 83 + }, + "id": 24, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "synapse_usage_monthly_active_users{homeserver=~\"$homeserver\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{homeserver}}", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sum(synapse_usage_monthly_active_users{homeserver=~\"$homeserver\"})", + "fullMetaSearch": false, + "hide": true, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Total", + "range": true, + "refId": "B", + "useBackend": false + } + ], + "title": "Monthly Active Users", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The number of 30 day retained users, with a revised algorithm. Defined as users that appear more than once in the past 60 days, and have more than 30 days between the most and least recent appearances in the past 60 days. Includes clients that do not fit into the below r30 client types", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": 21600000, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 83 + }, + "id": 31, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "synapse_usage_r30v2_users_all{homeserver=~\"$homeserver\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{homeserver}}", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sum(synapse_usage_r30v2_users_all{homeserver=~\"$homeserver\"})", + "fullMetaSearch": false, + "hide": true, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Total", + "range": true, + "refId": "B", + "useBackend": false + } + ], + "title": "Monthly Retained Users", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The number of 30 day retained users, as defined above. Filtered only to clients with (\"riot\" or \"element\") and \"android\" (case-insensitive) in the user agent string", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": 21600000, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 91 + }, + "id": 32, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "synapse_usage_r30v2_users_android{homeserver=~\"$homeserver\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{homeserver}}", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sum(synapse_usage_r30v2_users_android{homeserver=~\"$homeserver\"})", + "fullMetaSearch": false, + "hide": true, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Total", + "range": true, + "refId": "B", + "useBackend": false + } + ], + "title": "Monthly Retained Android Users", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The number of 30 day retained users, as defined above. Filtered only to clients with (\"riot\" or \"element\") and \"ios\" (case-insensitive) in the user agent string", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": 21600000, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 91 + }, + "id": 33, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "synapse_usage_r30v2_users_ios{homeserver=~\"$homeserver\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{homeserver}}", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sum(synapse_usage_r30v2_users_ios{homeserver=~\"$homeserver\"})", + "fullMetaSearch": false, + "hide": true, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Total", + "range": true, + "refId": "B", + "useBackend": false + } + ], + "title": "Monthly Retained iOS Users", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The number of 30 day retained users, as defined above. Filtered only to clients with (\"riot\" or \"element\") and \"electron\" (case-insensitive) in the user agent string", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": 21600000, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 99 + }, + "id": 34, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "synapse_usage_r30v2_users_electron{homeserver=~\"$homeserver\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{homeserver}}", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sum(synapse_usage_r30v2_users_electron{homeserver=~\"$homeserver\"})", + "fullMetaSearch": false, + "hide": true, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Total", + "range": true, + "refId": "B", + "useBackend": false + } + ], + "title": "Monthly Retained Electron Users", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "The number of 30 day retained users, as defined above. Filtered only to clients with \"mozilla\" or \"gecko\" (case-insensitive) in the user agent string", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": 21600000, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 99 + }, + "id": 35, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "synapse_usage_r30v2_users_web{homeserver=~\"$homeserver\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{homeserver}}", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sum(synapse_usage_r30v2_users_web{homeserver=~\"$homeserver\"})", + "fullMetaSearch": false, + "hide": true, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Total", + "range": true, + "refId": "B", + "useBackend": false + } + ], + "title": "Monthly Retained Web Users", + "type": "timeseries" + } + ], + "refresh": "1d", + "schemaVersion": 39, + "tags": [ + "matrix" + ], + "templating": { + "list": [ + { + "current": {}, + "hide": 0, + "includeAll": false, + "label": "Datasource", + "multi": false, + "name": "DS_PROMETHEUS", + "options": [], + "query": "prometheus", + "queryValue": "", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "allFormat": "regex wildcard", + "allValue": "", + "current": {}, + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "definition": "", + "hide": 0, + "includeAll": false, + "label": "Homeserver", + "multi": true, + "multiFormat": "regex values", + "name": "homeserver", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(synapse_usage_timestamp,homeserver)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + } + ] + }, + "time": { + "from": "now-24h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Homeserver Statistics", + "uid": "c84624d7-3935-4470-83c0-c10d1cee35ff", + "version": 2, + "weekStart": "" +} \ No newline at end of file diff --git a/roles/custom/matrix-synapse-usage-exporter/templates/labels.j2 b/roles/custom/matrix-synapse-usage-exporter/templates/labels.j2 new file mode 100755 index 000000000..7811c3372 --- /dev/null +++ b/roles/custom/matrix-synapse-usage-exporter/templates/labels.j2 @@ -0,0 +1,38 @@ +{% if matrix_synapse_usage_exporter_container_labels_traefik_enabled %} +traefik.enable=true + +{% if matrix_synapse_usage_exporter_container_labels_traefik_docker_network %} +traefik.docker.network={{ matrix_synapse_usage_exporter_container_labels_traefik_docker_network }} +{% endif %} + +traefik.http.services.matrix-synapse-usage-exporter.loadbalancer.server.port={{ matrix_synapse_usage_exporter_container_port }} + +############################################################ +# # +# Report Usage Stats (/report-usage-stats/push) # +# # +############################################################ + +traefik.http.routers.matrix-synapse-usage-exporter.rule={{ matrix_synapse_usage_exporter_container_labels_traefik_rule }} + +{% if matrix_synapse_usage_exporter_container_labels_traefik_priority | int > 0 %} +traefik.http.routers.matrix-synapse-usage-exporter.priority={{ matrix_synapse_usage_exporter_container_labels_traefik_priority }} +{% endif %} + +traefik.http.routers.matrix-synapse-usage-exporter.service=matrix-synapse-usage-exporter +traefik.http.routers.matrix-synapse-usage-exporter.entrypoints={{ matrix_synapse_usage_exporter_container_labels_traefik_entrypoints }} + +traefik.http.routers.matrix-synapse-usage-exporter.tls={{ matrix_synapse_usage_exporter_container_labels_traefik_tls | to_json }} +{% if matrix_synapse_usage_exporter_container_labels_traefik_tls %} +traefik.http.routers.matrix-synapse-usage-exporter.tls.certResolver={{ matrix_synapse_usage_exporter_container_labels_traefik_tls_certResolver }} +{% endif %} + +############################################################ +# # +# /Report Usage Stats (/report-usage-stats/push) # +# # +############################################################ + +{% endif %} + +{{ matrix_synapse_usage_exporter_container_labels_additional_labels }} diff --git a/roles/custom/matrix-synapse-usage-exporter/templates/systemd/matrix-synapse-usage-exporter.service.j2 b/roles/custom/matrix-synapse-usage-exporter/templates/systemd/matrix-synapse-usage-exporter.service.j2 new file mode 100644 index 000000000..da09078c3 --- /dev/null +++ b/roles/custom/matrix-synapse-usage-exporter/templates/systemd/matrix-synapse-usage-exporter.service.j2 @@ -0,0 +1,47 @@ +#jinja2: lstrip_blocks: "True" +[Unit] +Description=Matrix synapse-usage-exporter +{% for service in matrix_synapse_usage_exporter_systemd_required_services_list %} +Requires={{ service }} +After={{ service }} +{% endfor %} +{% for service in matrix_synapse_usage_exporter_systemd_wanted_services_list %} +Wants={{ service }} +{% endfor %} +DefaultDependencies=no + +[Service] +Type=simple +Environment="HOME={{ devture_systemd_docker_base_systemd_unit_home_path }}" +ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop --time={{ devture_systemd_docker_base_container_stop_grace_time_seconds }} {{ matrix_synapse_usage_exporter_identifier }} 2>/dev/null || true' +ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm {{ matrix_synapse_usage_exporter_identifier }} 2>/dev/null || true' + +ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ + --rm \ + --name={{ matrix_synapse_usage_exporter_identifier }} \ + --log-driver=none \ + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ + --network={{ matrix_synapse_usage_exporter_container_network }} \ + --env-file={{ matrix_synapse_usage_exporter_base_path }}/env \ + --label-file={{ matrix_synapse_usage_exporter_base_path }}/labels \ + {% for arg in matrix_synapse_usage_exporter_container_extra_arguments %} + {{ arg }} \ + {% endfor %} + {{ matrix_synapse_usage_exporter_container_image }} + +{% for network in matrix_synapse_usage_exporter_container_additional_networks %} +ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} {{ matrix_synapse_usage_exporter_identifier }} +{% endfor %} + +ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach {{ matrix_synapse_usage_exporter_identifier }} + +ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop --time={{ devture_systemd_docker_base_container_stop_grace_time_seconds }} {{ matrix_synapse_usage_exporter_identifier }} 2>/dev/null || true' +ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm {{ matrix_synapse_usage_exporter_identifier }} 2>/dev/null || true' +ExecReload={{ devture_systemd_docker_base_host_command_docker }} exec {{ matrix_synapse_usage_exporter_identifier }} /bin/sh -c 'kill -HUP 1' +Restart=always +RestartSec=30 +SyslogIdentifier={{ matrix_synapse_usage_exporter_identifier }} + +[Install] +WantedBy=multi-user.target diff --git a/roles/custom/matrix-synapse/defaults/main.yml b/roles/custom/matrix-synapse/defaults/main.yml index 03c6bd2ca..e7cfb2cdb 100644 --- a/roles/custom/matrix-synapse/defaults/main.yml +++ b/roles/custom/matrix-synapse/defaults/main.yml @@ -462,6 +462,9 @@ matrix_synapse_federation_listener_resource_names: "{{ ['federation'] if matrix_ # (things like number of users, number of messages sent, uptime, load, etc.) matrix_synapse_report_stats: false +# The endpoint to report homeserver usage statistics to. +matrix_synapse_report_stats_endpoint: "https://matrix.org/report-usage-stats/push" + # Controls whether the Matrix server will track presence status (online, offline, unavailable) for users. # If users participate in large rooms with many other servers, # disabling this will decrease server load significantly. diff --git a/roles/custom/matrix-synapse/templates/synapse/homeserver.yaml.j2 b/roles/custom/matrix-synapse/templates/synapse/homeserver.yaml.j2 index 48bacc4f6..f44e06db1 100644 --- a/roles/custom/matrix-synapse/templates/synapse/homeserver.yaml.j2 +++ b/roles/custom/matrix-synapse/templates/synapse/homeserver.yaml.j2 @@ -1604,6 +1604,7 @@ report_stats: {{ matrix_synapse_report_stats|to_json }} # #report_stats_endpoint: https://example.com/report-usage-stats/push +report_stats_endpoint: {{ matrix_synapse_report_stats_endpoint|to_json }} ## API Configuration ## diff --git a/setup.yml b/setup.yml index c0551b7fe..5da953096 100644 --- a/setup.yml +++ b/setup.yml @@ -102,6 +102,7 @@ - custom/matrix-dendrite - custom/matrix-conduit - custom/matrix-synapse-admin + - custom/matrix-synapse-usage-exporter - galaxy/prometheus_node_exporter - galaxy/prometheus_postgres_exporter - custom/matrix-prometheus-nginxlog-exporter From 4d9de7d58a4392252d528c4575baa50a4bd56eb6 Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Thu, 25 Jul 2024 20:24:04 +0300 Subject: [PATCH 10/18] Add `matrix_synapse_usage_exporter_hostname` and `matrix_synapse_usage_exporter_path_prefix` Related to https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/3442 --- .../configuring-playbook-synapse-usage-exporter.md | 3 ++- .../defaults/main.yml | 14 +++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/docs/configuring-playbook-synapse-usage-exporter.md b/docs/configuring-playbook-synapse-usage-exporter.md index 9f962a7c5..a67becdf4 100644 --- a/docs/configuring-playbook-synapse-usage-exporter.md +++ b/docs/configuring-playbook-synapse-usage-exporter.md @@ -8,7 +8,7 @@ Enabling this service will automatically: - install the synapse-usage-exporter service - re-configure Synapse to push (via HTTP `PUT`) usage statistics information to synapse-usage-exporter -- re-configure [Prometheus](./configuring-playbook-prometheus-grafana.md) (if Grafana is enabled), to periodically scrape metrics from synapse-usage-exporter +- re-configure [Prometheus](./configuring-playbook-prometheus-grafana.md) (if Prometheus is enabled), to periodically scrape metrics from synapse-usage-exporter - add a new [Grafana](./configuring-playbook-prometheus-grafana.md) dashboard (if Grafana is enabled) containing Synapse usage statistics ## Quickstart @@ -21,5 +21,6 @@ matrix_synapse_usage_exporter_enabled: true # (Optional) Expose endpoint if you want to collect statistics from outside (from other homeservers). # If enabled, synapse-usage-exporter will be exposed publicly at `matrix.DOMAIN/report-usage-stats/push`. # When collecting usage statistics for Synapse running on the same host, you don't need to enable this. +# You can adjust the hostname and path via `matrix_synapse_usage_exporter_hostname` and `matrix_synapse_usage_exporter_path_prefix`. # matrix_synapse_usage_exporter_proxying_enabled: true ``` diff --git a/roles/custom/matrix-synapse-usage-exporter/defaults/main.yml b/roles/custom/matrix-synapse-usage-exporter/defaults/main.yml index 991218645..c207e4b1c 100644 --- a/roles/custom/matrix-synapse-usage-exporter/defaults/main.yml +++ b/roles/custom/matrix-synapse-usage-exporter/defaults/main.yml @@ -5,6 +5,11 @@ matrix_synapse_usage_exporter_enabled: false +# Controls the hostname and path that this component exposes its web services on. +# Only used if `matrix_synapse_usage_exporter_proxying_enabled` is true. +matrix_synapse_usage_exporter_hostname: "{{ matrix_server_fqn_matrix }}" +matrix_synapse_usage_exporter_path_prefix: /report-usage-stats/push + # matrix_synapse_usage_exporter_identifier controls the identifier of this synapse-usage-exporter instance, which influences: # - the default storage path # - the names of systemd services and containers @@ -44,7 +49,10 @@ matrix_synapse_usage_exporter_container_additional_networks: [] # Extra arguments for the Docker container matrix_synapse_usage_exporter_container_extra_arguments: [] -# Controls whether the synapse usage exporter should be proxied (exposed) on `matrix.DOMAIN/report-usage-stats/push` +# Controls whether the synapse-usage-exporter's web services should be proxied (exposed publicly). +# +# Exposure happens on `matrix.DOMAIN/report-usage-stats/push` by default. +# See: `matrix_synapse_usage_exporter_hostname` and `matrix_synapse_usage_exporter_path_prefix`. matrix_synapse_usage_exporter_proxying_enabled: false # matrix_synapse_usage_exporter_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. @@ -54,8 +62,8 @@ matrix_synapse_usage_exporter_proxying_enabled: false matrix_synapse_usage_exporter_container_labels_traefik_enabled: "{{ matrix_synapse_usage_exporter_proxying_enabled }}" matrix_synapse_usage_exporter_container_labels_traefik_docker_network: "{{ matrix_synapse_usage_exporter_container_network }}" -matrix_synapse_usage_exporter_container_labels_traefik_path_prefix: "/report-usage-stats/push" -matrix_synapse_usage_exporter_container_labels_traefik_rule: "Host(`{{ matrix_server_fqn_matrix }}`) && PathPrefix(`{{ matrix_synapse_usage_exporter_container_labels_traefik_path_prefix | quote }}`)" +matrix_synapse_usage_exporter_container_labels_traefik_path_prefix: "{{ matrix_synapse_usage_exporter_path_prefix }}" +matrix_synapse_usage_exporter_container_labels_traefik_rule: "Host(`{{ matrix_synapse_usage_exporter_hostname }}`) && PathPrefix(`{{ matrix_synapse_usage_exporter_container_labels_traefik_path_prefix }}`)" matrix_synapse_usage_exporter_container_labels_traefik_priority: 0 matrix_synapse_usage_exporter_container_labels_traefik_entrypoints: "web-secure" matrix_synapse_usage_exporter_container_labels_traefik_tls: "{{ matrix_synapse_usage_exporter_container_labels_traefik_entrypoints != 'web' }}" From 020c66a2c15f93ec44fde14c092f0ae10498d694 Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Thu, 25 Jul 2024 20:30:41 +0300 Subject: [PATCH 11/18] Announce synapse-usage-exporter support Related to https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/3442 --- CHANGELOG.md | 9 +++++++++ docs/configuring-playbook-prometheus-grafana.md | 1 + docs/configuring-playbook-synapse.md | 4 +++- docs/configuring-playbook.md | 2 ++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3304d3a93..859c046d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# 2024-07-25 + +## synapse-usage-exporter support + +Thanks to [Michael Hollister](https://github.com/Michael-Hollister) from [FUTO](https://www.futo.org/), the creators of the [Circles app](https://circu.li/), the playbook can now set up [synapse-usage-exporter](https://github.com/loelkes/synapse-usage-exporter) - a small [Flask](https://flask.palletsprojects.com)-based webservice which can capture usage statistics from Synapse (via HTTP `PUT`) and then make them available for Prometheus to scrape. + +To learn more see our [Enabling synapse-usage-exporter for Synapse usage statistics](docs/configuring-playbook-synapse-usage-exporter.md) documentation page. + + # 2024-07-06 ## matrix-alertmanager-receiver support diff --git a/docs/configuring-playbook-prometheus-grafana.md b/docs/configuring-playbook-prometheus-grafana.md index 131b1752e..2bcb1d8e1 100644 --- a/docs/configuring-playbook-prometheus-grafana.md +++ b/docs/configuring-playbook-prometheus-grafana.md @@ -121,6 +121,7 @@ scrape_configs: ## More information +- [Enabling synapse-usage-exporter for Synapse usage statistics](configuring-playbook-synapse-usage-exporter.md) - [Understanding Synapse Performance Issues Through Grafana Graphs](https://element-hq.github.io/synapse/latest/usage/administration/understanding_synapse_through_grafana_graphs.html) at the Synapse Github Wiki - [The Prometheus scraping rules](https://github.com/element-hq/synapse/tree/master/contrib/prometheus) (we use v2) - [The Synapse Grafana dashboard](https://github.com/element-hq/synapse/tree/master/contrib/grafana) diff --git a/docs/configuring-playbook-synapse.md b/docs/configuring-playbook-synapse.md index e99a56e7f..b165b1a14 100644 --- a/docs/configuring-playbook-synapse.md +++ b/docs/configuring-playbook-synapse.md @@ -161,4 +161,6 @@ Due to this, it's recommended to only store and maintain template files in your This playbook allows you to enable Synapse metrics, which can provide insight into the performance and activity of Synapse. -To enable Synapse metrics see [`configuring-playbook-prometheus-grafana.md`](./configuring-playbook-prometheus-grafana.md) +To enable Synapse runtime metrics see: [Enabling metrics and graphs (Prometheus, Grafana) for your Matrix server](configuring-playbook-prometheus-grafana.md) + +To enable Synapse usage metrics, see: [Enabling synapse-usage-exporter for Synapse usage statistics](configuring-playbook-synapse-usage-exporter.md) diff --git a/docs/configuring-playbook.md b/docs/configuring-playbook.md index 64c47fbe6..e1ed4eb42 100644 --- a/docs/configuring-playbook.md +++ b/docs/configuring-playbook.md @@ -42,6 +42,8 @@ When you're done with all the configuration you'd like to do, continue with [Ins - [Enabling metrics and graphs (Prometheus, Grafana) for your Matrix server](configuring-playbook-prometheus-grafana.md) (optional) +- [Enabling synapse-usage-exporter for Synapse usage statistics](configuring-playbook-synapse-usage-exporter.md) (optional) + ### Core service adjustments - Homeserver configuration: From 0028e3e27d7c43554df4ff78d66056a9004dcfae Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Thu, 25 Jul 2024 20:37:44 +0300 Subject: [PATCH 12/18] Revert "chore(deps): update dependency grafana to v11.1.2-0" This reverts commit 90e3f4cba8a2c88ecf726dcfe7b31a77317b3fc2. Fixes https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3445 --- requirements.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.yml b/requirements.yml index 9aebc0bd3..5930cf21f 100644 --- a/requirements.yml +++ b/requirements.yml @@ -22,7 +22,7 @@ version: v4.98-r0-0-0 name: exim_relay - src: git+https://gitlab.com/etke.cc/roles/grafana.git - version: v11.1.2-0 + version: v11.1.0-0 name: grafana - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-jitsi.git version: v9584-1 From a1a1c982578cca2bc95e85fec3448ee6ccfd6ea0 Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Thu, 25 Jul 2024 20:40:18 +0300 Subject: [PATCH 13/18] Upgrade Grafana (v11.1.0-0 -> v11.1.1-0) Related to https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3445 --- requirements.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.yml b/requirements.yml index 5930cf21f..01593d62c 100644 --- a/requirements.yml +++ b/requirements.yml @@ -22,7 +22,7 @@ version: v4.98-r0-0-0 name: exim_relay - src: git+https://gitlab.com/etke.cc/roles/grafana.git - version: v11.1.0-0 + version: v11.1.1-0 name: grafana - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-jitsi.git version: v9584-1 From 035b1c3c045a5524ceceed5a93734a23d169684f Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Fri, 26 Jul 2024 15:15:51 +0300 Subject: [PATCH 14/18] Upgrade Coturn (4.6.2-r10 -> 4.6.2-r11) --- roles/custom/matrix-coturn/defaults/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/custom/matrix-coturn/defaults/main.yml b/roles/custom/matrix-coturn/defaults/main.yml index 1a702791d..edf616129 100644 --- a/roles/custom/matrix-coturn/defaults/main.yml +++ b/roles/custom/matrix-coturn/defaults/main.yml @@ -9,7 +9,7 @@ matrix_coturn_container_image_self_build_repo_version: "docker/{{ matrix_coturn_ matrix_coturn_container_image_self_build_repo_dockerfile_path: "docker/coturn/alpine/Dockerfile" # renovate: datasource=docker depName=coturn/coturn -matrix_coturn_version: 4.6.2-r10 +matrix_coturn_version: 4.6.2-r11 matrix_coturn_docker_image: "{{ matrix_coturn_docker_image_name_prefix }}coturn/coturn:{{ matrix_coturn_version }}-alpine" matrix_coturn_docker_image_name_prefix: "{{ 'localhost/' if matrix_coturn_container_image_self_build else matrix_container_global_registry_prefix }}" matrix_coturn_docker_image_force_pull: "{{ matrix_coturn_docker_image.endswith(':latest') }}" From bcd846d3b8cca31b76a03a80a989126bcbe6321c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 26 Jul 2024 17:22:06 +0000 Subject: [PATCH 15/18] chore(deps): update dependency grafana to v11.1.3-0 --- requirements.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.yml b/requirements.yml index 01593d62c..c8d27aa64 100644 --- a/requirements.yml +++ b/requirements.yml @@ -22,7 +22,7 @@ version: v4.98-r0-0-0 name: exim_relay - src: git+https://gitlab.com/etke.cc/roles/grafana.git - version: v11.1.1-0 + version: v11.1.3-0 name: grafana - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-jitsi.git version: v9584-1 From 570582b30b66a83eeac1f6c2bf2442a4b1533366 Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Sat, 27 Jul 2024 16:16:17 +0300 Subject: [PATCH 16/18] Upgrade Grafana (v11.1.3-0 -> v11.1.3-1) Fixes https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3449 Closes https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/3450 --- requirements.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.yml b/requirements.yml index c8d27aa64..6f623eb26 100644 --- a/requirements.yml +++ b/requirements.yml @@ -22,7 +22,7 @@ version: v4.98-r0-0-0 name: exim_relay - src: git+https://gitlab.com/etke.cc/roles/grafana.git - version: v11.1.3-0 + version: v11.1.3-1 name: grafana - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-jitsi.git version: v9584-1 From 880daf55af7d489bb416e2ba5e81a0b045e8b519 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 27 Jul 2024 18:46:34 +0000 Subject: [PATCH 17/18] chore(deps): update registry.gitlab.com/etke.cc/honoroit docker tag to v0.9.24 --- roles/custom/matrix-bot-honoroit/defaults/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/custom/matrix-bot-honoroit/defaults/main.yml b/roles/custom/matrix-bot-honoroit/defaults/main.yml index 013b68499..f1ebd1401 100644 --- a/roles/custom/matrix-bot-honoroit/defaults/main.yml +++ b/roles/custom/matrix-bot-honoroit/defaults/main.yml @@ -21,7 +21,7 @@ matrix_bot_honoroit_docker_repo_version: "{{ matrix_bot_honoroit_version }}" matrix_bot_honoroit_docker_src_files_path: "{{ matrix_base_data_path }}/honoroit/docker-src" # renovate: datasource=docker depName=registry.gitlab.com/etke.cc/honoroit -matrix_bot_honoroit_version: v0.9.23 +matrix_bot_honoroit_version: v0.9.24 matrix_bot_honoroit_docker_image: "{{ matrix_bot_honoroit_docker_image_name_prefix }}etke.cc/honoroit:{{ matrix_bot_honoroit_version }}" matrix_bot_honoroit_docker_image_name_prefix: "{{ 'localhost/' if matrix_bot_honoroit_container_image_self_build else 'registry.gitlab.com/' }}" matrix_bot_honoroit_docker_image_force_pull: "{{ matrix_bot_honoroit_docker_image.endswith(':latest') }}" From af089b89d1a1acdf7a6ddacb260e18c8f2a413b3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 27 Jul 2024 18:46:39 +0000 Subject: [PATCH 18/18] chore(deps): update registry.gitlab.com/etke.cc/postmoogle docker tag to v0.9.20 --- roles/custom/matrix-bot-postmoogle/defaults/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/custom/matrix-bot-postmoogle/defaults/main.yml b/roles/custom/matrix-bot-postmoogle/defaults/main.yml index 1aca94d04..a6ec622e7 100644 --- a/roles/custom/matrix-bot-postmoogle/defaults/main.yml +++ b/roles/custom/matrix-bot-postmoogle/defaults/main.yml @@ -10,7 +10,7 @@ matrix_bot_postmoogle_docker_repo_version: "{{ 'main' if matrix_bot_postmoogle_v matrix_bot_postmoogle_docker_src_files_path: "{{ matrix_base_data_path }}/postmoogle/docker-src" # renovate: datasource=docker depName=registry.gitlab.com/etke.cc/postmoogle -matrix_bot_postmoogle_version: v0.9.19 +matrix_bot_postmoogle_version: v0.9.20 matrix_bot_postmoogle_docker_image: "{{ matrix_bot_postmoogle_docker_image_name_prefix }}etke.cc/postmoogle:{{ matrix_bot_postmoogle_version }}" matrix_bot_postmoogle_docker_image_name_prefix: "{{ 'localhost/' if matrix_bot_postmoogle_container_image_self_build else 'registry.gitlab.com/' }}" matrix_bot_postmoogle_docker_image_force_pull: "{{ matrix_bot_postmoogle_docker_image.endswith(':latest') }}"