diff --git a/.ci/before_build_wheel.sh b/.ci/before_build_wheel.sh index 56108dcd60..44ca97f31b 100644 --- a/.ci/before_build_wheel.sh +++ b/.ci/before_build_wheel.sh @@ -7,4 +7,4 @@ if command -v yum &> /dev/null; then fi # Install a Rust toolchain -curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain 1.82.0 -y --profile minimal +curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain stable -y --profile minimal diff --git a/.ci/complement_package.gotpl b/.ci/complement_package.gotpl index 2dd5e5e0e6..e71ed9f616 100644 --- a/.ci/complement_package.gotpl +++ b/.ci/complement_package.gotpl @@ -29,7 +29,7 @@ which is under the Unlicense licence. {{- with .TestCases -}} {{- /* Passing tests are first */ -}} {{- range . -}} - {{- if eq .Result "PASS" -}} + {{- if and (eq .Result "PASS") (not $settings.HideSuccessfulTests) -}} ::group::{{ "\033" }}[0;32m✅{{ " " }}{{- .Name -}} {{- "\033" -}}[0;37m ({{if $settings.ShowTestStatus}}{{.Result}}; {{end}}{{ .Duration -}} {{- with .Coverage -}} @@ -49,7 +49,8 @@ which is under the Unlicense licence. {{- /* Then skipped tests are second */ -}} {{- range . -}} - {{- if eq .Result "SKIP" -}} + {{- /* Skipped tests are also purposefully hidden if "HideSuccessfulTests" is enabled */ -}} + {{- if and (eq .Result "SKIP") (not $settings.HideSuccessfulTests) -}} ::group::{{ "\033" }}[0;33m🚧{{ " " }}{{- .Name -}} {{- "\033" -}}[0;37m ({{if $settings.ShowTestStatus}}{{.Result}}; {{end}}{{ .Duration -}} {{- with .Coverage -}} diff --git a/.ci/scripts/auditwheel_wrapper.py b/.ci/scripts/auditwheel_wrapper.py deleted file mode 100755 index 9599b79e50..0000000000 --- a/.ci/scripts/auditwheel_wrapper.py +++ /dev/null @@ -1,147 +0,0 @@ -#!/usr/bin/env python -# -# This file is licensed under the Affero General Public License (AGPL) version 3. -# -# Copyright (C) 2023 New Vector, Ltd -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# See the GNU Affero General Public License for more details: -# . -# -# Originally licensed under the Apache License, Version 2.0: -# . -# -# [This file includes modifications made by New Vector Limited] -# -# - -# Wraps `auditwheel repair` to first check if we're repairing a potentially abi3 -# compatible wheel, if so rename the wheel before repairing it. - -import argparse -import os -import subprocess -from typing import Optional -from zipfile import ZipFile - -from packaging.tags import Tag -from packaging.utils import parse_wheel_filename -from packaging.version import Version - - -def check_is_abi3_compatible(wheel_file: str) -> None: - """Check the contents of the built wheel for any `.so` files that are *not* - abi3 compatible. - """ - - with ZipFile(wheel_file, "r") as wheel: - for file in wheel.namelist(): - if not file.endswith(".so"): - continue - - if not file.endswith(".abi3.so"): - raise Exception(f"Found non-abi3 lib: {file}") - - -def cpython(wheel_file: str, name: str, version: Version, tag: Tag) -> str: - """Replaces the cpython wheel file with a ABI3 compatible wheel""" - - if tag.abi == "abi3": - # Nothing to do. - return wheel_file - - check_is_abi3_compatible(wheel_file) - - # HACK: it seems that some older versions of pip will consider a wheel marked - # as macosx_11_0 as incompatible with Big Sur. I haven't done the full archaeology - # here; there are some clues in - # https://github.com/pantsbuild/pants/pull/12857 - # https://github.com/pypa/pip/issues/9138 - # https://github.com/pypa/packaging/pull/319 - # Empirically this seems to work, note that macOS 11 and 10.16 are the same, - # both versions are valid for backwards compatibility. - platform = tag.platform.replace("macosx_11_0", "macosx_10_16") - abi3_tag = Tag(tag.interpreter, "abi3", platform) - - dirname = os.path.dirname(wheel_file) - new_wheel_file = os.path.join( - dirname, - f"{name}-{version}-{abi3_tag}.whl", - ) - - os.rename(wheel_file, new_wheel_file) - - print("Renamed wheel to", new_wheel_file) - - return new_wheel_file - - -def main(wheel_file: str, dest_dir: str, archs: Optional[str]) -> None: - """Entry point""" - - # Parse the wheel file name into its parts. Note that `parse_wheel_filename` - # normalizes the package name (i.e. it converts matrix_synapse -> - # matrix-synapse), which is not what we want. - _, version, build, tags = parse_wheel_filename(os.path.basename(wheel_file)) - name = os.path.basename(wheel_file).split("-")[0] - - if len(tags) != 1: - # We expect only a wheel file with only a single tag - raise Exception(f"Unexpectedly found multiple tags: {tags}") - - tag = next(iter(tags)) - - if build: - # We don't use build tags in Synapse - raise Exception(f"Unexpected build tag: {build}") - - # If the wheel is for cpython then convert it into an abi3 wheel. - if tag.interpreter.startswith("cp"): - wheel_file = cpython(wheel_file, name, version, tag) - - # Finally, repair the wheel. - if archs is not None: - # If we are given archs then we are on macos and need to use - # `delocate-listdeps`. - subprocess.run(["delocate-listdeps", wheel_file], check=True) - subprocess.run( - ["delocate-wheel", "--require-archs", archs, "-w", dest_dir, wheel_file], - check=True, - ) - else: - subprocess.run(["auditwheel", "repair", "-w", dest_dir, wheel_file], check=True) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Tag wheel as abi3 and repair it.") - - parser.add_argument( - "--wheel-dir", - "-w", - metavar="WHEEL_DIR", - help="Directory to store delocated wheels", - required=True, - ) - - parser.add_argument( - "--require-archs", - metavar="archs", - default=None, - ) - - parser.add_argument( - "wheel_file", - metavar="WHEEL_FILE", - ) - - args = parser.parse_args() - - wheel_file = args.wheel_file - wheel_dir = args.wheel_dir - archs = args.require_archs - - main(wheel_file, wheel_dir, archs) diff --git a/.ci/scripts/calculate_jobs.py b/.ci/scripts/calculate_jobs.py index 5249acdc5d..1ddea715b0 100755 --- a/.ci/scripts/calculate_jobs.py +++ b/.ci/scripts/calculate_jobs.py @@ -35,49 +35,58 @@ IS_PR = os.environ["GITHUB_REF"].startswith("refs/pull/") # First calculate the various trial jobs. # -# For PRs, we only run each type of test with the oldest Python version supported (which -# is Python 3.9 right now) +# For PRs, we only run each type of test with the oldest and newest Python +# version that's supported. The oldest version ensures we don't accidentally +# introduce syntax or code that's too new, and the newest ensures we don't use +# code that's been dropped in the latest supported Python version. trial_sqlite_tests = [ { - "python-version": "3.9", + "python-version": "3.10", "database": "sqlite", "extras": "all", - } + }, + { + "python-version": "3.14", + "database": "sqlite", + "extras": "all", + }, ] if not IS_PR: + # Otherwise, check all supported Python versions. + # + # Avoiding running all of these versions on every PR saves on CI time. trial_sqlite_tests.extend( { "python-version": version, "database": "sqlite", "extras": "all", } - for version in ("3.10", "3.11", "3.12", "3.13") + for version in ("3.11", "3.12", "3.13") ) +# Only test postgres against the earliest and latest Python versions that we +# support in order to save on CI time. trial_postgres_tests = [ { - "python-version": "3.9", + "python-version": "3.10", "database": "postgres", - "postgres-version": "13", + "postgres-version": "14", "extras": "all", - } + }, + { + "python-version": "3.14", + "database": "postgres", + "postgres-version": "17", + "extras": "all", + }, ] -if not IS_PR: - trial_postgres_tests.append( - { - "python-version": "3.13", - "database": "postgres", - "postgres-version": "17", - "extras": "all", - } - ) - +# Ensure that Synapse passes unit tests even with no extra dependencies installed. trial_no_extra_tests = [ { - "python-version": "3.9", + "python-version": "3.10", "database": "sqlite", "extras": "", } @@ -99,24 +108,24 @@ set_output("trial_test_matrix", test_matrix) # First calculate the various sytest jobs. # -# For each type of test we only run on bullseye on PRs +# For each type of test we only run on bookworm on PRs sytest_tests = [ { - "sytest-tag": "bullseye", + "sytest-tag": "bookworm", }, { - "sytest-tag": "bullseye", + "sytest-tag": "bookworm", "postgres": "postgres", }, { - "sytest-tag": "bullseye", + "sytest-tag": "bookworm", "postgres": "multi-postgres", "workers": "workers", }, { - "sytest-tag": "bullseye", + "sytest-tag": "bookworm", "postgres": "multi-postgres", "workers": "workers", "reactor": "asyncio", @@ -127,11 +136,11 @@ if not IS_PR: sytest_tests.extend( [ { - "sytest-tag": "bullseye", + "sytest-tag": "bookworm", "reactor": "asyncio", }, { - "sytest-tag": "bullseye", + "sytest-tag": "bookworm", "postgres": "postgres", "reactor": "asyncio", }, diff --git a/.ci/scripts/gotestfmt b/.ci/scripts/gotestfmt deleted file mode 100755 index 83e0ec6361..0000000000 --- a/.ci/scripts/gotestfmt +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -# -# wraps `gotestfmt`, hiding output from successful packages unless -# all tests passed. - -set -o pipefail -set -e - -# tee the test results to a log, whilst also piping them into gotestfmt, -# telling it to hide successful results, so that we can clearly see -# unsuccessful results. -tee complement.log | gotestfmt -hide successful-packages - -# gotestfmt will exit non-zero if there were any failures, so if we got to this -# point, we must have had a successful result. -echo "All tests successful; showing all test results" - -# Pipe the test results back through gotestfmt, showing all results. -# The log file consists of JSON lines giving the test results, interspersed -# with regular stdout lines (including reports of downloaded packages). -grep '^{"Time":' complement.log | gotestfmt diff --git a/.ci/scripts/prepare_old_deps.sh b/.ci/scripts/prepare_old_deps.sh deleted file mode 100755 index 3589be26f8..0000000000 --- a/.ci/scripts/prepare_old_deps.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env bash -# this script is run by GitHub Actions in a plain `jammy` container; it -# - installs the minimal system requirements, and poetry; -# - patches the project definition file to refer to old versions only; -# - creates a venv with these old versions using poetry; and finally -# - invokes `trial` to run the tests with old deps. - -set -ex - -# Prevent virtualenv from auto-updating pip to an incompatible version -export VIRTUALENV_NO_DOWNLOAD=1 - -# TODO: in the future, we could use an implementation of -# https://github.com/python-poetry/poetry/issues/3527 -# https://github.com/pypa/pip/issues/8085 -# to select the lowest possible versions, rather than resorting to this sed script. - -# Patch the project definitions in-place: -# - Replace all lower and tilde bounds with exact bounds -# - Replace all caret bounds---but not the one that defines the supported Python version! -# - Delete all lines referring to psycopg2 --- so no testing of postgres support. -# - Use pyopenssl 17.0, which is the oldest version that works with -# a `cryptography` compiled against OpenSSL 1.1. -# - Omit systemd: we're not logging to journal here. - -sed -i \ - -e "s/[~>]=/==/g" \ - -e '/^python = "^/!s/\^/==/g' \ - -e "/psycopg2/d" \ - -e 's/pyOpenSSL = "==16.0.0"/pyOpenSSL = "==17.0.0"/' \ - -e '/systemd/d' \ - pyproject.toml - -echo "::group::Patched pyproject.toml" -cat pyproject.toml -echo "::endgroup::" diff --git a/.ci/scripts/setup_complement_prerequisites.sh b/.ci/scripts/setup_complement_prerequisites.sh index 47a3ff8e69..1fdaf5e631 100755 --- a/.ci/scripts/setup_complement_prerequisites.sh +++ b/.ci/scripts/setup_complement_prerequisites.sh @@ -10,7 +10,6 @@ alias block='{ set +x; } 2>/dev/null; func() { echo "::group::$*"; set -x; }; fu alias endblock='{ set +x; } 2>/dev/null; func() { echo "::endgroup::"; set -x; }; func' block Install Complement Dependencies - sudo apt-get -qq update && sudo apt-get install -qqy libolm3 libolm-dev go install -v github.com/gotesttools/gotestfmt/v2/cmd/gotestfmt@latest endblock diff --git a/.ci/scripts/triage_labelled_issue.sh b/.ci/scripts/triage_labelled_issue.sh new file mode 100755 index 0000000000..0458bccbd4 --- /dev/null +++ b/.ci/scripts/triage_labelled_issue.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +set -euo pipefail + +# 1) Resolve project ID. +PROJECT_ID=$(gh project view "$PROJECT_NUMBER" --owner "$PROJECT_OWNER" --format json | jq -r '.id') + +# 2) Find existing item (project card) for this issue. +ITEM_ID=$( + gh project item-list "$PROJECT_NUMBER" --owner "$PROJECT_OWNER" --format json \ + | jq -r --arg url "$ISSUE_URL" '.items[] | select(.content.url==$url) | .id' | head -n1 +) + +# 3) If one doesn't exist, add this issue to the project. +if [ -z "${ITEM_ID:-}" ]; then + ITEM_ID=$(gh project item-add "$PROJECT_NUMBER" --owner "$PROJECT_OWNER" --url "$ISSUE_URL" --format json | jq -r '.id') +fi + +# 4) Get Status field id + the option id for TARGET_STATUS. +FIELDS_JSON=$(gh project field-list "$PROJECT_NUMBER" --owner "$PROJECT_OWNER" --format json) +STATUS_FIELD=$(echo "$FIELDS_JSON" | jq -r '.fields[] | select(.name=="Status")') +STATUS_FIELD_ID=$(echo "$STATUS_FIELD" | jq -r '.id') +OPTION_ID=$(echo "$STATUS_FIELD" | jq -r --arg name "$TARGET_STATUS" '.options[] | select(.name==$name) | .id') + +if [ -z "${OPTION_ID:-}" ]; then + echo "No Status option named \"$TARGET_STATUS\" found"; exit 1 +fi + +# 5) Set Status (moves item to the matching column in the board view). +gh project item-edit --id "$ITEM_ID" --project-id "$PROJECT_ID" --field-id "$STATUS_FIELD_ID" --single-select-option-id "$OPTION_ID" \ No newline at end of file diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 4c7b0335e6..729b638c79 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -26,3 +26,8 @@ c4268e3da64f1abb5b31deaeb5769adb6510c0a7 # Update black to 23.1.0 (https://github.com/matrix-org/synapse/pull/15103) 9bb2eac71962970d02842bca441f4bcdbbf93a11 +# Use type hinting generics in standard collections (https://github.com/element-hq/synapse/pull/19046) +fc244bb592aa481faf28214a2e2ce3bb4e95d990 + +# Write union types as X | Y where possible (https://github.com/element-hq/synapse/pull/19111) +fcac7e0282b074d4bd3414d1c9c181e9701875d9 diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 7ce353ed64..38920ead7a 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,23 +1,92 @@ version: 2 +# As dependabot is currently only run on a weekly basis, we raise the +# open-pull-requests-limit to 10 (from the default of 5) to better ensure we +# don't continuously grow a backlog of updates. updates: - # "pip" is the correct setting for poetry, per https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#package-ecosystem package-ecosystem: "pip" directory: "/" + open-pull-requests-limit: 10 schedule: interval: "weekly" + # Group patch updates to packages together into a single PR, as they rarely + # if ever contain breaking changes that need to be reviewed separately. + # + # Less PRs means a streamlined review process. + # + # Python packages follow semantic versioning, and tend to only introduce + # breaking changes in major version bumps. Thus, we'll group minor and patch + # versions together. + groups: + minor-and-patches: + applies-to: version-updates + patterns: + - "*" + update-types: + - "minor" + - "patch" + # Prevent pulling packages that were recently updated to help mitigate + # supply chain attacks. 14 days was taken from the recommendation at + # https://blog.yossarian.net/2025/11/21/We-should-all-be-using-dependency-cooldowns + # where the author noted that 9/10 attacks would have been mitigated by a + # two week cooldown. + # + # The cooldown only applies to general updates; security updates will still + # be pulled in as soon as possible. + cooldown: + default-days: 14 - package-ecosystem: "docker" directory: "/docker" + open-pull-requests-limit: 10 schedule: interval: "weekly" + # For container versions, breaking changes are also typically only introduced in major + # package bumps. + groups: + minor-and-patches: + applies-to: version-updates + patterns: + - "*" + update-types: + - "minor" + - "patch" + cooldown: + default-days: 14 - package-ecosystem: "github-actions" directory: "/" + open-pull-requests-limit: 10 schedule: interval: "weekly" + # Similarly for GitHub Actions, breaking changes are typically only introduced in major + # package bumps. + groups: + minor-and-patches: + applies-to: version-updates + patterns: + - "*" + update-types: + - "minor" + - "patch" + cooldown: + default-days: 14 - package-ecosystem: "cargo" directory: "/" + open-pull-requests-limit: 10 versioning-strategy: "lockfile-only" schedule: interval: "weekly" + # The Rust ecosystem is special in that breaking changes are often introduced + # in minor version bumps, as packages typically stay pre-1.0 for a long time. + # Thus we specifically keep minor version bumps separate in their own PRs. + groups: + patches: + applies-to: version-updates + patterns: + - "*" + update-types: + - "patch" + cooldown: + default-days: 14 diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 0deb5052d5..051c66ebba 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -28,10 +28,10 @@ jobs: steps: - name: Set up Docker Buildx id: buildx - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Extract version from pyproject.toml # Note: explicitly requesting bash will mean bash is invoked with `-eo pipefail`, see @@ -41,21 +41,53 @@ jobs: echo "SYNAPSE_VERSION=$(grep "^version" pyproject.toml | sed -E 's/version\s*=\s*["]([^"]*)["]/\1/')" >> $GITHUB_ENV - name: Log in to DockerHub - uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0 + uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Log in to GHCR - uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0 + uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 with: registry: ghcr.io username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Tailscale + uses: tailscale/github-action@306e68a486fd2350f2bfc3b19fcd143891a4a2d8 # v4.1.2 + with: + oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }} + audience: ${{ secrets.TS_AUDIENCE }} + tags: tag:github-actions + + - name: Compute vault jwt role name + id: vault-jwt-role + run: | + echo "role_name=github_service_management_$( echo "${{ github.repository }}" | sed -r 's|[/-]|_|g')" | tee -a "$GITHUB_OUTPUT" + + - name: Get team registry token + id: import-secrets + uses: hashicorp/vault-action@4c06c5ccf5c0761b6029f56cfb1dcf5565918a3b # v3.4.0 + with: + url: https://vault.infra.ci.i.element.dev + role: ${{ steps.vault-jwt-role.outputs.role_name }} + path: service-management/github-actions + jwtGithubAudience: https://vault.infra.ci.i.element.dev + method: jwt + secrets: | + services/backend-repositories/secret/data/oci.element.io username | OCI_USERNAME ; + services/backend-repositories/secret/data/oci.element.io password | OCI_PASSWORD ; + + - name: Login to Element OCI Registry + uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 + with: + registry: oci-push.vpn.infra.element.io + username: ${{ steps.import-secrets.outputs.OCI_USERNAME }} + password: ${{ steps.import-secrets.outputs.OCI_PASSWORD }} + - name: Build and push by digest id: build - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 + uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0 with: push: true labels: | @@ -64,6 +96,7 @@ jobs: tags: | docker.io/matrixdotorg/synapse ghcr.io/element-hq/synapse + oci-push.vpn.infra.element.io/synapse file: "docker/Dockerfile" platforms: ${{ matrix.platform }} outputs: type=image,push-by-digest=true,name-canonical=true,push=true @@ -75,7 +108,7 @@ jobs: touch "${{ runner.temp }}/digests/${digest#sha256:}" - name: Upload digest - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: digests-${{ matrix.suffix }} path: ${{ runner.temp }}/digests/* @@ -90,40 +123,73 @@ jobs: repository: - docker.io/matrixdotorg/synapse - ghcr.io/element-hq/synapse + - oci-push.vpn.infra.element.io/synapse needs: - build steps: - name: Download digests - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: ${{ runner.temp }}/digests pattern: digests-* merge-multiple: true - name: Log in to DockerHub - uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0 + uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 if: ${{ startsWith(matrix.repository, 'docker.io') }} with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Log in to GHCR - uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0 + uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 if: ${{ startsWith(matrix.repository, 'ghcr.io') }} with: registry: ghcr.io username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Tailscale + uses: tailscale/github-action@306e68a486fd2350f2bfc3b19fcd143891a4a2d8 # v4.1.2 + with: + oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }} + audience: ${{ secrets.TS_AUDIENCE }} + tags: tag:github-actions + + - name: Compute vault jwt role name + id: vault-jwt-role + run: | + echo "role_name=github_service_management_$( echo "${{ github.repository }}" | sed -r 's|[/-]|_|g')" | tee -a "$GITHUB_OUTPUT" + + - name: Get team registry token + id: import-secrets + uses: hashicorp/vault-action@4c06c5ccf5c0761b6029f56cfb1dcf5565918a3b # v3.4.0 + with: + url: https://vault.infra.ci.i.element.dev + role: ${{ steps.vault-jwt-role.outputs.role_name }} + path: service-management/github-actions + jwtGithubAudience: https://vault.infra.ci.i.element.dev + method: jwt + secrets: | + services/backend-repositories/secret/data/oci.element.io username | OCI_USERNAME ; + services/backend-repositories/secret/data/oci.element.io password | OCI_PASSWORD ; + + - name: Login to Element OCI Registry + uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 + with: + registry: oci-push.vpn.infra.element.io + username: ${{ steps.import-secrets.outputs.OCI_USERNAME }} + password: ${{ steps.import-secrets.outputs.OCI_PASSWORD }} + - name: Set up Docker Buildx - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 - name: Install Cosign - uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2 + uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0 - name: Calculate docker image tag - uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0 + uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0 with: images: ${{ matrix.repository }} flavor: | diff --git a/.github/workflows/docs-pr-netlify.yaml b/.github/workflows/docs-pr-netlify.yaml deleted file mode 100644 index 53a2d6b597..0000000000 --- a/.github/workflows/docs-pr-netlify.yaml +++ /dev/null @@ -1,34 +0,0 @@ -name: Deploy documentation PR preview - -on: - workflow_run: - workflows: [ "Prepare documentation PR preview" ] - types: - - completed - -jobs: - netlify: - if: github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'pull_request' - runs-on: ubuntu-latest - steps: - # There's a 'download artifact' action, but it hasn't been updated for the workflow_run action - # (https://github.com/actions/download-artifact/issues/60) so instead we get this mess: - - name: 📥 Download artifact - uses: dawidd6/action-download-artifact@ac66b43f0e6a346234dd65d4d0c8fbb31cb316e5 # v11 - with: - workflow: docs-pr.yaml - run_id: ${{ github.event.workflow_run.id }} - name: book - path: book - - - name: 📤 Deploy to Netlify - uses: matrix-org/netlify-pr-preview@9805cd123fc9a7e421e35340a05e1ebc5dee46b5 # v3 - with: - path: book - owner: ${{ github.event.workflow_run.head_repository.owner.login }} - branch: ${{ github.event.workflow_run.head_branch }} - revision: ${{ github.event.workflow_run.head_sha }} - token: ${{ secrets.NETLIFY_AUTH_TOKEN }} - site_id: ${{ secrets.NETLIFY_SITE_ID }} - desc: Documentation preview - deployment_env: PR Documentation Preview diff --git a/.github/workflows/docs-pr.yaml b/.github/workflows/docs-pr.yaml index e4b8a4c9f2..cba1293743 100644 --- a/.github/workflows/docs-pr.yaml +++ b/.github/workflows/docs-pr.yaml @@ -13,7 +13,7 @@ jobs: name: GitHub Pages runs-on: ubuntu-latest steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: # Fetch all history so that the schema_versions script works. fetch-depth: 0 @@ -21,10 +21,10 @@ jobs: - name: Setup mdbook uses: peaceiris/actions-mdbook@ee69d230fe19748b7abf22df32acaa93833fad08 # v2.0.0 with: - mdbook-version: '0.4.17' + mdbook-version: '0.5.2' - name: Setup python - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.x" @@ -39,7 +39,7 @@ jobs: cp book/welcome_and_overview.html book/index.html - name: Upload Artifact - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: book path: book @@ -50,12 +50,12 @@ jobs: name: Check links in documentation runs-on: ubuntu-latest steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup mdbook uses: peaceiris/actions-mdbook@ee69d230fe19748b7abf22df32acaa93833fad08 # v2.0.0 with: - mdbook-version: '0.4.17' + mdbook-version: '0.5.2' - name: Setup htmltest run: | @@ -64,8 +64,17 @@ jobs: tar zxf htmltest_0.17.0_linux_amd64.tar.gz - name: Test links with htmltest - # Build the book with `./` as the site URL (to make checks on 404.html possible) - # Then run htmltest (without checking external links since that involves the network and is slow). run: | + # Build the book with `./` as the site URL (to make checks on 404.html possible) MDBOOK_OUTPUT__HTML__SITE_URL="./" mdbook build - ./htmltest book --skip-external + + # Delete the contents of the print.html file, as it can raise false + # positives during link checking. + # + # We empty out the file, instead of deleting it, as doing so would + # just cause htmltest to complain that links to it were invalid. + # Ideally `htmltest` would have an option to ignore specific files + # instead. + echo '' > book/print.html + + ./htmltest book --conf docs/.htmltest.yml diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 0ca45a39cf..31f3b05b8e 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -50,7 +50,7 @@ jobs: needs: - pre steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: # Fetch all history so that the schema_versions script works. fetch-depth: 0 @@ -58,13 +58,13 @@ jobs: - name: Setup mdbook uses: peaceiris/actions-mdbook@ee69d230fe19748b7abf22df32acaa93833fad08 # v2.0.0 with: - mdbook-version: '0.4.17' + mdbook-version: '0.5.2' - name: Set version of docs run: echo 'window.SYNAPSE_VERSION = "${{ needs.pre.outputs.branch-version }}";' > ./docs/website_files/version.js - name: Setup python - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.x" diff --git a/.github/workflows/fix_lint.yaml b/.github/workflows/fix_lint.yaml index d73df1e2e7..aea55fe0ce 100644 --- a/.github/workflows/fix_lint.yaml +++ b/.github/workflows/fix_lint.yaml @@ -18,20 +18,20 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rust uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master with: toolchain: ${{ env.RUST_VERSION }} components: clippy, rustfmt - - uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0 + - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 - name: Setup Poetry uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0 with: install-project: "false" - poetry-version: "2.1.1" + poetry-version: "2.2.1" - name: Run ruff check continue-on-error: true @@ -47,6 +47,6 @@ jobs: - run: cargo fmt continue-on-error: true - - uses: stefanzweifel/git-auto-commit-action@778341af668090896ca464160c2def5d1d1a3eb0 # v6.0.1 + - uses: stefanzweifel/git-auto-commit-action@04702edda442b2e678b25b537cec683a1493fcb9 # v7.1.0 with: commit_message: "Attempt to fix linting" diff --git a/.github/workflows/latest_deps.yml b/.github/workflows/latest_deps.yml index e97109d5fa..746223ef4a 100644 --- a/.github/workflows/latest_deps.yml +++ b/.github/workflows/latest_deps.yml @@ -42,19 +42,19 @@ jobs: if: needs.check_repo.outputs.should_run_workflow == 'true' runs-on: ubuntu-latest steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rust uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master with: toolchain: ${{ env.RUST_VERSION }} - - uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0 + - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 # The dev dependencies aren't exposed in the wheel metadata (at least with current # poetry-core versions), so we install with poetry. - uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0 with: python-version: "3.x" - poetry-version: "2.1.1" + poetry-version: "2.2.1" extras: "all" # Dump installed versions for debugging. - run: poetry run pip list > before.txt @@ -77,13 +77,13 @@ jobs: postgres-version: "14" steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rust uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master with: toolchain: ${{ env.RUST_VERSION }} - - uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0 + - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 - run: sudo apt-get -qq install xmlsec1 - name: Set up PostgreSQL ${{ matrix.postgres-version }} @@ -93,7 +93,7 @@ jobs: -e POSTGRES_PASSWORD=postgres \ -e POSTGRES_INITDB_ARGS="--lc-collate C --lc-ctype C --encoding UTF8" \ postgres:${{ matrix.postgres-version }} - - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.x" - run: pip install .[all,test] @@ -126,7 +126,6 @@ jobs: -exec echo "::endgroup::" \; || true - sytest: needs: check_repo if: needs.check_repo.outputs.should_run_workflow == 'true' @@ -139,9 +138,9 @@ jobs: fail-fast: false matrix: include: - - sytest-tag: bullseye + - sytest-tag: bookworm - - sytest-tag: bullseye + - sytest-tag: bookworm postgres: postgres workers: workers redis: redis @@ -152,13 +151,13 @@ jobs: BLACKLIST: ${{ matrix.workers && 'synapse-blacklist-with-workers' }} steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rust uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master with: toolchain: ${{ env.RUST_VERSION }} - - uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0 + - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 - name: Ensure sytest runs `pip install` # Delete the lockfile so sytest will `pip install` rather than `poetry install` @@ -173,7 +172,7 @@ jobs: if: ${{ always() }} run: /sytest/scripts/tap_to_gha.pl /logs/results.tap - name: Upload SyTest logs - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 if: ${{ always() }} with: name: Sytest Logs - ${{ job.status }} - (${{ join(matrix.*, ', ') }}) @@ -181,7 +180,6 @@ jobs: /logs/results.tap /logs/**/*.log* - complement: needs: check_repo if: "!failure() && !cancelled() && needs.check_repo.outputs.should_run_workflow == 'true'" @@ -202,23 +200,65 @@ jobs: steps: - name: Check out synapse codebase - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: path: synapse - name: Prepare Complement's Prerequisites run: synapse/.ci/scripts/setup_complement_prerequisites.sh - - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: cache-dependency-path: complement/go.sum go-version-file: complement/go.mod - - run: | + - name: Run Complement Tests + id: run_complement_tests + # -p=1: We're using `-p 1` to force the test packages to run serially as GHA boxes + # are underpowered and don't like running tons of Synapse instances at once. + # -json: Output JSON format so that gotestfmt can parse it. + # + # tee /tmp/gotest-complement.log: We tee the output to a file so that we can re-process it + # later on for better formatting with gotestfmt. But we still want the command + # to output to the terminal as it runs so we can see what's happening in + # real-time. + run: | set -o pipefail - TEST_ONLY_IGNORE_POETRY_LOCKFILE=1 POSTGRES=${{ (matrix.database == 'Postgres') && 1 || '' }} WORKERS=${{ (matrix.arrangement == 'workers') && 1 || '' }} COMPLEMENT_DIR=`pwd`/complement synapse/scripts-dev/complement.sh -json 2>&1 | synapse/.ci/scripts/gotestfmt + COMPLEMENT_DIR=`pwd`/complement synapse/scripts-dev/complement.sh -p 1 -json 2>&1 | tee /tmp/gotest-complement.log shell: bash - name: Run Complement Tests + env: + POSTGRES: ${{ (matrix.database == 'Postgres') && 1 || '' }} + WORKERS: ${{ (matrix.arrangement == 'workers') && 1 || '' }} + TEST_ONLY_IGNORE_POETRY_LOCKFILE: 1 + + - name: Formatted Complement test logs + # Always run this step if we attempted to run the Complement tests. + if: always() && steps.run_complement_tests.outcome != 'skipped' + run: cat /tmp/gotest-complement.log | gotestfmt -hide "successful-downloads,empty-packages" + + - name: Run in-repo Complement Tests + id: run_in_repo_complement_tests + # -p=1: We're using `-p 1` to force the test packages to run serially as GHA boxes + # are underpowered and don't like running tons of Synapse instances at once. + # -json: Output JSON format so that gotestfmt can parse it. + # + # tee /tmp/gotest-in-repo-complement.log: We tee the output to a file so that we can re-process it + # later on for better formatting with gotestfmt. But we still want the command + # to output to the terminal as it runs so we can see what's happening in + # real-time. + run: | + set -o pipefail + COMPLEMENT_DIR=`pwd`/complement synapse/scripts-dev/complement.sh --in-repo -p 1 -json 2>&1 | tee /tmp/gotest-in-repo-complement.log + shell: bash + env: + POSTGRES: ${{ (matrix.database == 'Postgres') && 1 || '' }} + WORKERS: ${{ (matrix.arrangement == 'workers') && 1 || '' }} + TEST_ONLY_IGNORE_POETRY_LOCKFILE: 1 + + - name: Formatted in-repo Complement test logs + # Always run this step if we attempted to run the Complement tests. + if: always() && steps.run_in_repo_complement_tests.outcome != 'skipped' + run: cat /tmp/gotest-in-repo-complement.log | gotestfmt -hide "successful-downloads,empty-packages" # Open an issue if the build fails, so we know about it. # Only do this if we're not experimenting with this action in a PR. @@ -234,7 +274,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: JasonEtco/create-an-issue@1b14a70e4d8dc185e5cc76d3bec9eab20257b2c5 # v2.9.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/poetry_lockfile.yaml b/.github/workflows/poetry_lockfile.yaml index 5c8a0d7117..5042a564f2 100644 --- a/.github/workflows/poetry_lockfile.yaml +++ b/.github/workflows/poetry_lockfile.yaml @@ -16,8 +16,8 @@ jobs: name: "Check locked dependencies have sdists" runs-on: ubuntu-latest steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: '3.x' - run: pip install tomli diff --git a/.github/workflows/push_complement_image.yml b/.github/workflows/push_complement_image.yml index bfafe5642a..3931dbebb3 100644 --- a/.github/workflows/push_complement_image.yml +++ b/.github/workflows/push_complement_image.yml @@ -33,29 +33,33 @@ jobs: packages: write steps: - name: Checkout specific branch (debug build) - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 if: github.event_name == 'workflow_dispatch' with: ref: ${{ inputs.branch }} - name: Checkout clean copy of develop (scheduled build) - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 if: github.event_name == 'schedule' with: ref: develop - name: Checkout clean copy of master (on-push) - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 if: github.event_name == 'push' with: ref: master + # We use `poetry` in `complement.sh` + - uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0 + with: + poetry-version: "2.2.1" - name: Login to registry - uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0 + uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Work out labels for complement image id: meta - uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0 + uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0 with: images: ghcr.io/${{ github.repository }}/complement-synapse tags: | @@ -69,6 +73,7 @@ jobs: run: | for TAG in ${{ join(fromJson(steps.meta.outputs.json).tags, ' ') }}; do echo "tag and push $TAG" - docker tag complement-synapse $TAG + # `localhost/complement-synapse` should match the image created by `scripts-dev/complement.sh` + docker tag localhost/complement-synapse $TAG docker push $TAG done diff --git a/.github/workflows/release-artifacts.yml b/.github/workflows/release-artifacts.yml index 8a43f696dc..c313a64250 100644 --- a/.github/workflows/release-artifacts.yml +++ b/.github/workflows/release-artifacts.yml @@ -5,7 +5,7 @@ name: Build release artifacts on: # we build on PRs and develop to (hopefully) get early warning # of things breaking (but only build one set of debs). PRs skip - # building wheels on macOS & ARM. + # building wheels on ARM. pull_request: push: branches: ["develop", "release-*"] @@ -27,8 +27,8 @@ jobs: name: "Calculate list of debian distros" runs-on: ubuntu-latest steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.x" - id: set-distros @@ -55,18 +55,16 @@ jobs: steps: - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: path: src - name: Set up Docker Buildx id: buildx - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - with: - install: true + uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 - name: Set up docker layer caching - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: /tmp/.buildx-cache key: ${{ runner.os }}-buildx-${{ github.sha }} @@ -74,7 +72,7 @@ jobs: ${{ runner.os }}-buildx- - name: Set up python - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.x" @@ -101,7 +99,7 @@ jobs: echo "ARTIFACT_NAME=${DISTRO#*:}" >> "$GITHUB_OUTPUT" - name: Upload debs as artifacts - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: debs-${{ steps.artifact-name.outputs.ARTIFACT_NAME }} path: debs/* @@ -114,47 +112,45 @@ jobs: os: - ubuntu-24.04 - ubuntu-24.04-arm - - macos-13 # This uses x86-64 - - macos-14 # This uses arm64 # is_pr is a flag used to exclude certain jobs from the matrix on PRs. # It is not read by the rest of the workflow. is_pr: - ${{ startsWith(github.ref, 'refs/pull/') }} exclude: - # Don't build macos wheels on PR CI. - - is_pr: true - os: "macos-13" - - is_pr: true - os: "macos-14" # Don't build aarch64 wheels on PR CI. - is_pr: true os: "ubuntu-24.04-arm" steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: # setup-python@v4 doesn't impose a default python version. Need to use 3.x # here, because `python` on osx points to Python 2.7. python-version: "3.x" - name: Install cibuildwheel - run: python -m pip install cibuildwheel==3.0.0 + run: python -m pip install cibuildwheel==3.2.1 - name: Only build a single wheel on PR if: startsWith(github.ref, 'refs/pull/') - run: echo "CIBW_BUILD="cp39-manylinux_*"" >> $GITHUB_ENV + run: echo "CIBW_BUILD="cp310-manylinux_*"" >> $GITHUB_ENV - name: Build wheels run: python -m cibuildwheel --output-dir wheelhouse env: - # Skip testing for platforms which various libraries don't have wheels - # for, and so need extra build deps. - CIBW_TEST_SKIP: pp3*-* *i686* *musl* + # The platforms that we build for are determined by the + # `tool.cibuildwheel.skip` option in `pyproject.toml`. - - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + # We skip testing wheels for the following platforms in CI: + # + # pp3*-* (PyPy wheels) broke in CI (TODO: investigate). + # musl: (TODO: investigate). + CIBW_TEST_SKIP: pp3*-* *musl* + + - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: Wheel-${{ matrix.os }} path: ./wheelhouse/*.whl @@ -165,8 +161,8 @@ jobs: if: ${{ !startsWith(github.ref, 'refs/pull/') }} steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.10" @@ -175,7 +171,7 @@ jobs: - name: Build sdist run: python -m build --sdist - - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: Sdist path: dist/*.tar.gz @@ -191,7 +187,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Download all workflow run artifacts - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - name: Build a tarball for the debs # We need to merge all the debs uploads into one folder, then compress # that. @@ -200,16 +196,11 @@ jobs: mv debs*/* debs/ tar -cvJf debs.tar.xz debs - name: Attach to release - # Pinned to work around https://github.com/softprops/action-gh-release/issues/445 - uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v0.1.15 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - files: | - Sdist/* - Wheel*/* - debs.tar.xz - # if it's not already published, keep the release as a draft. - draft: true - # mark it as a prerelease if the tag contains 'rc'. - prerelease: ${{ contains(github.ref, 'rc') }} + run: | + gh release upload "${{ github.ref_name }}" \ + Sdist/* \ + Wheel*/* \ + debs.tar.xz \ + --repo ${{ github.repository }} diff --git a/.github/workflows/schema.yaml b/.github/workflows/schema.yaml index 53d6bace2c..430ff8861a 100644 --- a/.github/workflows/schema.yaml +++ b/.github/workflows/schema.yaml @@ -14,8 +14,8 @@ jobs: name: Ensure Synapse config schema is valid runs-on: ubuntu-latest steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.x" - name: Install check-jsonschema @@ -40,8 +40,8 @@ jobs: name: Ensure generated documentation is up-to-date runs-on: ubuntu-latest steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.x" - name: Install PyYAML diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ae75369809..488208291f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -26,59 +26,59 @@ jobs: linting: ${{ !startsWith(github.ref, 'refs/pull/') || steps.filter.outputs.linting }} linting_readme: ${{ !startsWith(github.ref, 'refs/pull/') || steps.filter.outputs.linting_readme }} steps: - - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 - id: filter - # We only check on PRs - if: startsWith(github.ref, 'refs/pull/') - with: - filters: | - rust: - - 'rust/**' - - 'Cargo.toml' - - 'Cargo.lock' - - '.rustfmt.toml' - - '.github/workflows/tests.yml' + - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1 + id: filter + # We only check on PRs + if: startsWith(github.ref, 'refs/pull/') + with: + filters: | + rust: + - 'rust/**' + - 'Cargo.toml' + - 'Cargo.lock' + - '.rustfmt.toml' + - '.github/workflows/tests.yml' - trial: - - 'synapse/**' - - 'tests/**' - - 'rust/**' - - '.ci/scripts/calculate_jobs.py' - - 'Cargo.toml' - - 'Cargo.lock' - - 'pyproject.toml' - - 'poetry.lock' - - '.github/workflows/tests.yml' + trial: + - 'synapse/**' + - 'tests/**' + - 'rust/**' + - '.ci/scripts/calculate_jobs.py' + - 'Cargo.toml' + - 'Cargo.lock' + - 'pyproject.toml' + - 'poetry.lock' + - '.github/workflows/tests.yml' - integration: - - 'synapse/**' - - 'rust/**' - - 'docker/**' - - 'Cargo.toml' - - 'Cargo.lock' - - 'pyproject.toml' - - 'poetry.lock' - - 'docker/**' - - '.ci/**' - - 'scripts-dev/complement.sh' - - '.github/workflows/tests.yml' + integration: + - 'synapse/**' + - 'rust/**' + - 'docker/**' + - 'Cargo.toml' + - 'Cargo.lock' + - 'pyproject.toml' + - 'poetry.lock' + - 'docker/**' + - '.ci/**' + - 'scripts-dev/complement.sh' + - '.github/workflows/tests.yml' - linting: - - 'synapse/**' - - 'docker/**' - - 'tests/**' - - 'scripts-dev/**' - - 'contrib/**' - - 'synmark/**' - - 'stubs/**' - - '.ci/**' - - 'mypy.ini' - - 'pyproject.toml' - - 'poetry.lock' - - '.github/workflows/tests.yml' + linting: + - 'synapse/**' + - 'docker/**' + - 'tests/**' + - 'scripts-dev/**' + - 'contrib/**' + - 'synmark/**' + - 'stubs/**' + - '.ci/**' + - 'mypy.ini' + - 'pyproject.toml' + - 'poetry.lock' + - '.github/workflows/tests.yml' - linting_readme: - - 'README.rst' + linting_readme: + - 'README.rst' check-sampleconfig: runs-on: ubuntu-latest @@ -86,16 +86,16 @@ jobs: if: ${{ needs.changes.outputs.linting == 'true' }} steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rust uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master with: toolchain: ${{ env.RUST_VERSION }} - - uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0 + - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 - uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0 with: python-version: "3.x" - poetry-version: "2.1.1" + poetry-version: "2.2.1" extras: "all" - run: poetry run scripts-dev/generate_sample_config.sh --check - run: poetry run scripts-dev/config-lint.sh @@ -106,18 +106,18 @@ jobs: if: ${{ needs.changes.outputs.linting == 'true' }} steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.x" - - run: "pip install 'click==8.1.1' 'GitPython>=3.1.20'" + - run: "pip install 'click==8.1.1' 'GitPython>=3.1.20' 'sqlglot>=28.0.0'" - run: scripts-dev/check_schema_delta.py --force-colors check-lockfile: runs-on: ubuntu-latest steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.x" - run: .ci/scripts/check_lockfile.py @@ -129,12 +129,12 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Poetry uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0 with: - poetry-version: "2.1.1" + poetry-version: "2.2.1" install-project: "false" - name: Run ruff check @@ -151,13 +151,13 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rust uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master with: toolchain: ${{ env.RUST_VERSION }} - - uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0 + - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 - name: Setup Poetry uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0 @@ -169,12 +169,12 @@ jobs: # https://github.com/matrix-org/synapse/pull/15376#issuecomment-1498983775 # To make CI green, err towards caution and install the project. install-project: "true" - poetry-version: "2.1.1" + poetry-version: "2.2.1" # Cribbed from # https://github.com/AustinScola/mypy-cache-github-action/blob/85ea4f2972abed39b33bd02c36e341b28ca59213/src/restore.ts#L10-L17 - name: Restore/persist mypy's cache - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 with: path: | .mypy_cache @@ -187,19 +187,20 @@ jobs: lint-crlf: runs-on: ubuntu-latest steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Check line endings run: scripts-dev/check_line_terminators.sh lint-newsfile: - if: ${{ (github.base_ref == 'develop' || contains(github.base_ref, 'release-')) && github.actor != 'dependabot[bot]' }} + # Only run on pull_request events, targeting develop/release branches, and skip when the PR author is dependabot[bot]. + if: ${{ github.event_name == 'pull_request' && (github.base_ref == 'develop' || contains(github.base_ref, 'release-')) && github.event.pull_request.user.login != 'dependabot[bot]' }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 - - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.x" - run: "pip install 'towncrier>=18.6.0rc1'" @@ -207,40 +208,20 @@ jobs: env: PULL_REQUEST_NUMBER: ${{ github.event.number }} - lint-pydantic: - runs-on: ubuntu-latest - needs: changes - if: ${{ needs.changes.outputs.linting == 'true' }} - - steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - with: - ref: ${{ github.event.pull_request.head.sha }} - - name: Install Rust - uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master - with: - toolchain: ${{ env.RUST_VERSION }} - - uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0 - - uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0 - with: - poetry-version: "2.1.1" - extras: "all" - - run: poetry run scripts-dev/check_pydantic_models.py - lint-clippy: runs-on: ubuntu-latest needs: changes if: ${{ needs.changes.outputs.rust == 'true' }} steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rust uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master with: - components: clippy - toolchain: ${{ env.RUST_VERSION }} - - uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0 + components: clippy + toolchain: ${{ env.RUST_VERSION }} + - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 - run: cargo clippy -- -D warnings @@ -252,14 +233,14 @@ jobs: if: ${{ needs.changes.outputs.rust == 'true' }} steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rust uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master with: - toolchain: nightly-2025-04-23 - components: clippy - - uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0 + toolchain: nightly-2026-02-01 + components: clippy + - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 - run: cargo clippy --all-features -- -D warnings @@ -270,13 +251,13 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rust uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master with: toolchain: ${{ env.RUST_VERSION }} - - uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0 + - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 - name: Setup Poetry uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0 @@ -284,7 +265,7 @@ jobs: # Install like a normal project from source with all optional dependencies extras: all install-project: "true" - poetry-version: "2.1.1" + poetry-version: "2.2.1" - name: Ensure `Cargo.lock` is up to date (no stray changes after install) # The `::error::` syntax is using GitHub Actions' error annotations, see @@ -306,7 +287,7 @@ jobs: if: ${{ needs.changes.outputs.rust == 'true' }} steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rust uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master @@ -315,7 +296,7 @@ jobs: # `.rustfmt.toml`. toolchain: nightly-2025-04-23 components: rustfmt - - uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0 + - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 - run: cargo fmt --check @@ -326,8 +307,8 @@ jobs: needs: changes if: ${{ needs.changes.outputs.linting_readme == 'true' }} steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.x" - run: "pip install rstcheck" @@ -341,7 +322,6 @@ jobs: - lint-mypy - lint-crlf - lint-newsfile - - lint-pydantic - check-sampleconfig - check-schema-delta - check-lockfile @@ -363,21 +343,19 @@ jobs: lint lint-mypy lint-newsfile - lint-pydantic lint-clippy lint-clippy-nightly lint-rust lint-rustfmt lint-readme - calculate-test-jobs: if: ${{ !cancelled() && !failure() }} # Allow previous steps to be skipped, but not fail needs: linting-done runs-on: ubuntu-latest steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.x" - id: get-matrix @@ -394,10 +372,10 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - job: ${{ fromJson(needs.calculate-test-jobs.outputs.trial_test_matrix) }} + job: ${{ fromJson(needs.calculate-test-jobs.outputs.trial_test_matrix) }} steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - run: sudo apt-get -qq install xmlsec1 - name: Set up PostgreSQL ${{ matrix.job.postgres-version }} if: ${{ matrix.job.postgres-version }} @@ -415,12 +393,12 @@ jobs: uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master with: toolchain: ${{ env.RUST_VERSION }} - - uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0 + - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 - uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0 with: python-version: ${{ matrix.job.python-version }} - poetry-version: "2.1.1" + poetry-version: "2.2.1" extras: ${{ matrix.job.extras }} - name: Await PostgreSQL if: ${{ matrix.job.postgres-version }} @@ -453,13 +431,13 @@ jobs: - changes runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rust uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master with: toolchain: ${{ env.RUST_VERSION }} - - uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0 + - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 # There aren't wheels for some of the older deps, so we need to install # their build dependencies @@ -468,19 +446,17 @@ jobs: sudo apt-get -qq install build-essential libffi-dev python3-dev \ libxml2-dev libxslt-dev xmlsec1 zlib1g-dev libjpeg-dev libwebp-dev - - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: - python-version: '3.9' + python-version: "3.10" - name: Prepare old deps - if: steps.cache-poetry-old-deps.outputs.cache-hit != 'true' - run: .ci/scripts/prepare_old_deps.sh - - # Note: we install using `pip` here, not poetry. `poetry install` ignores the - # build-system section (https://github.com/python-poetry/poetry/issues/6154), but - # we explicitly want to test that you can `pip install` using the oldest version - # of poetry-core and setuptools-rust. - - run: pip install .[all,test] + # Note: we install using `uv` here, not poetry or pip to allow us to test with the + # minimum version of all dependencies, both those explicitly specified and those + # implicitly brought in by the explicit dependencies. + run: | + pip install uv + uv pip install --system --resolution=lowest .[all,test] # We nuke the local copy, as we've installed synapse into the virtualenv # (rather than use an editable install, which we no longer support). If we @@ -514,17 +490,17 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["pypy-3.9"] + python-version: ["pypy-3.10"] extras: ["all"] steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 # Install libs necessary for PyPy to build binary wheels for dependencies - run: sudo apt-get -qq install xmlsec1 libxml2-dev libxslt-dev - uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0 with: python-version: ${{ matrix.python-version }} - poetry-version: "2.1.1" + poetry-version: "2.2.1" extras: ${{ matrix.extras }} - run: poetry run trial --jobs=2 tests - name: Dump logs @@ -568,7 +544,7 @@ jobs: job: ${{ fromJson(needs.calculate-test-jobs.outputs.sytest_test_matrix) }} steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Prepare test blacklist run: cat sytest-blacklist .ci/worker-blacklist > synapse-blacklist-with-workers @@ -576,7 +552,7 @@ jobs: uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master with: toolchain: ${{ env.RUST_VERSION }} - - uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0 + - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 - name: Run SyTest run: /bootstrap.sh synapse @@ -585,7 +561,7 @@ jobs: if: ${{ always() }} run: /sytest/scripts/tap_to_gha.pl /logs/results.tap - name: Upload SyTest logs - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 if: ${{ always() }} with: name: Sytest Logs - ${{ job.status }} - (${{ join(matrix.job.*, ', ') }}) @@ -615,11 +591,11 @@ jobs: --health-retries 5 steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - run: sudo apt-get -qq install xmlsec1 postgresql-client - uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0 with: - poetry-version: "2.1.1" + poetry-version: "2.2.1" extras: "postgres" - run: .ci/scripts/test_export_data_command.sh env: @@ -628,7 +604,6 @@ jobs: PGPASSWORD: postgres PGDATABASE: postgres - portdb: if: ${{ !failure() && !cancelled() && needs.changes.outputs.integration == 'true'}} # Allow previous steps to be skipped, but not fail needs: @@ -638,10 +613,10 @@ jobs: strategy: matrix: include: - - python-version: "3.9" - postgres-version: "13" + - python-version: "3.10" + postgres-version: "14" - - python-version: "3.13" + - python-version: "3.14" postgres-version: "17" services: @@ -659,7 +634,7 @@ jobs: --health-retries 5 steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Add PostgreSQL apt repository # We need a version of pg_dump that can handle the version of # PostgreSQL being tested against. The Ubuntu package repository lags @@ -673,7 +648,7 @@ jobs: - uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0 with: python-version: ${{ matrix.python-version }} - poetry-version: "2.1.1" + poetry-version: "2.2.1" extras: "postgres" - run: .ci/scripts/test_synapse_port_db.sh id: run_tester_script @@ -683,7 +658,7 @@ jobs: PGPASSWORD: postgres PGDATABASE: postgres - name: "Upload schema differences" - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 if: ${{ failure() && !cancelled() && steps.run_tester_script.outcome == 'failure' }} with: name: Schema dumps @@ -714,33 +689,124 @@ jobs: steps: - name: Checkout synapse codebase - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: path: synapse + # Log Docker system info for debugging (compare with your local environment) and + # tracking GitHub runner changes over time (can easily compare a run from last + # week with the current one in question). + - run: docker system info + shell: bash + - name: Install Rust uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master with: toolchain: ${{ env.RUST_VERSION }} - - uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0 + - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 + + # We use `poetry` in `complement.sh` + - uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0 + with: + poetry-version: "2.2.1" + # Matches the `path` where we checkout Synapse above + working-directory: "synapse" - name: Prepare Complement's Prerequisites run: synapse/.ci/scripts/setup_complement_prerequisites.sh - - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: cache-dependency-path: complement/go.sum go-version-file: complement/go.mod - # use p=1 concurrency as GHA boxes are underpowered and don't like running tons of synapses at once. - - run: | + # Run the image sanity check test first as this is the first thing we want to know + # about (are we actually testing what we expect?) and we don't want to debug + # downstream failures (wild goose chase). + - name: Sanity check Complement image + id: run_sanity_check_complement_image_test + # -p=1: We're using `-p 1` to force the test packages to run serially as GHA boxes + # are underpowered and don't like running tons of Synapse instances at once. + # -json: Output JSON format so that gotestfmt can parse it. + # + # tee /tmp/gotest-complement.log: We tee the output to a file so that we can re-process it + # later on for better formatting with gotestfmt. But we still want the command + # to output to the terminal as it runs so we can see what's happening in + # real-time. + run: | set -o pipefail - COMPLEMENT_DIR=`pwd`/complement synapse/scripts-dev/complement.sh -p 1 -json 2>&1 | synapse/.ci/scripts/gotestfmt + COMPLEMENT_DIR=`pwd`/complement synapse/scripts-dev/complement.sh --in-repo -p 1 -json -run 'TestSynapseVersion/Synapse_version_matches_current_git_checkout' 2>&1 | tee /tmp/gotest-sanity-check-complement.log shell: bash env: POSTGRES: ${{ (matrix.database == 'Postgres') && 1 || '' }} WORKERS: ${{ (matrix.arrangement == 'workers') && 1 || '' }} - name: Run Complement Tests + + - name: Formatted sanity check Complement test logs + # Always run this step if we attempted to run the Complement tests. + if: always() && steps.run_sanity_check_complement_image_test.outcome != 'skipped' + # We do not hide successful tests in `gotestfmt` here as the list of sanity + # check tests is so short. Feel free to change this when we get more tests. + # + # Note that the `-hide` argument is interpreted by `gotestfmt`. From it, + # it derives several values under `$settings` and passes them to our + # custom `.ci/complement_package.gotpl` template to render the output. + run: cat /tmp/gotest-sanity-check-complement.log | gotestfmt -hide "successful-downloads,empty-packages" + + - name: Run Complement Tests + id: run_complement_tests + # -p=1: We're using `-p 1` to force the test packages to run serially as GHA boxes + # are underpowered and don't like running tons of Synapse instances at once. + # -json: Output JSON format so that gotestfmt can parse it. + # + # tee /tmp/gotest-complement.log: We tee the output to a file so that we can re-process it + # later on for better formatting with gotestfmt. But we still want the command + # to output to the terminal as it runs so we can see what's happening in + # real-time. + run: | + set -o pipefail + COMPLEMENT_DIR=`pwd`/complement synapse/scripts-dev/complement.sh -p 1 -json 2>&1 | tee /tmp/gotest-complement.log + shell: bash + env: + POSTGRES: ${{ (matrix.database == 'Postgres') && 1 || '' }} + WORKERS: ${{ (matrix.arrangement == 'workers') && 1 || '' }} + + - name: Formatted Complement test logs (only failing are shown) + # Always run this step if we attempted to run the Complement tests. + if: always() && steps.run_complement_tests.outcome != 'skipped' + # Hide successful tests in order to reduce the verbosity of the otherwise very large output. + # + # Note that the `-hide` argument is interpreted by `gotestfmt`. From it, + # it derives several values under `$settings` and passes them to our + # custom `.ci/complement_package.gotpl` template to render the output. + run: cat /tmp/gotest-complement.log | gotestfmt -hide "successful-downloads,successful-tests,empty-packages" + + - name: Run in-repo Complement Tests + id: run_in_repo_complement_tests + # -p=1: We're using `-p 1` to force the test packages to run serially as GHA boxes + # are underpowered and don't like running tons of Synapse instances at once. + # -json: Output JSON format so that gotestfmt can parse it. + # + # tee /tmp/gotest-in-repo-complement.log: We tee the output to a file so that we can re-process it + # later on for better formatting with gotestfmt. But we still want the command + # to output to the terminal as it runs so we can see what's happening in + # real-time. + run: | + set -o pipefail + COMPLEMENT_DIR=`pwd`/complement synapse/scripts-dev/complement.sh --in-repo -p 1 -json 2>&1 | tee /tmp/gotest-in-repo-complement.log + shell: bash + env: + POSTGRES: ${{ (matrix.database == 'Postgres') && 1 || '' }} + WORKERS: ${{ (matrix.arrangement == 'workers') && 1 || '' }} + + - name: Formatted in-repo Complement test logs (only failing are shown) + # Always run this step if we attempted to run the Complement tests. + if: always() && steps.run_in_repo_complement_tests.outcome != 'skipped' + # Hide successful tests in order to reduce the verbosity of the otherwise very large output. + # + # Note that the `-hide` argument is interpreted by `gotestfmt`. From it, + # it derives several values under `$settings` and passes them to our + # custom `.ci/complement_package.gotpl` template to render the output. + run: cat /tmp/gotest-in-repo-complement.log | gotestfmt -hide "successful-downloads,successful-tests,empty-packages" cargo-test: if: ${{ needs.changes.outputs.rust == 'true' }} @@ -750,13 +816,13 @@ jobs: - changes steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rust uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master with: toolchain: ${{ env.RUST_VERSION }} - - uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0 + - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 - run: cargo test @@ -770,13 +836,13 @@ jobs: - changes steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rust uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master with: - toolchain: nightly-2022-12-01 - - uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0 + toolchain: nightly-2022-12-01 + - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 - run: cargo bench --no-run diff --git a/.github/workflows/triage_labelled.yml b/.github/workflows/triage_labelled.yml index 41f535a15d..31dddab012 100644 --- a/.github/workflows/triage_labelled.yml +++ b/.github/workflows/triage_labelled.yml @@ -6,43 +6,26 @@ on: jobs: move_needs_info: - name: Move X-Needs-Info on the triage board runs-on: ubuntu-latest if: > contains(github.event.issue.labels.*.name, 'X-Needs-Info') + permissions: + contents: read + env: + # This token must have the following scopes: ["repo:public_repo", "admin:org->read:org", "user->read:user", "project"] + GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }} + PROJECT_OWNER: matrix-org + # Backend issue triage board. + # https://github.com/orgs/matrix-org/projects/67/views/1 + PROJECT_NUMBER: 67 + ISSUE_URL: ${{ github.event.issue.html_url }} + # This field is case-sensitive. + TARGET_STATUS: Needs info steps: - - uses: actions/add-to-project@4515659e2b458b27365e167605ac44f219494b66 # v1.0.2 - id: add_project + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: - project-url: "https://github.com/orgs/matrix-org/projects/67" - github-token: ${{ secrets.ELEMENT_BOT_TOKEN }} - # This action will error if the issue already exists on the project. Which is - # common as `X-Needs-Info` will often be added to issues that are already in - # the triage queue. Prevent the whole job from failing in this case. - continue-on-error: true - - name: Set status - env: - GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }} - run: | - gh api graphql -f query=' - mutation( - $project: ID! - $item: ID! - $fieldid: ID! - $columnid: String! - ) { - updateProjectV2ItemFieldValue( - input: { - projectId: $project - itemId: $item - fieldId: $fieldid - value: { - singleSelectOptionId: $columnid - } - } - ) { - projectV2Item { - id - } - } - }' -f project="PVT_kwDOAIB0Bs4AFDdZ" -f item=${{ steps.add_project.outputs.itemId }} -f fieldid="PVTSSF_lADOAIB0Bs4AFDdZzgC6ZA4" -f columnid=ba22e43c --silent + # Only clone the script file we care about, instead of the whole repo. + sparse-checkout: .ci/scripts/triage_labelled_issue.sh + + - name: Ensure issue exists on the board, then set Status + run: .ci/scripts/triage_labelled_issue.sh diff --git a/.github/workflows/twisted_trunk.yml b/.github/workflows/twisted_trunk.yml index fbe1270767..be73e5283b 100644 --- a/.github/workflows/twisted_trunk.yml +++ b/.github/workflows/twisted_trunk.yml @@ -12,10 +12,9 @@ on: twisted_ref: description: Commit, branch or tag to checkout from upstream Twisted. required: false - default: 'trunk' + default: "trunk" type: string - concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true @@ -43,19 +42,19 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rust uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master with: toolchain: ${{ env.RUST_VERSION }} - - uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0 + - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 - uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0 with: python-version: "3.x" extras: "all" - poetry-version: "2.1.1" + poetry-version: "2.2.1" - run: | poetry remove twisted poetry add --extras tls git+https://github.com/twisted/twisted.git#${{ inputs.twisted_ref || 'trunk' }} @@ -70,26 +69,25 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - run: sudo apt-get -qq install xmlsec1 - name: Install Rust uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master with: toolchain: ${{ env.RUST_VERSION }} - - uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0 + - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 - uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0 with: python-version: "3.x" extras: "all test" - poetry-version: "2.1.1" + poetry-version: "2.2.1" - run: | poetry remove twisted poetry add --extras tls git+https://github.com/twisted/twisted.git#trunk poetry install --no-interaction --extras "all test" - run: poetry run trial --jobs 2 tests - - name: Dump logs # Logs are most useful when the command fails, always include them. if: ${{ always() }} @@ -108,22 +106,22 @@ jobs: if: needs.check_repo.outputs.should_run_workflow == 'true' runs-on: ubuntu-latest container: - # We're using debian:bullseye because it uses Python 3.9 which is our minimum supported Python version. + # We're using bookworm because that's what Debian oldstable is at the time of writing. # This job is a canary to warn us about unreleased twisted changes that would cause problems for us if # they were to be released immediately. For simplicity's sake (and to save CI runners) we use the oldest # version, assuming that any incompatibilities on newer versions would also be present on the oldest. - image: matrixdotorg/sytest-synapse:bullseye + image: matrixdotorg/sytest-synapse:bookworm volumes: - ${{ github.workspace }}:/src steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rust uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # master with: toolchain: ${{ env.RUST_VERSION }} - - uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0 + - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 - name: Patch dependencies # Note: The poetry commands want to create a virtualenv in /src/.venv/, @@ -147,7 +145,7 @@ jobs: if: ${{ always() }} run: /sytest/scripts/tap_to_gha.pl /logs/results.tap - name: Upload SyTest logs - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 if: ${{ always() }} with: name: Sytest Logs - ${{ job.status }} - (${{ join(matrix.*, ', ') }}) @@ -175,14 +173,14 @@ jobs: steps: - name: Run actions/checkout@v4 for synapse - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: path: synapse - name: Prepare Complement's Prerequisites run: synapse/.ci/scripts/setup_complement_prerequisites.sh - - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0 with: cache-dependency-path: complement/go.sum go-version-file: complement/go.mod @@ -199,11 +197,53 @@ jobs: poetry lock working-directory: synapse - - run: | + - name: Run Complement Tests + id: run_complement_tests + # -p=1: We're using `-p 1` to force the test packages to run serially as GHA boxes + # are underpowered and don't like running tons of Synapse instances at once. + # -json: Output JSON format so that gotestfmt can parse it. + # + # tee /tmp/gotest-complement.log: We tee the output to a file so that we can re-process it + # later on for better formatting with gotestfmt. But we still want the command + # to output to the terminal as it runs so we can see what's happening in + # real-time. + run: | set -o pipefail - TEST_ONLY_SKIP_DEP_HASH_VERIFICATION=1 POSTGRES=${{ (matrix.database == 'Postgres') && 1 || '' }} WORKERS=${{ (matrix.arrangement == 'workers') && 1 || '' }} COMPLEMENT_DIR=`pwd`/complement synapse/scripts-dev/complement.sh -json 2>&1 | synapse/.ci/scripts/gotestfmt + COMPLEMENT_DIR=`pwd`/complement synapse/scripts-dev/complement.sh -p 1 -json 2>&1 | tee /tmp/gotest-complement.log shell: bash - name: Run Complement Tests + env: + POSTGRES: ${{ (matrix.database == 'Postgres') && 1 || '' }} + WORKERS: ${{ (matrix.arrangement == 'workers') && 1 || '' }} + TEST_ONLY_SKIP_DEP_HASH_VERIFICATION: 1 + + - name: Formatted Complement test logs + # Always run this step if we attempted to run the Complement tests. + if: always() && steps.run_complement_tests.outcome != 'skipped' + run: cat /tmp/gotest-complement.log | gotestfmt -hide "successful-downloads,empty-packages" + + - name: Run in-repo Complement Tests + id: run_in_repo_complement_tests + # -p=1: We're using `-p 1` to force the test packages to run serially as GHA boxes + # are underpowered and don't like running tons of Synapse instances at once. + # -json: Output JSON format so that gotestfmt can parse it. + # + # tee /tmp/gotest-in-repo-complement.log: We tee the output to a file so that we can re-process it + # later on for better formatting with gotestfmt. But we still want the command + # to output to the terminal as it runs so we can see what's happening in + # real-time. + run: | + set -o pipefail + COMPLEMENT_DIR=`pwd`/complement synapse/scripts-dev/complement.sh --in-repo -p 1 -json 2>&1 | tee /tmp/gotest-in-repo-complement.log + shell: bash + env: + POSTGRES: ${{ (matrix.database == 'Postgres') && 1 || '' }} + WORKERS: ${{ (matrix.arrangement == 'workers') && 1 || '' }} + TEST_ONLY_SKIP_DEP_HASH_VERIFICATION: 1 + + - name: Formatted in-repo Complement test logs + # Always run this step if we attempted to run the Complement tests. + if: always() && steps.run_in_repo_complement_tests.outcome != 'skipped' + run: cat /tmp/gotest-in-repo-complement.log | gotestfmt -hide "successful-downloads,empty-packages" # open an issue if the build fails, so we know about it. open-issue: @@ -217,7 +257,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: JasonEtco/create-an-issue@1b14a70e4d8dc185e5cc76d3bec9eab20257b2c5 # v2.9.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/CHANGES.md b/CHANGES.md index 76f4645905..c6e06aad49 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,985 @@ +# Synapse 1.151.0 (2026-04-07) + +## Bugfixes + +- Fix `KNOWN_ROOM_VERSIONS.__contains__` raising `TypeError` for non-string keys, which could cause `/sync` to fail for rooms with a `NULL` room version in the database. Bug introduced in [#19589](https://github.com/element-hq/synapse/pull/19589) as part of v1.151.0rc1. ([\#19649](https://github.com/element-hq/synapse/issues/19649)) + + + + +# Synapse 1.151.0rc1 (2026-03-31) + +## Features + +- Add stable support for [MSC4284](https://github.com/matrix-org/matrix-spec-proposals/pull/4284) Policy Servers. ([\#19503](https://github.com/element-hq/synapse/issues/19503)) +- Update and stabilize support for [MSC2666](https://github.com/matrix-org/matrix-spec-proposals/pull/2666): Get rooms in common with another user. Contributed by @tulir @ Beeper. ([\#19511](https://github.com/element-hq/synapse/issues/19511)) +- Updated experimental support for [MSC4388: Secure out-of-band channel for sign in with QR](https://github.com/matrix-org/matrix-spec-proposals/pull/4388). ([\#19573](https://github.com/element-hq/synapse/issues/19573)) +- Stabilize `room_version` and `encryption` fields in the space/room `/hierarchy` API (part of [MSC3266](https://github.com/matrix-org/matrix-spec-proposals/pull/3266)). ([\#19576](https://github.com/element-hq/synapse/issues/19576)) +- Introduce a [configuration option](https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#matrix_authentication_service) to allow using HTTP/2 over plaintext when Synapse connects to Matrix Authentication Service. ([\#19586](https://github.com/element-hq/synapse/issues/19586)) + +## Bugfixes + +- Fix [MSC4284](https://github.com/matrix-org/matrix-spec-proposals/pull/4284) Policy Servers implementation to skip signing `org.matrix.msc4284.policy` and `m.room.policy` state events. ([\#19503](https://github.com/element-hq/synapse/issues/19503)) +- Correctly apply [MSC4284](https://github.com/matrix-org/matrix-spec-proposals/pull/4284) Policy Server signatures to events when the sender and policy server have the same server name. ([\#19503](https://github.com/element-hq/synapse/issues/19503)) +- Allow Synapse to start up even when discovery fails for an OpenID Connect provider. ([\#19509](https://github.com/element-hq/synapse/issues/19509)) +- Fix quarantine media admin APIs sometimes returning inaccurate counts for remote media. ([\#19559](https://github.com/element-hq/synapse/issues/19559)) +- Fix `Build and push complement image` CI job not having `poetry` available for the Complement runner script. ([\#19578](https://github.com/element-hq/synapse/issues/19578)) +- Increase timeout for policy server requests to avoid repeated requests for checking media. ([\#19629](https://github.com/element-hq/synapse/issues/19629)) + +## Deprecations and Removals + +- Remove support for [MSC3852: Expose user agent information on Device](https://github.com/matrix-org/matrix-spec-proposals/pull/3852) as the MSC was closed. ([\#19430](https://github.com/element-hq/synapse/issues/19430)) + +## Internal Changes + +- Fix small comment typo in config output from the `demo/start.sh` script. ([\#19538](https://github.com/element-hq/synapse/issues/19538)) +- Add MSC3820 comment context to `RoomVersion` attributes. ([\#19577](https://github.com/element-hq/synapse/issues/19577)) +- Remove `redacted_because` from internal unsigned. ([\#19581](https://github.com/element-hq/synapse/issues/19581)) +- Prevent sending registration emails if registration is disabled. ([\#19585](https://github.com/element-hq/synapse/issues/19585)) +- Port `RoomVersion` to Rust. ([\#19589](https://github.com/element-hq/synapse/issues/19589)) +- Only show failing Complement tests in the formatted output in CI. ([\#19590](https://github.com/element-hq/synapse/issues/19590)) +- Ensure old Complement test files are removed when downloading a Complement checkout via `./scripts-dev/complement.sh`. ([\#19592](https://github.com/element-hq/synapse/issues/19592)) +- Update `HomeserverTestCase.pump()` docstring to demystify behavior (Twisted reactor/clock). ([\#19602](https://github.com/element-hq/synapse/issues/19602)) +- Deprecate `HomeserverTestCase.pump()` in favor of more direct `HomeserverTestCase.reactor.advance(...)` usage. ([\#19602](https://github.com/element-hq/synapse/issues/19602)) +- Lower the Postgres database `statement_timeout` to 10m (previously 1h). ([\#19604](https://github.com/element-hq/synapse/issues/19604)) + + + + +# Synapse 1.150.0 (2026-03-24) + +No significant changes since 1.150.0rc1. + + + + +# Synapse 1.150.0rc1 (2026-03-17) + +## Features + +- Add experimental support for the [MSC4370](https://github.com/matrix-org/matrix-spec-proposals/pull/4370) Federation API `GET /extremities` endpoint. ([\#19314](https://github.com/element-hq/synapse/issues/19314)) +- [MSC4140: Cancellable delayed events](https://github.com/matrix-org/matrix-spec-proposals/pull/4140): When persisting a delayed event to the timeline, include its `delay_id` in the event's `unsigned` section in `/sync` responses to the event sender. ([\#19479](https://github.com/element-hq/synapse/issues/19479)) +- Expose [MSC4354 Sticky Events](https://github.com/matrix-org/matrix-spec-proposals/pull/4354) over the legacy (v3) /sync API. ([\#19487](https://github.com/element-hq/synapse/issues/19487)) +- When Matrix Authentication Service (MAS) integration is enabled, allow MAS to set the user locked status in Synapse. ([\#19554](https://github.com/element-hq/synapse/issues/19554)) + +## Bugfixes + +- Fix `Build and push complement image` CI job pointing to non-existent image. ([\#19523](https://github.com/element-hq/synapse/issues/19523)) +- Fix a bug introduced in v1.26.0 that caused deactivated, erased users to not be removed from the user directory. ([\#19542](https://github.com/element-hq/synapse/issues/19542)) + +## Improved Documentation + +- In the Admin API documentation, always express path parameters as `/` instead of as `/$param`. ([\#19307](https://github.com/element-hq/synapse/issues/19307)) +- Update docs to clarify `outbound_federation_restricted_to` can also be used with the [Secure Border Gateway (SBG)](https://element.io/en/server-suite/secure-border-gateways). ([\#19517](https://github.com/element-hq/synapse/issues/19517)) +- Unify Complement developer docs. ([\#19518](https://github.com/element-hq/synapse/issues/19518)) + +## Internal Changes + +- Put membership updates in a background resumable task when changing the avatar or the display name. ([\#19311](https://github.com/element-hq/synapse/issues/19311)) +- Add in-repo Complement test to sanity check Synapse version matches git checkout (testing what we think we are). ([\#19476](https://github.com/element-hq/synapse/issues/19476)) +- Migrate `dev` dependencies to [PEP 735](https://peps.python.org/pep-0735/) dependency groups. ([\#19490](https://github.com/element-hq/synapse/issues/19490)) +- Remove the optional `systemd-python` dependency and the `systemd` extra on the `synapse` package. ([\#19491](https://github.com/element-hq/synapse/issues/19491)) +- Avoid re-computing the event ID when cloning events. ([\#19527](https://github.com/element-hq/synapse/issues/19527)) +- Allow caching of the `/versions` and `/auth_metadata` public endpoints. ([\#19530](https://github.com/element-hq/synapse/issues/19530)) +- Add a few labels to the number groupings in the `Processed request` logs. ([\#19548](https://github.com/element-hq/synapse/issues/19548)) + + + + +# Synapse 1.149.1 (2026-03-11) + +## Internal Changes + +- Bump `matrix-synapse-ldap3` to `0.4.0` to support `setuptools>=82.0.0`. Fixes [\#19541](https://github.com/element-hq/synapse/issues/19541). ([\#19543](https://github.com/element-hq/synapse/issues/19543)) + + + + +# Synapse 1.149.0 (2026-03-10) + +No significant changes since 1.149.0rc1. + + + + +# Synapse 1.149.0rc1 (2026-03-03) + +## Features + +- Add experimental support for [MSC4388: Secure out-of-band channel for sign in with QR](https://github.com/matrix-org/matrix-spec-proposals/pull/4388). ([\#19127](https://github.com/element-hq/synapse/issues/19127)) +- Add stable support for [MSC4380](https://github.com/matrix-org/matrix-spec-proposals/pull/4380) invite blocking. ([\#19431](https://github.com/element-hq/synapse/issues/19431)) + +## Bugfixes + +- Fix the 'Login as a user' Admin API not checking if the user exists before issuing an access token. ([\#18518](https://github.com/element-hq/synapse/issues/18518)) +- Fix `/sync` missing membership event in `state_after` (experimental [MSC4222](https://github.com/matrix-org/matrix-spec-proposals/pull/4222) implementation) in some scenarios. ([\#19460](https://github.com/element-hq/synapse/issues/19460)) + +## Internal Changes + +- Add log to explain when and why we freeze objects in the garbage collector. ([\#19440](https://github.com/element-hq/synapse/issues/19440)) +- Better instrument `JoinRoomAliasServlet` with tracing. ([\#19461](https://github.com/element-hq/synapse/issues/19461)) +- Fix Complement CI not running against the code from our PRs. ([\#19475](https://github.com/element-hq/synapse/issues/19475)) +- Log `docker system info` in CI so we have a plain record of how GitHub runners evolve over time. ([\#19480](https://github.com/element-hq/synapse/issues/19480)) +- Rename the `test_disconnect` test helper so that pytest doesn't see it as a test. ([\#19486](https://github.com/element-hq/synapse/issues/19486)) +- Add a log line when we delete devices. Contributed by @bradtgmurray @ Beeper. ([\#19496](https://github.com/element-hq/synapse/issues/19496)) +- Pre-allocate the buffer based on the expected `Content-Length` with the Rust HTTP client. ([\#19498](https://github.com/element-hq/synapse/issues/19498)) +- Cancel long-running sync requests if the client has gone away. ([\#19499](https://github.com/element-hq/synapse/issues/19499)) +- Try and reduce reactor tick times when under heavy load. ([\#19507](https://github.com/element-hq/synapse/issues/19507)) +- Simplify Rust HTTP client response streaming and limiting. ([\#19510](https://github.com/element-hq/synapse/issues/19510)) +- Replace deprecated collection import locations with current locations. ([\#19515](https://github.com/element-hq/synapse/issues/19515)) +- Bump most locked Python dependencies to their latest versions. ([\#19519](https://github.com/element-hq/synapse/issues/19519)) + + + + +# Synapse 1.148.0 (2026-02-24) + +No significant changes since 1.148.0rc1. + + + + +# Synapse 1.148.0rc1 (2026-02-17) + +## Features + +- Support sending and receiving [MSC4354 Sticky Event](https://github.com/matrix-org/matrix-spec-proposals/pull/4354) metadata. ([\#19365](https://github.com/element-hq/synapse/issues/19365)) + +## Improved Documentation + +- Fix reference to the `experimental_features` section of the configuration manual documentation. ([\#19435](https://github.com/element-hq/synapse/issues/19435)) + +## Deprecations and Removals + +- Remove support for [MSC3244: Room version capabilities](https://github.com/matrix-org/matrix-spec-proposals/pull/3244) as the MSC was rejected. ([\#19429](https://github.com/element-hq/synapse/issues/19429)) + +## Internal Changes + +- Add in-repo Complement tests so we can test Synapse specific behavior at an end-to-end level. ([\#19406](https://github.com/element-hq/synapse/issues/19406)) +- Push Synapse docker images to Element OCI Registry. ([\#19420](https://github.com/element-hq/synapse/issues/19420)) +- Allow configuring the Rust HTTP client to use HTTP/2 only. ([\#19457](https://github.com/element-hq/synapse/issues/19457)) +- Correctly refuse to start if the Rust workspace config has changed and the Rust library has not been rebuilt. ([\#19470](https://github.com/element-hq/synapse/issues/19470)) + + + + +# Synapse 1.147.1 (2026-02-12) + +## Internal Changes + +- Block federation requests and events authenticated using a known insecure signing key. See [CVE-2026-24044](https://www.cve.org/CVERecord?id=CVE-2026-24044) / [ELEMENTSEC-2025-1670](https://github.com/element-hq/ess-helm/security/advisories/GHSA-qwcj-h6m8-vp6q). ([\#19459](https://github.com/element-hq/synapse/issues/19459)) + + + + +# Synapse 1.147.0 (2026-02-10) + +No significant changes since 1.147.0rc1. + +# Synapse 1.147.0rc1 (2026-02-03) + +## Bugfixes + +- Fix memory leak caused by not cleaning up stopped looping calls. Introduced in v1.140.0. ([\#19416](https://github.com/element-hq/synapse/issues/19416)) +- Fix a typo that incorrectly made `setuptools_rust` a runtime dependency. ([\#19417](https://github.com/element-hq/synapse/issues/19417)) + +## Internal Changes + +- Prune stale entries from `sliding_sync_connection_required_state` table. ([\#19306](https://github.com/element-hq/synapse/issues/19306)) +- Update "Event Send Time Quantiles" graph to only use dots for the event persistence rate (Grafana dashboard). ([\#19399](https://github.com/element-hq/synapse/issues/19399)) +- Update and align Grafana dashboard to use regex matching for `job` selectors (`job=~"$job"`) so the "all" value works correctly across all panels. ([\#19400](https://github.com/element-hq/synapse/issues/19400)) +- Don't retry joining partial state rooms all at once on startup. ([\#19402](https://github.com/element-hq/synapse/issues/19402)) +- Disallow requests to the health endpoint from containing trailing path characters. ([\#19405](https://github.com/element-hq/synapse/issues/19405)) +- Add notes that new experimental features should have associated tracking issues. ([\#19410](https://github.com/element-hq/synapse/issues/19410)) +- Bump `pyo3` from 0.26.0 to 0.27.2 and `pythonize` from 0.26.0 to 0.27.0. Contributed by @razvp @ ERCOM. ([\#19412](https://github.com/element-hq/synapse/issues/19412)) + + + + +# Synapse 1.146.0 (2026-01-27) + +No significant changes since 1.146.0rc1. + +## Deprecations and Removals + +- [MSC2697](https://github.com/matrix-org/matrix-spec-proposals/pull/2697) (Dehydrated devices) has been removed, as the MSC is closed. Developers should migrate to [MSC3814](https://github.com/matrix-org/matrix-spec-proposals/pull/3814). ([\#19346](https://github.com/element-hq/synapse/issues/19346)) +- Support for Ubuntu 25.04 (Plucky Puffin) has been dropped. Synapse no longer builds debian packages for Ubuntu 25.04. + + + +# Synapse 1.146.0rc1 (2026-01-20) + +## Features + +- Add a new config option [`enable_local_media_storage`](https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#enable_local_media_storage) which controls whether media is additionally stored locally when using configured `media_storage_providers`. Setting this to `false` allows off-site media storage without a local cache. Contributed by Patrice Brend'amour @dr.allgood. ([\#19204](https://github.com/element-hq/synapse/issues/19204)) +- Stabilise support for [MSC4312](https://github.com/matrix-org/matrix-spec-proposals/pull/4312)'s `m.oauth` User-Interactive Auth stage for resetting cross-signing identity with the OAuth 2.0 API. The old, unstable name (`org.matrix.cross_signing_reset`) is now deprecated and will be removed in a future release. ([\#19273](https://github.com/element-hq/synapse/issues/19273)) +- Refactor Grafana dashboard to use `server_name` label (instead of `instance`). ([\#19337](https://github.com/element-hq/synapse/issues/19337)) + +## Bugfixes + +- Fix joining a restricted v12 room locally when no local room creator is present but local users with sufficient power levels are. Contributed by @nexy7574. ([\#19321](https://github.com/element-hq/synapse/issues/19321)) +- Fixed parallel calls to `/_matrix/media/v1/create` being ratelimited for appservices even if `rate_limited: false` was set in the registration. Contributed by @tulir @ Beeper. ([\#19335](https://github.com/element-hq/synapse/issues/19335)) +- Fix a bug introduced in 1.61.0 where a user's membership in a room was accidentally ignored when considering access to historical state events in rooms with the "shared" history visibility. Contributed by Lukas Tautz. ([\#19353](https://github.com/element-hq/synapse/issues/19353)) +- [MSC4140](https://github.com/matrix-org/matrix-spec-proposals/pull/4140): Store the JSON content of scheduled delayed events as text instead of a byte array. This fixes the inability to schedule a delayed event with non-ASCII characters in its content. ([\#19360](https://github.com/element-hq/synapse/issues/19360)) +- Always rollback database transactions when retrying (avoid orphaned connections). ([\#19372](https://github.com/element-hq/synapse/issues/19372)) +- Fix `InFlightGauge` typing to allow upgrading to `prometheus_client` 0.24. ([\#19379](https://github.com/element-hq/synapse/issues/19379)) + +## Updates to the Docker image + +- Add [Prometheus HTTP service discovery](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#http_sd_config) endpoint for easy discovery of all workers when using the `docker/Dockerfile-workers` image (see the [*Metrics* section of our Docker testing docs](docker/README-testing.md#metrics)). ([\#19336](https://github.com/element-hq/synapse/issues/19336)) + +## Improved Documentation + +- Remove docs on legacy metric names (no longer in the codebase since 2022-12-06). ([\#19341](https://github.com/element-hq/synapse/issues/19341)) +- Clarify how the estimated value of room complexity is calculated internally. ([\#19384](https://github.com/element-hq/synapse/issues/19384)) + +## Internal Changes + +- Add an internal `cancel_task` API to the task scheduler. ([\#19310](https://github.com/element-hq/synapse/issues/19310)) +- Tweak docstrings and signatures of `auth_types_for_event` and `get_catchup_room_event_ids`. ([\#19320](https://github.com/element-hq/synapse/issues/19320)) +- Replace usage of deprecated `assertEquals` with `assertEqual` in unit test code. ([\#19345](https://github.com/element-hq/synapse/issues/19345)) +- Drop support for Ubuntu 25.04 'Plucky Puffin', add support for Ubuntu 25.10 'Questing Quokka'. ([\#19348](https://github.com/element-hq/synapse/issues/19348)) +- Revert "Add an Admin API endpoint for listing quarantined media (#19268)". ([\#19351](https://github.com/element-hq/synapse/issues/19351)) +- Bump `mdbook` from 0.4.17 to 0.5.2 and remove our custom table-of-contents plugin in favour of the new default functionality. ([\#19356](https://github.com/element-hq/synapse/issues/19356)) +- Replace deprecated usage of PyGitHub's `GitRelease.title` with `.name` in release script. ([\#19358](https://github.com/element-hq/synapse/issues/19358)) +- Update the Element logo in Synapse's README to be an absolute URL, allowing it to render on other sites (such as PyPI). ([\#19368](https://github.com/element-hq/synapse/issues/19368)) +- Apply minor tweaks to v1.145.0 changelog. ([\#19376](https://github.com/element-hq/synapse/issues/19376)) +- Update Grafana dashboard syntax to use the latest from importing/exporting with Grafana 12.3.1. ([\#19381](https://github.com/element-hq/synapse/issues/19381)) +- Warn about skipping reactor metrics when using unknown reactor type. ([\#19383](https://github.com/element-hq/synapse/issues/19383)) +- Add support for reactor metrics with the `ProxiedReactor` used in worker Complement tests. ([\#19385](https://github.com/element-hq/synapse/issues/19385)) + + + + +# Synapse 1.145.0 (2026-01-13) + +No significant changes since 1.145.0rc4. + +## End of Life of Ubuntu 25.04 Plucky Puffin + +Ubuntu 25.04 (Plucky Puffin) will be end of life on Jan 17, 2026. Synapse will stop building packages for Ubuntu 25.04 shortly thereafter. + +## Updates to Locked Dependencies No Longer Included in Changelog + +The "Updates to locked dependencies" section has been removed from the changelog due to lack of use and the maintenance burden. ([\#19254](https://github.com/element-hq/synapse/issues/19254)) + + + + +# Synapse 1.145.0rc4 (2026-01-08) + +No significant changes since 1.145.0rc3. + +This RC contains a fix specifically for openSUSE packaging and no other changes. + + + +# Synapse 1.145.0rc3 (2026-01-07) + +No significant changes since 1.145.0rc2. + +This RC strips out unnecessary files from the wheels that were added when fixing the source distribution packaging in the previous RC. + + + +# Synapse 1.145.0rc2 (2026-01-07) + +No significant changes since 1.145.0rc1. + +This RC fixes the source distribution packaging for uploading to PyPI. + + + +# Synapse 1.145.0rc1 (2026-01-06) + +## Features + +- Add `memberships` endpoint to the admin API. This is useful for forensics and T&S purposes. ([\#19260](https://github.com/element-hq/synapse/issues/19260)) +- Server admins can bypass the quarantine media check when downloading media by setting the `admin_unsafely_bypass_quarantine` query parameter to `true` on Client-Server API media download requests. ([\#19275](https://github.com/element-hq/synapse/issues/19275)) +- Implemented pagination for the [MSC2666](https://github.com/matrix-org/matrix-spec-proposals/pull/2666) mutual rooms endpoint. Contributed by @tulir @ Beeper. ([\#19279](https://github.com/element-hq/synapse/issues/19279)) +- Admin API: add worker support to `GET /_synapse/admin/v2/users/`. ([\#19281](https://github.com/element-hq/synapse/issues/19281)) +- Improve proxy support for the `federation_client.py` dev script. Contributed by Denis Kasak (@dkasak). ([\#19300](https://github.com/element-hq/synapse/issues/19300)) + +## Bugfixes + +- Fix sliding sync performance slow down for long lived connections. ([\#19206](https://github.com/element-hq/synapse/issues/19206)) +- Fix a bug where Mastodon posts (and possibly other embeds) have the wrong description for URL previews. ([\#19231](https://github.com/element-hq/synapse/issues/19231)) +- Fix bug where `Duration` was logged incorrectly. ([\#19267](https://github.com/element-hq/synapse/issues/19267)) +- Fix bug introduced in 1.143.0 that broke support for versions of `zope-interface` older than 6.2. ([\#19274](https://github.com/element-hq/synapse/issues/19274)) +- Transform events with client metadata before serialising in /event response. ([\#19340](https://github.com/element-hq/synapse/issues/19340)) + +## Updates to the Docker image + +- Add a way to expose metrics from the Docker image (`SYNAPSE_ENABLE_METRICS`). ([\#19324](https://github.com/element-hq/synapse/issues/19324)) + +## Improved Documentation + +- Document the importance of `public_baseurl` when configuring OpenID Connect authentication. ([\#19270](https://github.com/element-hq/synapse/issues/19270)) + +## Deprecations and Removals + +- Ubuntu 25.04 (Plucky Puffin) will be end of life on Jan 17, 2026. Synapse will stop building packages for Ubuntu 25.04 shortly thereafter. +- Remove the "Updates to locked dependencies" section from the changelog due to lack of use and the maintenance burden. ([\#19254](https://github.com/element-hq/synapse/issues/19254)) + +## Internal Changes + +- Group together dependabot update PRs to reduce the review load. ([\#18402](https://github.com/element-hq/synapse/issues/18402)) +- Fix `HomeServer.shutdown()` failing if the homeserver hasn't been setup yet. ([\#19187](https://github.com/element-hq/synapse/issues/19187)) +- Respond with useful error codes with `Content-Length` header/s are invalid. ([\#19212](https://github.com/element-hq/synapse/issues/19212)) +- Fix `HomeServer.shutdown()` failing if the homeserver failed to `start`. ([\#19232](https://github.com/element-hq/synapse/issues/19232)) +- Switch the build backend from `poetry-core` to `maturin`. ([\#19234](https://github.com/element-hq/synapse/issues/19234)) +- Raise the limit for concurrently-open non-security @dependabot PRs from 5 to 10. ([\#19253](https://github.com/element-hq/synapse/issues/19253)) +- Require 14 days to pass before pulling in general dependency updates to help mitigate upstream supply chain attacks. ([\#19258](https://github.com/element-hq/synapse/issues/19258)) +- Drop the broken netlify documentation workflow until a new one is implemented. ([\#19262](https://github.com/element-hq/synapse/issues/19262)) +- Don't include debug logs in `Clock` unless explicitly enabled. ([\#19278](https://github.com/element-hq/synapse/issues/19278)) +- Use `uv` to test olddeps to ensure all transitive dependencies use minimum versions. ([\#19289](https://github.com/element-hq/synapse/issues/19289)) +- Add a config to be able to rate limit search in the user directory. ([\#19291](https://github.com/element-hq/synapse/issues/19291)) +- Log the original bind exception when encountering `Failed to listen on 0.0.0.0, continuing because listening on [::]`. ([\#19297](https://github.com/element-hq/synapse/issues/19297)) +- Unpin the version of Rust we use to build Synapse wheels (was 1.82.0) now that MacOS support has been dropped. ([\#19302](https://github.com/element-hq/synapse/issues/19302)) +- Make it more clear how `shared_extra_conf` is combined in our Docker configuration scripts. ([\#19323](https://github.com/element-hq/synapse/issues/19323)) +- Update CI to stream Complement progress and format logs in a separate step after all tests are done. ([\#19326](https://github.com/element-hq/synapse/issues/19326)) +- Format `.github/workflows/tests.yml`. ([\#19327](https://github.com/element-hq/synapse/issues/19327)) + + + + +# Synapse 1.144.0 (2025-12-09) + +## Deprecation of MacOS Python wheels + +The team has decided to deprecate and stop publishing python wheels for MacOS. +Synapse docker images will continue to work on MacOS, as will building Synapse +from source (though note this requires a Rust compiler). + +## Unstable mutual rooms endpoint is now behind an experimental feature flag + +Admins using the unstable [MSC2666](https://github.com/matrix-org/matrix-spec-proposals/pull/2666) endpoint (`/_matrix/client/unstable/uk.half-shot.msc2666/user/mutual_rooms`), +please check [the relevant section in the upgrade notes](https://github.com/element-hq/synapse/blob/develop/docs/upgrade.md#upgrading-to-v11440) as this release contains changes +that disable that endpoint by default. + + + +No significant changes since 1.144.0rc1. + + + + +# Synapse 1.144.0rc1 (2025-12-02) + +Admins using the unstable [MSC2666](https://github.com/matrix-org/matrix-spec-proposals/pull/2666) endpoint (`/_matrix/client/unstable/uk.half-shot.msc2666/user/mutual_rooms`), please check [the relevant section in the upgrade notes](https://github.com/element-hq/synapse/blob/develop/docs/upgrade.md#upgrading-to-v11440) as this release contains changes that disable that endpoint by default. + +## Features + +- Add experimentatal implememntation of [MSC4380](https://github.com/matrix-org/matrix-spec-proposals/pull/4380) (invite blocking). ([\#19203](https://github.com/element-hq/synapse/issues/19203)) +- Allow restarting delayed event timeouts on workers. ([\#19207](https://github.com/element-hq/synapse/issues/19207)) + +## Bugfixes + +- Fix a bug in the database function for fetching state deltas that could result in unnecessarily long query times. ([\#18960](https://github.com/element-hq/synapse/issues/18960)) +- Fix v12 rooms when running with `use_frozen_dicts: True`. ([\#19235](https://github.com/element-hq/synapse/issues/19235)) +- Fix bug where invalid `canonical_alias` content would return 500 instead of 400. ([\#19240](https://github.com/element-hq/synapse/issues/19240)) +- Fix bug where `Duration` was logged incorrectly. ([\#19267](https://github.com/element-hq/synapse/issues/19267)) + +## Improved Documentation + +- Document in the `--config-path` help how multiple files are merged - by merging them shallowly. ([\#19243](https://github.com/element-hq/synapse/issues/19243)) + +## Deprecations and Removals + +- Stop building release wheels for MacOS. ([\#19225](https://github.com/element-hq/synapse/issues/19225)) + +## Internal Changes + +- Improve event filtering for Simplified Sliding Sync. ([\#17782](https://github.com/element-hq/synapse/issues/17782)) +- Export `SYNAPSE_SUPPORTED_COMPLEMENT_TEST_PACKAGES` environment variable from `scripts-dev/complement.sh`. ([\#19208](https://github.com/element-hq/synapse/issues/19208)) +- Refactor `scripts-dev/complement.sh` logic to avoid `exit` to facilitate being able to source it from other scripts (composable). ([\#19209](https://github.com/element-hq/synapse/issues/19209)) +- Expire sliding sync connections that are too old or have too much pending data. ([\#19211](https://github.com/element-hq/synapse/issues/19211)) +- Require an experimental feature flag to be enabled in order for the unstable [MSC2666](https://github.com/matrix-org/matrix-spec-proposals/pull/2666) endpoint (`/_matrix/client/unstable/uk.half-shot.msc2666/user/mutual_rooms`) to be available. ([\#19219](https://github.com/element-hq/synapse/issues/19219)) +- Prevent changelog check CI running on @dependabot's PRs even when a human has modified the branch. ([\#19220](https://github.com/element-hq/synapse/issues/19220)) +- Auto-fix trailing spaces in multi-line strings and comments when running the lint script. ([\#19221](https://github.com/element-hq/synapse/issues/19221)) +- Move towards using a dedicated `Duration` type. ([\#19223](https://github.com/element-hq/synapse/issues/19223), [\#19229](https://github.com/element-hq/synapse/issues/19229)) +- Improve robustness of the SQL schema linting in CI. ([\#19224](https://github.com/element-hq/synapse/issues/19224)) +- Add log to determine whether clients are using `/messages` as expected. ([\#19226](https://github.com/element-hq/synapse/issues/19226)) +- Simplify README and add ESS Getting started section. ([\#19228](https://github.com/element-hq/synapse/issues/19228), [\#19259](https://github.com/element-hq/synapse/issues/19259)) +- Add a unit test for ensuring associated refresh tokens are erased when a device is deleted. ([\#19230](https://github.com/element-hq/synapse/issues/19230)) +- Prompt user to consider adding future deprecations to the changelog in release script. ([\#19239](https://github.com/element-hq/synapse/issues/19239)) +- Fix check of the Rust compiled code being outdated when using source checkout and `.egg-info`. ([\#19251](https://github.com/element-hq/synapse/issues/19251)) +- Stop building macos wheels in CI pipeline. ([\#19263](https://github.com/element-hq/synapse/issues/19263)) + + + +### Updates to locked dependencies + +* Bump Swatinem/rust-cache from 2.8.1 to 2.8.2. ([\#19244](https://github.com/element-hq/synapse/issues/19244)) +* Bump actions/checkout from 5.0.0 to 6.0.0. ([\#19213](https://github.com/element-hq/synapse/issues/19213)) +* Bump actions/setup-go from 6.0.0 to 6.1.0. ([\#19214](https://github.com/element-hq/synapse/issues/19214)) +* Bump actions/setup-python from 6.0.0 to 6.1.0. ([\#19245](https://github.com/element-hq/synapse/issues/19245)) +* Bump attrs from 25.3.0 to 25.4.0. ([\#19215](https://github.com/element-hq/synapse/issues/19215)) +* Bump docker/metadata-action from 5.9.0 to 5.10.0. ([\#19246](https://github.com/element-hq/synapse/issues/19246)) +* Bump http from 1.3.1 to 1.4.0. ([\#19249](https://github.com/element-hq/synapse/issues/19249)) +* Bump pydantic from 2.12.4 to 2.12.5. ([\#19250](https://github.com/element-hq/synapse/issues/19250)) +* Bump pyopenssl from 25.1.0 to 25.3.0. ([\#19248](https://github.com/element-hq/synapse/issues/19248)) +* Bump rpds-py from 0.28.0 to 0.29.0. ([\#19216](https://github.com/element-hq/synapse/issues/19216)) +* Bump rpds-py from 0.29.0 to 0.30.0. ([\#19247](https://github.com/element-hq/synapse/issues/19247)) +* Bump sentry-sdk from 2.44.0 to 2.46.0. ([\#19218](https://github.com/element-hq/synapse/issues/19218)) +* Bump types-bleach from 6.2.0.20250809 to 6.3.0.20251115. ([\#19217](https://github.com/element-hq/synapse/issues/19217)) +* Bump types-jsonschema from 4.25.1.20250822 to 4.25.1.20251009. ([\#19252](https://github.com/element-hq/synapse/issues/19252)) + +# Synapse 1.143.0 (2025-11-25) + +## Dropping support for PostgreSQL 13 + +In line with our [deprecation policy](https://github.com/element-hq/synapse/blob/develop/docs/deprecation_policy.md), we've dropped +support for PostgreSQL 13, as it is no longer supported upstream. +This release of Synapse requires PostgreSQL 14+. + +No significant changes since 1.143.0rc2. + + + + +# Synapse 1.143.0rc2 (2025-11-18) + +## Dropping support for PostgreSQL 13 + +In line with our [deprecation policy](https://github.com/element-hq/synapse/blob/develop/docs/deprecation_policy.md), we've dropped +support for PostgreSQL 13, as it is no longer supported upstream. +This release of Synapse requires PostgreSQL 14+. + + +## Internal Changes + +- Fixes docker image creation in the release workflow. + + + +# Synapse 1.143.0rc1 (2025-11-18) + +## Features + +- Support multiple config files in `register_new_matrix_user`. ([\#18784](https://github.com/element-hq/synapse/issues/18784)) +- Remove authentication from `POST /_matrix/client/v1/delayed_events`, and allow calling this endpoint with the update action to take (`send`/`cancel`/`restart`) in the request path instead of the body. ([\#19152](https://github.com/element-hq/synapse/issues/19152)) + +## Bugfixes + +- Fixed a longstanding bug where background updates were only run on the `main` database. ([\#19181](https://github.com/element-hq/synapse/issues/19181)) +- Fixed a bug introduced in v1.142.0 preventing subpaths in MAS endpoints from working. ([\#19186](https://github.com/element-hq/synapse/issues/19186)) +- Fix the SQLite-to-PostgreSQL migration script to correctly migrate a boolean column in the `delayed_events` table. ([\#19155](https://github.com/element-hq/synapse/issues/19155)) + +## Improved Documentation + +- Improve documentation around streams, particularly ID generators and adding new streams. ([\#18943](https://github.com/element-hq/synapse/issues/18943)) + +## Deprecations and Removals + +- Remove support for PostgreSQL 13. ([\#19170](https://github.com/element-hq/synapse/issues/19170)) + +## Internal Changes + +- Provide additional servers with federation room directory results. ([\#18970](https://github.com/element-hq/synapse/issues/18970)) +- Add a shortcut return when there are no events to purge. ([\#19093](https://github.com/element-hq/synapse/issues/19093)) +- Write union types as `X | Y` where possible, as per PEP 604, added in Python 3.10. ([\#19111](https://github.com/element-hq/synapse/issues/19111)) +- Reduce cardinality of `synapse_storage_events_persisted_events_sep_total` metric by removing `origin_entity` label. This also separates out events sent by local application services by changing the `origin_type` for such events to `application_service`. The `type` field also only tracks common event types, and anything else is bucketed under `*other*`. ([\#19133](https://github.com/element-hq/synapse/issues/19133), [\#19168](https://github.com/element-hq/synapse/issues/19168)) +- Run trial tests on Python 3.14 for PRs. ([\#19135](https://github.com/element-hq/synapse/issues/19135)) +- Update `pyproject.toml` project metadata to be compatible with standard Python packaging tooling. ([\#19137](https://github.com/element-hq/synapse/issues/19137)) +- Minor speed up of processing of inbound replication. ([\#19138](https://github.com/element-hq/synapse/issues/19138), [\#19145](https://github.com/element-hq/synapse/issues/19145), [\#19146](https://github.com/element-hq/synapse/issues/19146)) +- Ignore recent Python language refactors from git blame (`.git-blame-ignore-revs`). ([\#19150](https://github.com/element-hq/synapse/issues/19150)) +- Bump lower bounds of dependencies `parameterized` to `0.9.0` and `idna` to `3.3` as those are the first to advertise support for Python 3.10. ([\#19167](https://github.com/element-hq/synapse/issues/19167)) +- Point out which event caused the exception when checking [MSC4293](https://github.com/matrix-org/matrix-spec-proposals/pull/4293) redactions. ([\#19169](https://github.com/element-hq/synapse/issues/19169)) +- Restore printing `sentinel` for the log record `request` when no logcontext is active. ([\#19172](https://github.com/element-hq/synapse/issues/19172)) +- Add debug logs to track `Clock` utilities. ([\#19173](https://github.com/element-hq/synapse/issues/19173)) +- Remove explicit python version skips in `cibuildwheel` config as it's no longer required after [#19137](https://github.com/element-hq/synapse/pull/19137). ([\#19177](https://github.com/element-hq/synapse/issues/19177)) +- Fix potential lost logcontext when `PerDestinationQueue.shutdown(...)` is called. ([\#19178](https://github.com/element-hq/synapse/issues/19178)) +- Fix bad deferred logcontext handling across the codebase. ([\#19180](https://github.com/element-hq/synapse/issues/19180)) + + + +### Updates to locked dependencies + +* Bump bytes from 1.10.1 to 1.11.0. ([\#19193](https://github.com/element-hq/synapse/issues/19193)) +* Bump click from 8.1.8 to 8.3.1. ([\#19195](https://github.com/element-hq/synapse/issues/19195)) +* Bump cryptography from 43.0.3 to 45.0.7. ([\#19159](https://github.com/element-hq/synapse/issues/19159)) +* Bump docker/metadata-action from 5.8.0 to 5.9.0. ([\#19161](https://github.com/element-hq/synapse/issues/19161)) +* Bump pydantic from 2.12.3 to 2.12.4. ([\#19158](https://github.com/element-hq/synapse/issues/19158)) +* Bump pyo3-log from 0.13.1 to 0.13.2. ([\#19156](https://github.com/element-hq/synapse/issues/19156)) +* Bump ruff from 0.14.3 to 0.14.5. ([\#19196](https://github.com/element-hq/synapse/issues/19196)) +* Bump sentry-sdk from 2.34.1 to 2.43.0. ([\#19157](https://github.com/element-hq/synapse/issues/19157)) +* Bump sentry-sdk from 2.43.0 to 2.44.0. ([\#19197](https://github.com/element-hq/synapse/issues/19197)) +* Bump tomli from 2.2.1 to 2.3.0. ([\#19194](https://github.com/element-hq/synapse/issues/19194)) +* Bump types-netaddr from 1.3.0.20240530 to 1.3.0.20251108. ([\#19160](https://github.com/element-hq/synapse/issues/19160)) + + + +# Synapse 1.142.1 (2025-11-18) + +## Bugfixes + +- Fixed a bug introduced in v1.142.0 preventing subpaths in MAS endpoints from working. ([\#19186](https://github.com/element-hq/synapse/issues/19186)) + + + + +# Synapse 1.142.0 (2025-11-11) + +## Dropped support for Python 3.9 + +This release drops support for Python 3.9, in line with our [dependency +deprecation +policy](https://element-hq.github.io/synapse/latest/deprecation_policy.html#platform-dependencies), +as it is now [end of life](https://endoflife.date/python). + +## SQLite 3.40.0+ is now required + +The minimum supported SQLite version has been increased from 3.27.0 to 3.40.0. + +If you use current versions of the +[matrixorg/synapse](setup/installation.html#docker-images-and-ansible-playbooks) +Docker images, no action is required. + + +## Deprecation of MacOS Python wheels + +The team has decided to deprecate and eventually stop publishing python wheels +for MacOS. This is a burden on the team, and we're not aware of any parties +that use them. Synapse docker images will continue to work on MacOS, as will +building Synapse from source (though note this requires a Rust compiler). + +At present, publishing MacOS Python wheels will continue for the next release +(1.143.0), but will not be available after that (1.144.0+). If you do make use +of these wheels downstream, please reach out to us in +[#synapse-dev:matrix.org](https://matrix.to/#/#synapse-dev:matrix.org). We'd +love to hear from you! + +## Internal Changes + +- Properly stop building wheels for Python 3.9 and free-threaded CPython. ([\#19154](https://github.com/element-hq/synapse/issues/19154)) + + + + +# Synapse 1.142.0rc4 (2025-11-07) + +## Bugfixes + +- Fix a bug introduced in 1.142.0rc1 where any attempt to configure `matrix_authentication_service.secret_path` would prevent the homeserver from starting up. ([\#19144](https://github.com/element-hq/synapse/issues/19144)) + + + + +# Synapse 1.142.0rc3 (2025-11-04) + +## Internal Changes + +- Update release scripts to prevent building wheels for free-threaded Python, as Synapse does not currently support it. ([\#19140](https://github.com/element-hq/synapse/issues/19140)) + + +# Synapse 1.142.0rc2 (2025-11-04) + + +## Internal Changes + +- Manually skip building Python 3.9 wheels, to prevent errors in the release workflow. ([\#19119](https://github.com/element-hq/synapse/issues/19119)) + + + + +# Synapse 1.142.0rc1 (2025-11-04) + +## Features + +- Add support for Python 3.14. ([\#19055](https://github.com/element-hq/synapse/issues/19055), [\#19134](https://github.com/element-hq/synapse/issues/19134)) +- Add an [Admin API](https://element-hq.github.io/synapse/latest/usage/administration/admin_api/index.html) + to allow an admin to fetch the space/room hierarchy for a given space. ([\#19021](https://github.com/element-hq/synapse/issues/19021)) + +## Bugfixes + +- Fix a bug introduced in 1.111.0 where failed attempts to download authenticated remote media would not be handled correctly. ([\#19062](https://github.com/element-hq/synapse/issues/19062)) +- Update the `oidc_session_no_samesite` cookie to have the `Secure` attribute, so the only difference between it and the paired `oidc_session` cookie, is the configuration of the `SameSite` attribute as described in the comments / cookie names. Contributed by @kieranlane. ([\#19079](https://github.com/element-hq/synapse/issues/19079)) +- Fix a bug introduced in 1.140.0 where lost logcontext warnings would be emitted from timeouts in sync and requests made by Synapse itself. ([\#19090](https://github.com/element-hq/synapse/issues/19090)) +- Fix a bug introdued in 1.140.0 where lost logcontext warning were emitted when using `HomeServer.shutdown()`. ([\#19108](https://github.com/element-hq/synapse/issues/19108)) + +## Improved Documentation + +- Update the link to the Debian oldstable package for SQLite. ([\#19047](https://github.com/element-hq/synapse/issues/19047)) +- Point out additional Redis configuration options available in the worker docs. Contributed by @servisbryce. ([\#19073](https://github.com/element-hq/synapse/issues/19073)) +- Update the list of Debian releases that the downstream Debian package is maintained for. ([\#19100](https://github.com/element-hq/synapse/issues/19100)) +- Add [a page](https://element-hq.github.io/synapse/latest/development/internal_documentation/release_notes_review_checklist.html) to the documentation describing the steps the Synapse team takes to review the release notes before publishing them. ([\#19109](https://github.com/element-hq/synapse/issues/19109)) + +## Deprecations and Removals + +- Drop support for Python 3.9. ([\#19099](https://github.com/element-hq/synapse/issues/19099)) +- Remove support for SQLite < 3.37.2. ([\#19047](https://github.com/element-hq/synapse/issues/19047)) + +## Internal Changes + +- Fix CI linter for schema delta files to correctly handle all types of `CREATE TABLE` syntax. ([\#19020](https://github.com/element-hq/synapse/issues/19020)) +- Use type hinting generics in standard collections, as per [PEP 585](https://peps.python.org/pep-0585/), added in Python 3.9. ([\#19046](https://github.com/element-hq/synapse/issues/19046)) +- Always treat `RETURNING` as supported by SQL engines, now that the minimum-supported versions of both SQLite and PostgreSQL support it. ([\#19047](https://github.com/element-hq/synapse/issues/19047)) +- Move `oidc.load_metadata()` startup into `_base.start()`. ([\#19056](https://github.com/element-hq/synapse/issues/19056)) +- Remove logcontext problems caused by awaiting raw `deferLater(...)`. ([\#19058](https://github.com/element-hq/synapse/issues/19058)) +- Prevent duplicate logging setup when running multiple Synapse instances. ([\#19067](https://github.com/element-hq/synapse/issues/19067)) +- Be mindful of other logging context filters in 3rd-party code and avoid overwriting log record fields unless we know the log record is relevant to Synapse. ([\#19068](https://github.com/element-hq/synapse/issues/19068)) +- Update pydantic to v2. ([\#19071](https://github.com/element-hq/synapse/issues/19071)) +- Update deprecated code in the release script to prevent a warning message from being printed. ([\#19080](https://github.com/element-hq/synapse/issues/19080)) +- Update the deprecated poetry development dependencies group name in `pyproject.toml`. ([\#19081](https://github.com/element-hq/synapse/issues/19081)) +- Remove `pp38*` skip selector from cibuildwheel to silence warning. ([\#19085](https://github.com/element-hq/synapse/issues/19085)) +- Don't immediately exit the release script if the checkout is dirty. Instead, allow the user to clear the dirty changes and retry. ([\#19088](https://github.com/element-hq/synapse/issues/19088)) +- Update the release script's generated announcement text to include a title and extra text for RC's. ([\#19089](https://github.com/element-hq/synapse/issues/19089)) +- Fix lints on main branch. ([\#19092](https://github.com/element-hq/synapse/issues/19092)) +- Use cheaper random string function in logcontext utilities. ([\#19094](https://github.com/element-hq/synapse/issues/19094)) +- Avoid clobbering other `SIGHUP` handlers in 3rd-party code. ([\#19095](https://github.com/element-hq/synapse/issues/19095)) +- Prevent duplicate GitHub draft releases being created during the Synapse release process. ([\#19096](https://github.com/element-hq/synapse/issues/19096)) +- Use Pillow's `Image.getexif` method instead of the experimental `Image._getexif`. ([\#19098](https://github.com/element-hq/synapse/issues/19098)) +- Prevent uv `/usr/local/.lock` file from appearing in built Synapse docker images. ([\#19107](https://github.com/element-hq/synapse/issues/19107)) +- Allow Synapse's runtime dependency checking code to take packaging markers (i.e. `python <= 3.14`) into account when checking dependencies. ([\#19110](https://github.com/element-hq/synapse/issues/19110)) +- Move exception handling up the stack (avoid `exit(1)` in our composable functions). ([\#19116](https://github.com/element-hq/synapse/issues/19116)) +- Fix a lint error related to lifetimes in Rust 1.90. ([\#19118](https://github.com/element-hq/synapse/issues/19118)) +- Refactor and align app entrypoints (avoid `exit(1)` in our composable functions). ([\#19121](https://github.com/element-hq/synapse/issues/19121), [\#19131](https://github.com/element-hq/synapse/issues/19131)) +- Speed up pruning of ratelimiters. ([\#19129](https://github.com/element-hq/synapse/issues/19129)) + + + +### Updates to locked dependencies + +* Bump actions/download-artifact from 5.0.0 to 6.0.0. ([\#19102](https://github.com/element-hq/synapse/issues/19102)) +* Bump actions/upload-artifact from 4 to 5. ([\#19106](https://github.com/element-hq/synapse/issues/19106)) +* Bump hiredis from 3.2.1 to 3.3.0. ([\#19103](https://github.com/element-hq/synapse/issues/19103)) +* Bump icu_segmenter from 2.0.0 to 2.0.1. ([\#19126](https://github.com/element-hq/synapse/issues/19126)) +* Bump idna from 3.10 to 3.11. ([\#19053](https://github.com/element-hq/synapse/issues/19053)) +* Bump ijson from 3.4.0 to 3.4.0.post0. ([\#19051](https://github.com/element-hq/synapse/issues/19051)) +* Bump markdown-it-py from 3.0.0 to 4.0.0. ([\#19123](https://github.com/element-hq/synapse/issues/19123)) +* Bump msgpack from 1.1.1 to 1.1.2. ([\#19050](https://github.com/element-hq/synapse/issues/19050)) +* Bump psycopg2 from 2.9.10 to 2.9.11. ([\#19125](https://github.com/element-hq/synapse/issues/19125)) +* Bump pyyaml from 6.0.2 to 6.0.3. ([\#19105](https://github.com/element-hq/synapse/issues/19105)) +* Bump regex from 1.11.3 to 1.12.2. ([\#19074](https://github.com/element-hq/synapse/issues/19074)) +* Bump reqwest from 0.12.23 to 0.12.24. ([\#19077](https://github.com/element-hq/synapse/issues/19077)) +* Bump ruff from 0.12.10 to 0.14.3. ([\#19124](https://github.com/element-hq/synapse/issues/19124)) +* Bump sigstore/cosign-installer from 3.10.0 to 4.0.0. ([\#19075](https://github.com/element-hq/synapse/issues/19075)) +* Bump stefanzweifel/git-auto-commit-action from 6.0.1 to 7.0.0. ([\#19052](https://github.com/element-hq/synapse/issues/19052)) +* Bump tokio from 1.47.1 to 1.48.0. ([\#19076](https://github.com/element-hq/synapse/issues/19076)) +* Bump types-psycopg2 from 2.9.21.20250915 to 2.9.21.20251012. ([\#19054](https://github.com/element-hq/synapse/issues/19054)) + +# Synapse 1.141.0 (2025-10-29) + +## Deprecation of MacOS Python wheels + +The team has decided to deprecate and eventually stop publishing python wheels +for MacOS. This is a burden on the team, and we're not aware of any parties +that use them. Synapse docker images will continue to work on MacOS, as will +building Synapse from source (though note this requires a Rust compiler). + +Publishing MacOS Python wheels will continue for the next few releases. If you +do make use of these wheels downstream, please reach out to us in +[#synapse-dev:matrix.org](https://matrix.to/#/#synapse-dev:matrix.org). We'd +love to hear from you! + + +## Docker images now based on Debian `trixie` with Python 3.13 + +The Docker images are now based on Debian `trixie` and use Python 3.13. If you +are using the Docker images as a base image you may need to e.g. adjust the +paths you mount any additional Python packages at. + +No significant changes since 1.141.0rc2. + + + + +# Synapse 1.141.0rc2 (2025-10-28) + +## Bugfixes + +- Fix users being unable to log in if their password, or the server's configured pepper, was too long. ([\#19101](https://github.com/element-hq/synapse/issues/19101)) + + + + +# Synapse 1.141.0rc1 (2025-10-21) + +## Features + +- Allow using [MSC4190](https://github.com/matrix-org/matrix-spec-proposals/pull/4190) behavior without the opt-in registration flag. Contributed by @tulir @ Beeper. ([\#19031](https://github.com/element-hq/synapse/issues/19031)) +- Stabilized support for [MSC4326](https://github.com/matrix-org/matrix-spec-proposals/pull/4326): Device masquerading for appservices. Contributed by @tulir @ Beeper. ([\#19033](https://github.com/element-hq/synapse/issues/19033)) + +## Bugfixes + +- Fix a bug introduced in 1.136.0 that would prevent Synapse from being able to be `reload`-ed more than once when running under systemd. ([\#19060](https://github.com/element-hq/synapse/issues/19060)) +- Fix a bug introduced in 1.140.0 where an internal server error could be raised when hashing user passwords that are too long. ([\#19078](https://github.com/element-hq/synapse/issues/19078)) + +## Updates to the Docker image + +- Update docker image to use Debian trixie as the base and thus Python 3.13. ([\#19064](https://github.com/element-hq/synapse/issues/19064)) + +## Internal Changes + +- Move unique snowflake homeserver background tasks to `start_background_tasks` (the standard pattern for this kind of thing). ([\#19037](https://github.com/element-hq/synapse/issues/19037)) +- Drop a deprecated field of the `PyGitHub` dependency in the release script and raise the dependency's minimum version to `1.59.0`. ([\#19039](https://github.com/element-hq/synapse/issues/19039)) +- Update TODO list of conflicting areas where we encounter metrics being clobbered (`ApplicationService`). ([\#19040](https://github.com/element-hq/synapse/issues/19040)) + + + + +# Synapse 1.140.0 (2025-10-14) + +## Compatibility notice for users of `synapse-s3-storage-provider` + +Deployments that make use of the +[synapse-s3-storage-provider](https://github.com/matrix-org/synapse-s3-storage-provider) +module must upgrade to +[v1.6.0](https://github.com/matrix-org/synapse-s3-storage-provider/releases/tag/v1.6.0). +Using older versions of the module with this release of Synapse will prevent +users from being able to upload or download media. + + +No significant changes since 1.140.0rc1. + + + + +# Synapse 1.140.0rc1 (2025-10-10) + +## Features + +- Add [a new Media Query by ID Admin API](https://element-hq.github.io/synapse/v1.140/admin_api/media_admin_api.html#query-a-piece-of-media-by-id) that allows server admins to query and investigate the metadata of local or cached remote media via + the `origin/media_id` identifier found in a [Matrix Content URI](https://spec.matrix.org/v1.14/client-server-api/#matrix-content-mxc-uris). ([\#18911](https://github.com/element-hq/synapse/issues/18911)) +- Add [a new Fetch Event Admin API](https://element-hq.github.io/synapse/v1.140/admin_api/fetch_event.html) to fetch an event by ID. ([\#18963](https://github.com/element-hq/synapse/issues/18963)) +- Update [MSC4284: Policy Servers](https://github.com/matrix-org/matrix-spec-proposals/pull/4284) implementation to support signatures when available. ([\#18934](https://github.com/element-hq/synapse/issues/18934)) +- Add experimental implementation of the `GET /_matrix/client/v1/rtc/transports` endpoint for the latest draft of [MSC4143: MatrixRTC](https://github.com/matrix-org/matrix-spec-proposals/pull/4143). ([\#18967](https://github.com/element-hq/synapse/issues/18967)) +- Expose a `defer_to_threadpool` function in the Synapse Module API that allows modules to run a function on a separate thread in a custom threadpool. ([\#19032](https://github.com/element-hq/synapse/issues/19032)) + +## Bugfixes + +- Fix room upgrade `room_config` argument and documentation for `user_may_create_room` spam-checker callback. ([\#18721](https://github.com/element-hq/synapse/issues/18721)) +- Compute a user's last seen timestamp from their devices' last seen timestamps instead of IPs, because the latter are automatically cleared according to `user_ips_max_age`. ([\#18948](https://github.com/element-hq/synapse/issues/18948)) +- Fix bug where ephemeral events were not filtered by room ID. Contributed by @frastefanini. ([\#19002](https://github.com/element-hq/synapse/issues/19002)) +- Update Synapse main process version string to include git info. ([\#19011](https://github.com/element-hq/synapse/issues/19011)) + +## Improved Documentation + +- Explain how `Deferred` callbacks interact with logcontexts. ([\#18914](https://github.com/element-hq/synapse/issues/18914)) +- Fix documentation for `rc_room_creation` and `rc_reports` to clarify that a `per_user` rate limit is not supported. ([\#18998](https://github.com/element-hq/synapse/issues/18998)) + +## Deprecations and Removals + +- Remove deprecated `LoggingContext.set_current_context`/`LoggingContext.current_context` methods which already have equivalent bare methods in `synapse.logging.context`. ([\#18989](https://github.com/element-hq/synapse/issues/18989)) +- Drop support for unstable field names from the long-accepted [MSC2732](https://github.com/matrix-org/matrix-spec-proposals/pull/2732) (Olm fallback keys) proposal. ([\#18996](https://github.com/element-hq/synapse/issues/18996)) + +## Internal Changes + +- Cleanly shutdown `SynapseHomeServer` object, allowing artifacts of embedded small hosts to be properly garbage collected. ([\#18828](https://github.com/element-hq/synapse/issues/18828)) +- Update OEmbed providers to use 'X' instead of 'Twitter' in URL previews, following a rebrand. Contributed by @HammyHavoc. ([\#18767](https://github.com/element-hq/synapse/issues/18767)) +- Fix `server_name` in logging context for multiple Synapse instances in one process. ([\#18868](https://github.com/element-hq/synapse/issues/18868)) +- Wrap the Rust HTTP client with `make_deferred_yieldable` so it follows Synapse logcontext rules. ([\#18903](https://github.com/element-hq/synapse/issues/18903)) +- Fix the GitHub Actions workflow that moves issues labeled "X-Needs-Info" to the "Needs info" column on the team's internal triage board. ([\#18913](https://github.com/element-hq/synapse/issues/18913)) +- Disconnect background process work from request trace. ([\#18932](https://github.com/element-hq/synapse/issues/18932)) +- Reduce overall number of calls to `_get_e2e_cross_signing_signatures_for_devices` by increasing the batch size of devices the query is called with, reducing DB load. ([\#18939](https://github.com/element-hq/synapse/issues/18939)) +- Update error code used when an appservice tries to masquerade as an unknown device using [MSC4326](https://github.com/matrix-org/matrix-spec-proposals/pull/4326). Contributed by @tulir @ Beeper. ([\#18947](https://github.com/element-hq/synapse/issues/18947)) +- Fix `no active span when trying to log` tracing error on startup (when OpenTracing is enabled). ([\#18959](https://github.com/element-hq/synapse/issues/18959)) +- Fix `run_coroutine_in_background(...)` incorrectly handling logcontext. ([\#18964](https://github.com/element-hq/synapse/issues/18964)) +- Add debug logs wherever we change current logcontext. ([\#18966](https://github.com/element-hq/synapse/issues/18966)) +- Update dockerfile metadata to fix broken link; point to documentation website. ([\#18971](https://github.com/element-hq/synapse/issues/18971)) +- Note that the code is additionally licensed under the [Element Commercial license](https://github.com/element-hq/synapse/blob/develop/LICENSE-COMMERCIAL) in SPDX expression field configs. ([\#18973](https://github.com/element-hq/synapse/issues/18973)) +- Fix logcontext handling in `timeout_deferred` tests. ([\#18974](https://github.com/element-hq/synapse/issues/18974)) +- Remove internal `ReplicationUploadKeysForUserRestServlet` as a follow-up to the work in https://github.com/element-hq/synapse/pull/18581 that moved device changes off the main process. ([\#18988](https://github.com/element-hq/synapse/issues/18988)) +- Switch task scheduler from raw logcontext manipulation to using the dedicated logcontext utils. ([\#18990](https://github.com/element-hq/synapse/issues/18990)) +- Remove `MockClock()` in tests. ([\#18992](https://github.com/element-hq/synapse/issues/18992)) +- Switch back to our own custom `LogContextScopeManager` instead of OpenTracing's `ContextVarsScopeManager` which was causing problems when using the experimental `SYNAPSE_ASYNC_IO_REACTOR` option with tracing enabled. ([\#19007](https://github.com/element-hq/synapse/issues/19007)) +- Remove `version_string` argument from `HomeServer` since it's always the same. ([\#19012](https://github.com/element-hq/synapse/issues/19012)) +- Remove duplicate call to `hs.start_background_tasks()` introduced from a bad merge. ([\#19013](https://github.com/element-hq/synapse/issues/19013)) +- Split homeserver creation (`create_homeserver`) and setup (`setup`). ([\#19015](https://github.com/element-hq/synapse/issues/19015)) +- Swap near-end-of-life `macos-13` GitHub Actions runner for the `macos-15-intel` variant. ([\#19025](https://github.com/element-hq/synapse/issues/19025)) +- Introduce `RootConfig.validate_config()` which can be subclassed in `HomeServerConfig` to do cross-config class validation. ([\#19027](https://github.com/element-hq/synapse/issues/19027)) +- Allow any command of the `release.py` script to accept a `--gh-token` argument. ([\#19035](https://github.com/element-hq/synapse/issues/19035)) + + + +### Updates to locked dependencies + +* Bump Swatinem/rust-cache from 2.8.0 to 2.8.1. ([\#18949](https://github.com/element-hq/synapse/issues/18949)) +* Bump actions/cache from 4.2.4 to 4.3.0. ([\#18983](https://github.com/element-hq/synapse/issues/18983)) +* Bump anyhow from 1.0.99 to 1.0.100. ([\#18950](https://github.com/element-hq/synapse/issues/18950)) +* Bump authlib from 1.6.3 to 1.6.4. ([\#18957](https://github.com/element-hq/synapse/issues/18957)) +* Bump authlib from 1.6.4 to 1.6.5. ([\#19019](https://github.com/element-hq/synapse/issues/19019)) +* Bump bcrypt from 4.3.0 to 5.0.0. ([\#18984](https://github.com/element-hq/synapse/issues/18984)) +* Bump docker/login-action from 3.5.0 to 3.6.0. ([\#18978](https://github.com/element-hq/synapse/issues/18978)) +* Bump lxml from 6.0.0 to 6.0.2. ([\#18979](https://github.com/element-hq/synapse/issues/18979)) +* Bump phonenumbers from 9.0.13 to 9.0.14. ([\#18954](https://github.com/element-hq/synapse/issues/18954)) +* Bump phonenumbers from 9.0.14 to 9.0.15. ([\#18991](https://github.com/element-hq/synapse/issues/18991)) +* Bump prometheus-client from 0.22.1 to 0.23.1. ([\#19016](https://github.com/element-hq/synapse/issues/19016)) +* Bump pydantic from 2.11.9 to 2.11.10. ([\#19017](https://github.com/element-hq/synapse/issues/19017)) +* Bump pygithub from 2.7.0 to 2.8.1. ([\#18952](https://github.com/element-hq/synapse/issues/18952)) +* Bump regex from 1.11.2 to 1.11.3. ([\#18981](https://github.com/element-hq/synapse/issues/18981)) +* Bump serde from 1.0.224 to 1.0.226. ([\#18953](https://github.com/element-hq/synapse/issues/18953)) +* Bump serde from 1.0.226 to 1.0.228. ([\#18982](https://github.com/element-hq/synapse/issues/18982)) +* Bump setuptools-rust from 1.11.1 to 1.12.0. ([\#18980](https://github.com/element-hq/synapse/issues/18980)) +* Bump twine from 6.1.0 to 6.2.0. ([\#18985](https://github.com/element-hq/synapse/issues/18985)) +* Bump types-pyyaml from 6.0.12.20250809 to 6.0.12.20250915. ([\#19018](https://github.com/element-hq/synapse/issues/19018)) +* Bump types-requests from 2.32.4.20250809 to 2.32.4.20250913. ([\#18951](https://github.com/element-hq/synapse/issues/18951)) +* Bump typing-extensions from 4.14.1 to 4.15.0. ([\#18956](https://github.com/element-hq/synapse/issues/18956)) + +# Synapse 1.139.2 (2025-10-07) + +## Bugfixes + +- Fix a bug introduced in 1.139.1 where a client could receive an Internal Server Error if they set `device_keys: null` in the request to [`POST /_matrix/client/v3/keys/upload`](https://spec.matrix.org/v1.16/client-server-api/#post_matrixclientv3keysupload). ([\#19023](https://github.com/element-hq/synapse/issues/19023)) + + + + +# Synapse 1.139.1 (2025-10-07) + +## Security Fixes + +- Fix [CVE-2025-61672](https://www.cve.org/CVERecord?id=CVE-2025-61672) / [GHSA-fh66-fcv5-jjfr](https://github.com/element-hq/synapse/security/advisories/GHSA-fh66-fcv5-jjfr). Lack of validation for device keys in Synapse before 1.139.1 allows an attacker registered on the victim homeserver to degrade federation functionality, unpredictably breaking outbound federation to other homeservers. ([\#17097](https://github.com/element-hq/synapse/issues/17097)) + +## Deprecations and Removals + +- Drop support for unstable field names from the long-accepted [MSC2732](https://github.com/matrix-org/matrix-spec-proposals/pull/2732) (Olm fallback keys) proposal. This change allows unit tests to pass following the security patch above. ([\#18996](https://github.com/element-hq/synapse/issues/18996)) + + + +# Synapse 1.138.4 (2025-10-07) + +## Bugfixes + +- Fix a bug introduced in 1.138.3 where a client could receive an Internal Server Error if they set `device_keys: null` in the request to [`POST /_matrix/client/v3/keys/upload`](https://spec.matrix.org/v1.16/client-server-api/#post_matrixclientv3keysupload). ([\#19023](https://github.com/element-hq/synapse/issues/19023)) + + + + +# Synapse 1.138.3 (2025-10-07) + +## Security Fixes + +- Fix [CVE-2025-61672](https://www.cve.org/CVERecord?id=CVE-2025-61672) / [GHSA-fh66-fcv5-jjfr](https://github.com/element-hq/synapse/security/advisories/GHSA-fh66-fcv5-jjfr). Lack of validation for device keys in Synapse before 1.139.1 allows an attacker registered on the victim homeserver to degrade federation functionality, unpredictably breaking outbound federation to other homeservers. ([\#17097](https://github.com/element-hq/synapse/issues/17097)) + +## Deprecations and Removals + +- Drop support for unstable field names from the long-accepted [MSC2732](https://github.com/matrix-org/matrix-spec-proposals/pull/2732) (Olm fallback keys) proposal. This change allows unit tests to pass following the security patch above. ([\#18996](https://github.com/element-hq/synapse/issues/18996)) + +# Synapse 1.139.0 (2025-09-30) + +### `/register` requests from old application service implementations may break when using MAS + +If you are using Matrix Authentication Service (MAS), as of this release any +Application Services that do not set `inhibit_login=true` when calling `POST +/_matrix/client/v3/register` will receive the error +`IO.ELEMENT.MSC4190.M_APPSERVICE_LOGIN_UNSUPPORTED` in response. Please see [the +upgrade +notes](https://element-hq.github.io/synapse/develop/upgrade.html#register-requests-from-old-application-service-implementations-may-break-when-using-mas) +for more information. + +No significant changes since 1.139.0rc3. + + +# Synapse 1.139.0rc3 (2025-09-25) + +## Bugfixes + +- Fix a bug introduced in 1.139.0rc1 where `run_coroutine_in_background(...)` incorrectly handled logcontexts, resulting in partially broken logging. ([\#18964](https://github.com/element-hq/synapse/issues/18964)) + + + + +# Synapse 1.139.0rc2 (2025-09-23) + +## Internal Changes + +- Drop support for Ubuntu 24.10 Oracular Oriole, and add support for Ubuntu 25.04 Plucky Puffin. This change was applied on top of 1.139.0rc1. ([\#18962](https://github.com/element-hq/synapse/issues/18962)) + + + +# Synapse 1.139.0rc1 (2025-09-23) + +## Features + +- Add experimental support for [MSC4308: Thread Subscriptions extension to Sliding Sync](https://github.com/matrix-org/matrix-spec-proposals/pull/4308) when [MSC4306: Thread Subscriptions](https://github.com/matrix-org/matrix-spec-proposals/pull/4306) and [MSC4186: Simplified Sliding Sync](https://github.com/matrix-org/matrix-spec-proposals/pull/4186) are enabled. ([\#18695](https://github.com/element-hq/synapse/issues/18695)) +- Update push rules for experimental [MSC4306: Thread Subscriptions](https://github.com/matrix-org/matrix-doc/issues/4306) to follow a newer draft. ([\#18846](https://github.com/element-hq/synapse/issues/18846)) +- Add `get_media_upload_limits_for_user` and `on_media_upload_limit_exceeded` module API callbacks to the media repository. ([\#18848](https://github.com/element-hq/synapse/issues/18848)) +- Support [MSC4169](https://github.com/matrix-org/matrix-spec-proposals/pull/4169) for backwards-compatible redaction sending using the `/send` endpoint. Contributed by @SpiritCroc @ Beeper. ([\#18898](https://github.com/element-hq/synapse/issues/18898)) +- Add an in-memory cache to `_get_e2e_cross_signing_signatures_for_devices` to reduce DB load. ([\#18899](https://github.com/element-hq/synapse/issues/18899)) +- Update [MSC4190](https://github.com/matrix-org/matrix-spec-proposals/pull/4190) support to return correct errors and allow appservices to reset cross-signing keys without user-interactive authentication. Contributed by @tulir @ Beeper. ([\#18946](https://github.com/element-hq/synapse/issues/18946)) + +## Bugfixes + +- Ensure all PDUs sent via `/send` pass canonical JSON checks. ([\#18641](https://github.com/element-hq/synapse/issues/18641)) +- Fix bug where we did not send invite revocations over federation. ([\#18823](https://github.com/element-hq/synapse/issues/18823)) +- Fix prefixed support for [MSC4133](https://github.com/matrix-org/matrix-spec-proposals/pull/4133). ([\#18875](https://github.com/element-hq/synapse/issues/18875)) +- Fix open redirect in legacy SSO flow with the `idp` query parameter. ([\#18909](https://github.com/element-hq/synapse/issues/18909)) +- Fix a performance regression related to the experimental Delayed Events ([MSC4140](https://github.com/matrix-org/matrix-spec-proposals/pull/4140)) feature. ([\#18926](https://github.com/element-hq/synapse/issues/18926)) + +## Updates to the Docker image + +- Suppress "Applying schema" log noise bulk when `SYNAPSE_LOG_TESTING` is set. ([\#18878](https://github.com/element-hq/synapse/issues/18878)) + +## Improved Documentation + +- Clarify Python dependency constraints in our deprecation policy. ([\#18856](https://github.com/element-hq/synapse/issues/18856)) +- Clarify necessary `jwt_config` parameter in OIDC documentation for authentik. Contributed by @maxkratz. ([\#18931](https://github.com/element-hq/synapse/issues/18931)) + +## Deprecations and Removals + +- Remove obsolete and experimental `/sync/e2ee` endpoint. ([\#18583](https://github.com/element-hq/synapse/issues/18583)) + +## Internal Changes + +- Fix `LaterGauge` metrics to collect from all servers. ([\#18791](https://github.com/element-hq/synapse/issues/18791)) +- Configure Synapse to run [MSC4306: Thread Subscriptions](https://github.com/matrix-org/matrix-spec-proposals/pull/4306) Complement tests. ([\#18819](https://github.com/element-hq/synapse/issues/18819)) +- Remove `sentinel` logcontext usage where we log in `setup`, `start` and `exit`. ([\#18870](https://github.com/element-hq/synapse/issues/18870)) +- Use the `Enum`'s value for the dictionary key when responding to an admin request for experimental features. ([\#18874](https://github.com/element-hq/synapse/issues/18874)) +- Start background tasks after we fork the process (daemonize). ([\#18886](https://github.com/element-hq/synapse/issues/18886)) +- Better explain how we manage the logcontext in `run_in_background(...)` and `run_as_background_process(...)`. ([\#18900](https://github.com/element-hq/synapse/issues/18900), [\#18906](https://github.com/element-hq/synapse/issues/18906)) +- Remove `sentinel` logcontext usage in `Clock` utilities like `looping_call` and `call_later`. ([\#18907](https://github.com/element-hq/synapse/issues/18907)) +- Replace usages of the deprecated `pkg_resources` interface in preparation of setuptools dropping it soon. ([\#18910](https://github.com/element-hq/synapse/issues/18910)) +- Split loading config from homeserver `setup`. ([\#18933](https://github.com/element-hq/synapse/issues/18933)) +- Fix `run_in_background` not being awaited properly in some tests causing `LoggingContext` problems. ([\#18937](https://github.com/element-hq/synapse/issues/18937)) +- Fix `run_as_background_process` not being awaited properly causing `LoggingContext` problems in experimental [MSC4140](https://github.com/matrix-org/matrix-spec-proposals/pull/4140): Delayed events implementation. ([\#18938](https://github.com/element-hq/synapse/issues/18938)) +- Introduce `Clock.call_when_running(...)` to wrap startup code in a logcontext, ensuring we can identify which server generated the logs. ([\#18944](https://github.com/element-hq/synapse/issues/18944)) +- Introduce `Clock.add_system_event_trigger(...)` to wrap system event callback code in a logcontext, ensuring we can identify which server generated the logs. ([\#18945](https://github.com/element-hq/synapse/issues/18945)) + + + +### Updates to locked dependencies + +* Bump actions/setup-go from 5.5.0 to 6.0.0. ([\#18891](https://github.com/element-hq/synapse/issues/18891)) +* Bump actions/setup-python from 5.6.0 to 6.0.0. ([\#18890](https://github.com/element-hq/synapse/issues/18890)) +* Bump authlib from 1.6.1 to 1.6.3. ([\#18921](https://github.com/element-hq/synapse/issues/18921)) +* Bump jsonschema from 4.25.0 to 4.25.1. ([\#18897](https://github.com/element-hq/synapse/issues/18897)) +* Bump log from 0.4.27 to 0.4.28. ([\#18892](https://github.com/element-hq/synapse/issues/18892)) +* Bump phonenumbers from 9.0.12 to 9.0.13. ([\#18893](https://github.com/element-hq/synapse/issues/18893)) +* Bump pydantic from 2.11.7 to 2.11.9. ([\#18922](https://github.com/element-hq/synapse/issues/18922)) +* Bump serde from 1.0.219 to 1.0.223. ([\#18920](https://github.com/element-hq/synapse/issues/18920)) +* Bump serde_json from 1.0.143 to 1.0.145. ([\#18919](https://github.com/element-hq/synapse/issues/18919)) +* Bump sigstore/cosign-installer from 3.9.2 to 3.10.0. ([\#18917](https://github.com/element-hq/synapse/issues/18917)) +* Bump towncrier from 24.8.0 to 25.8.0. ([\#18894](https://github.com/element-hq/synapse/issues/18894)) +* Bump types-psycopg2 from 2.9.21.20250809 to 2.9.21.20250915. ([\#18918](https://github.com/element-hq/synapse/issues/18918)) +* Bump types-requests from 2.32.4.20250611 to 2.32.4.20250809. ([\#18895](https://github.com/element-hq/synapse/issues/18895)) +* Bump types-setuptools from 80.9.0.20250809 to 80.9.0.20250822. ([\#18924](https://github.com/element-hq/synapse/issues/18924)) + +# Synapse 1.138.2 (2025-09-24) + +## Internal Changes + +- Drop support for Ubuntu 24.10 Oracular Oriole, and add support for Ubuntu 25.04 Plucky Puffin. This change was applied on top of 1.138.1. ([\#18962](https://github.com/element-hq/synapse/issues/18962)) + + + +# Synapse 1.138.1 (2025-09-24) + +## Bugfixes + +- Fix a performance regression related to the experimental Delayed Events ([MSC4140](https://github.com/matrix-org/matrix-spec-proposals/pull/4140)) feature. ([\#18926](https://github.com/element-hq/synapse/issues/18926)) + + + + +# Synapse 1.138.0 (2025-09-09) + +No significant changes since 1.138.0rc1. + + + + # Synapse 1.138.0rc1 (2025-09-02) ### Features diff --git a/Cargo.lock b/Cargo.lock index 095fb38ce1..e1747182e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,21 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" - [[package]] name = "aho-corasick" version = "1.1.3" @@ -28,9 +13,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.99" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "arc-swap" @@ -50,21 +35,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" -[[package]] -name = "backtrace" -version = "0.3.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets", -] - [[package]] name = "base64" version = "0.22.1" @@ -103,9 +73,9 @@ checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "bytes" -version = "1.10.1" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "cc" @@ -217,9 +187,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" dependencies = [ "futures-channel", "futures-core", @@ -232,9 +202,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" dependencies = [ "futures-core", "futures-sink", @@ -242,15 +212,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" [[package]] name = "futures-executor" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" dependencies = [ "futures-core", "futures-task", @@ -259,15 +229,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" [[package]] name = "futures-macro" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", @@ -276,21 +246,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" [[package]] name = "futures-task" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-util" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ "futures-channel", "futures-core", @@ -300,7 +270,6 @@ dependencies = [ "futures-task", "memchr", "pin-project-lite", - "pin-utils", "slab", ] @@ -341,12 +310,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - [[package]] name = "h2" version = "0.4.11" @@ -410,12 +373,11 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "http" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" dependencies = [ "bytes", - "fnv", "itoa", ] @@ -625,9 +587,9 @@ dependencies = [ [[package]] name = "icu_segmenter" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e185fc13b6401c138cf40db12b863b35f5edf31b88192a545857b41aeaf7d3d3" +checksum = "38e30e593cf9c3ca2f51aa312eb347cd1ba95715e91a842ec3fc9058eab2af4b" dependencies = [ "core_maths", "displaydoc", @@ -684,17 +646,6 @@ version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" -[[package]] -name = "io-uring" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4" -dependencies = [ - "bitflags", - "cfg-if", - "libc", -] - [[package]] name = "ipnet" version = "2.11.0" @@ -753,9 +704,9 @@ checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" [[package]] name = "log" -version = "0.4.27" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "lru-slab" @@ -784,15 +735,6 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" -[[package]] -name = "miniz_oxide" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" -dependencies = [ - "adler2", -] - [[package]] name = "mio" version = "1.0.4" @@ -804,20 +746,11 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "object" -version = "0.36.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" -version = "1.21.3" +version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "openssl-probe" @@ -837,12 +770,6 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - [[package]] name = "portable-atomic" version = "1.11.1" @@ -879,11 +806,12 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.25.1" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8970a78afe0628a3e3430376fc5fd76b6b45c4d43360ffd6cdd40bdde72b682a" +checksum = "ab53c047fcd1a1d2a8820fe84f05d6be69e9526be40cb03b73f86b6b03e6d87d" dependencies = [ "anyhow", + "bytes", "indoc", "libc", "memoffset", @@ -897,19 +825,18 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.25.1" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "458eb0c55e7ece017adeba38f2248ff3ac615e53660d7c71a238d7d2a01c7598" +checksum = "b455933107de8642b4487ed26d912c2d899dec6114884214a0b3bb3be9261ea6" dependencies = [ - "once_cell", "target-lexicon", ] [[package]] name = "pyo3-ffi" -version = "0.25.1" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7114fe5457c61b276ab77c5055f206295b812608083644a5c5b2640c3102565c" +checksum = "1c85c9cbfaddf651b1221594209aed57e9e5cff63c4d11d1feead529b872a089" dependencies = [ "libc", "pyo3-build-config", @@ -917,9 +844,9 @@ dependencies = [ [[package]] name = "pyo3-log" -version = "0.12.4" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45192e5e4a4d2505587e27806c7b710c231c40c56f3bfc19535d0bb25df52264" +checksum = "26c2ec80932c5c3b2d4fbc578c9b56b2d4502098587edb8bef5b6bfcad43682e" dependencies = [ "arc-swap", "log", @@ -928,9 +855,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.25.1" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8725c0a622b374d6cb051d11a0983786448f7785336139c3c94f5aa6bef7e50" +checksum = "0a5b10c9bf9888125d917fb4d2ca2d25c8df94c7ab5a52e13313a07e050a3b02" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -940,9 +867,9 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.25.1" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4109984c22491085343c05b0dbc54ddc405c3cf7b4374fc533f5c3313a572ccc" +checksum = "03b51720d314836e53327f5871d4c0cfb4fb37cc2c4a11cc71907a86342c40f9" dependencies = [ "heck", "proc-macro2", @@ -953,9 +880,9 @@ dependencies = [ [[package]] name = "pythonize" -version = "0.25.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597907139a488b22573158793aa7539df36ae863eba300c75f3a0d65fc475e27" +checksum = "a3a8f29db331e28c332c63496cfcbb822aca3d7320bc08b655d7fd0c29c50ede" dependencies = [ "pyo3", "serde", @@ -983,9 +910,9 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.12" +version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49df843a9161c85bb8aae55f101bc0bac8bcafd637a620d9122fd7e0b2f7422e" +checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" dependencies = [ "bytes", "getrandom 0.3.3", @@ -1062,9 +989,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.2" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" dependencies = [ "aho-corasick", "memchr", @@ -1074,9 +1001,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.9" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", @@ -1091,9 +1018,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" -version = "0.12.23" +version = "0.12.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ "base64", "bytes", @@ -1145,18 +1072,21 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rustc-demangle" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" - [[package]] name = "rustc-hash" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + [[package]] name = "rustls" version = "0.23.31" @@ -1195,9 +1125,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.4" +version = "0.103.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" +checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef" dependencies = [ "ring", "rustls-pki-types", @@ -1249,19 +1179,35 @@ dependencies = [ ] [[package]] -name = "serde" -version = "1.0.219" +name = "semver" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -1270,14 +1216,15 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.143" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ "itoa", "memchr", - "ryu", "serde", + "serde_core", + "zmij", ] [[package]] @@ -1398,6 +1345,7 @@ dependencies = [ "pythonize", "regex", "reqwest", + "rustc_version", "serde", "serde_json", "sha2", @@ -1478,19 +1426,16 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.47.1" +version = "1.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" +checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d" dependencies = [ - "backtrace", "bytes", - "io-uring", "libc", "mio", "pin-project-lite", - "slab", "socket2 0.6.0", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -1533,9 +1478,9 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ "bitflags", "bytes", @@ -1771,6 +1716,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + [[package]] name = "windows-sys" version = "0.52.0" @@ -1789,6 +1740,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-targets" version = "0.52.6" @@ -1971,3 +1931,9 @@ dependencies = [ "quote", "syn", ] + +[[package]] +name = "zmij" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff05f8caa9038894637571ae6b9e29466c1f4f829d26c9b28f869a29cbe3445" diff --git a/README.rst b/README.rst index 92854f631c..4db5d461a8 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -.. image:: ./docs/element_logo_white_bg.svg +.. image:: https://github.com/element-hq/synapse/raw/develop/docs/element_logo_white_bg.svg :height: 60px **Element Synapse - Matrix homeserver implementation** @@ -7,170 +7,48 @@ Synapse is an open source `Matrix `__ homeserver implementation, written and maintained by `Element `_. -`Matrix `__ is the open standard for -secure and interoperable real-time communications. You can directly run -and manage the source code in this repository, available under an AGPL -license (or alternatively under a commercial license from Element). -There is no support provided by Element unless you have a -subscription from Element. +`Matrix `__ is the open standard for secure and +interoperable real-time communications. You can directly run and manage the +source code in this repository, available under an AGPL license (or +alternatively under a commercial license from Element). -Subscription -============ +There is no support provided by Element unless you have a subscription from +Element. -For those that need an enterprise-ready solution, Element -Server Suite (ESS) is `available via subscription `_. -ESS builds on Synapse to offer a complete Matrix-based backend including the full -`Admin Console product `_, -giving admins the power to easily manage an organization-wide -deployment. It includes advanced identity management, auditing, -moderation and data retention options as well as Long-Term Support and -SLAs. ESS supports any Matrix-compatible client. +🚀 Getting started +================== -.. contents:: +This component is developed and maintained by `Element `_. +It gets shipped as part of the **Element Server Suite (ESS)** which provides the +official means of deployment. -🛠️ Installation and configuration -================================== +ESS is a Matrix distribution from Element with focus on quality and ease of use. +It ships a full Matrix stack tailored to the respective use case. -The Synapse documentation describes `how to install Synapse `_. We recommend using -`Docker images `_ or `Debian packages from Matrix.org -`_. +There are three editions of ESS: -.. _federation: - -Synapse has a variety of `config options -`_ -which can be used to customise its behaviour after installation. -There are additional details on how to `configure Synapse for federation here -`_. - -.. _reverse-proxy: - -Using a reverse proxy with Synapse ----------------------------------- - -It is recommended to put a reverse proxy such as -`nginx `_, -`Apache `_, -`Caddy `_, -`HAProxy `_ or -`relayd `_ in front of Synapse. One advantage of -doing so is that it means that you can expose the default https port (443) to -Matrix clients without needing to run Synapse with root privileges. -For information on configuring one, see `the reverse proxy docs -`_. - -Upgrading an existing Synapse ------------------------------ - -The instructions for upgrading Synapse are in `the upgrade notes`_. -Please check these instructions as upgrading may require extra steps for some -versions of Synapse. - -.. _the upgrade notes: https://element-hq.github.io/synapse/develop/upgrade.html +- `ESS Community `_ - the free Matrix + distribution from Element tailored to small-/mid-scale, non-commercial + community use cases +- `ESS Pro `_ - the commercial Matrix + distribution from Element for professional use +- `ESS TI-M `_ - a special version + of ESS Pro focused on the requirements of TI-Messenger Pro and ePA as + specified by the German National Digital Health Agency Gematik -Platform dependencies ---------------------- +🛠️ Standalone installation and configuration +============================================ -Synapse uses a number of platform dependencies such as Python and PostgreSQL, -and aims to follow supported upstream versions. See the -`deprecation policy `_ -for more details. +The Synapse documentation describes `options for installing Synapse standalone +`_. See +below for more useful documentation links. +- `Synapse configuration options `_ +- `Synapse configuration for federation `_ +- `Using a reverse proxy with Synapse `_ +- `Upgrading Synapse `_ -Security note -------------- - -Matrix serves raw, user-supplied data in some APIs -- specifically the `content -repository endpoints`_. - -.. _content repository endpoints: https://matrix.org/docs/spec/client_server/latest.html#get-matrix-media-r0-download-servername-mediaid - -Whilst we make a reasonable effort to mitigate against XSS attacks (for -instance, by using `CSP`_), a Matrix homeserver should not be hosted on a -domain hosting other web applications. This especially applies to sharing -the domain with Matrix web clients and other sensitive applications like -webmail. See -https://developer.github.com/changes/2014-04-25-user-content-security for more -information. - -.. _CSP: https://github.com/matrix-org/synapse/pull/1021 - -Ideally, the homeserver should not simply be on a different subdomain, but on -a completely different `registered domain`_ (also known as top-level site or -eTLD+1). This is because `some attacks`_ are still possible as long as the two -applications share the same registered domain. - -.. _registered domain: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-2.3 - -.. _some attacks: https://en.wikipedia.org/wiki/Session_fixation#Attacks_using_cross-subdomain_cookie - -To illustrate this with an example, if your Element Web or other sensitive web -application is hosted on ``A.example1.com``, you should ideally host Synapse on -``example2.com``. Some amount of protection is offered by hosting on -``B.example1.com`` instead, so this is also acceptable in some scenarios. -However, you should *not* host your Synapse on ``A.example1.com``. - -Note that all of the above refers exclusively to the domain used in Synapse's -``public_baseurl`` setting. In particular, it has no bearing on the domain -mentioned in MXIDs hosted on that server. - -Following this advice ensures that even if an XSS is found in Synapse, the -impact to other applications will be minimal. - - -🧪 Testing a new installation -============================= - -The easiest way to try out your new Synapse installation is by connecting to it -from a web client. - -Unless you are running a test instance of Synapse on your local machine, in -general, you will need to enable TLS support before you can successfully -connect from a client: see -`TLS certificates `_. - -An easy way to get started is to login or register via Element at -https://app.element.io/#/login or https://app.element.io/#/register respectively. -You will need to change the server you are logging into from ``matrix.org`` -and instead specify a homeserver URL of ``https://:8448`` -(or just ``https://`` if you are using a reverse proxy). -If you prefer to use another client, refer to our -`client breakdown `_. - -If all goes well you should at least be able to log in, create a room, and -start sending messages. - -.. _`client-user-reg`: - -Registering a new user from a client ------------------------------------- - -By default, registration of new users via Matrix clients is disabled. To enable -it: - -1. In the - `registration config section `_ - set ``enable_registration: true`` in ``homeserver.yaml``. -2. Then **either**: - - a. set up a `CAPTCHA `_, or - b. set ``enable_registration_without_verification: true`` in ``homeserver.yaml``. - -We **strongly** recommend using a CAPTCHA, particularly if your homeserver is exposed to -the public internet. Without it, anyone can freely register accounts on your homeserver. -This can be exploited by attackers to create spambots targeting the rest of the Matrix -federation. - -Your new Matrix ID will be formed partly from the ``server_name``, and partly -from a localpart you specify when you create the account in the form of:: - - @localpart:my.domain.name - -(pronounced "at localpart on my dot domain dot name"). - -As when logging in, you will need to specify a "Custom server". Specify your -desired ``localpart`` in the 'Username' box. 🎯 Troubleshooting and support ============================== @@ -182,7 +60,7 @@ Enterprise quality support for Synapse including SLAs is available as part of an `Element Server Suite (ESS) `_ subscription. If you are an existing ESS subscriber then you can raise a `support request `_ -and access the `knowledge base `_. +and access the `Element product documentation `_. 🤝 Community support -------------------- @@ -201,35 +79,6 @@ issues for support requests, only for bug reports and feature requests. .. |docs| replace:: ``docs`` .. _docs: docs -🪪 Identity Servers -=================== - -Identity servers have the job of mapping email addresses and other 3rd Party -IDs (3PIDs) to Matrix user IDs, as well as verifying the ownership of 3PIDs -before creating that mapping. - -**Identity servers do not store accounts or credentials - these are stored and managed on homeservers. -Identity Servers are just for mapping 3rd Party IDs to Matrix IDs.** - -This process is highly security-sensitive, as there is an obvious risk of spam if it -is too easy to sign up for Matrix accounts or harvest 3PID data. In the longer -term, we hope to create a decentralised system to manage it (`matrix-doc #712 -`_), but in the meantime, -the role of managing trusted identity in the Matrix ecosystem is farmed out to -a cluster of known trusted ecosystem partners, who run 'Matrix Identity -Servers' such as `Sydent `_, whose role -is purely to authenticate and track 3PID logins and publish end-user public -keys. - -You can host your own copy of Sydent, but this will prevent you reaching other -users in the Matrix ecosystem via their email address, and prevent them finding -you. We therefore recommend that you use one of the centralised identity servers -at ``https://matrix.org`` or ``https://vector.im`` for now. - -To reiterate: the Identity server will only be used if you choose to associate -an email address with your account, or send an invite to another user via their -email address. - 🛠️ Development ============== @@ -252,18 +101,29 @@ Alongside all that, join our developer community on Matrix: Copyright and Licensing ======================= -| Copyright 2014-2017 OpenMarket Ltd -| Copyright 2017 Vector Creations Ltd -| Copyright 2017-2025 New Vector Ltd -| + | Copyright 2014–2017 OpenMarket Ltd + | Copyright 2017 Vector Creations Ltd + | Copyright 2017–2025 New Vector Ltd + | Copyright 2025 Element Creations Ltd -This software is dual-licensed by New Vector Ltd (Element). It can be used either: +This software is dual-licensed by Element Creations Ltd (Element). It can be +used either: -(1) for free under the terms of the GNU Affero General Public License (as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version); OR +(1) for free under the terms of the GNU Affero General Public License (as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version); OR -(2) under the terms of a paid-for Element Commercial License agreement between you and Element (the terms of which may vary depending on what you and Element have agreed to). +(2) under the terms of a paid-for Element Commercial License agreement between + you and Element (the terms of which may vary depending on what you and + Element have agreed to). -Unless required by applicable law or agreed to in writing, software distributed under the Licenses is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the Licenses for the specific language governing permissions and limitations under the Licenses. +Unless required by applicable law or agreed to in writing, software distributed +under the Licenses is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the Licenses for the +specific language governing permissions and limitations under the Licenses. + +Please contact `licensing@element.io `_ to purchase +an Element commercial license for this software. .. |support| image:: https://img.shields.io/badge/matrix-community%20support-success diff --git a/book.toml b/book.toml index 98d749ed39..99e4d03bf4 100644 --- a/book.toml +++ b/book.toml @@ -4,7 +4,6 @@ title = "Synapse" authors = ["The Matrix.org Foundation C.I.C."] language = "en" -multilingual = false # The directory that documentation files are stored in src = "docs" @@ -31,13 +30,10 @@ site-url = "/synapse/" # Additional HTML, JS, CSS that's injected into each page of the book. # More information available in docs/website_files/README.md additional-css = [ - "docs/website_files/table-of-contents.css", - "docs/website_files/remove-nav-buttons.css", "docs/website_files/indent-section-headers.css", "docs/website_files/version-picker.css", ] additional-js = [ - "docs/website_files/table-of-contents.js", "docs/website_files/version-picker.js", "docs/website_files/version.js", ] diff --git a/build_rust.py b/build_rust.py index 5c796af461..a9e9265daf 100644 --- a/build_rust.py +++ b/build_rust.py @@ -2,13 +2,13 @@ import itertools import os -from typing import Any, Dict +from typing import Any from packaging.specifiers import SpecifierSet from setuptools_rust import Binding, RustExtension -def build(setup_kwargs: Dict[str, Any]) -> None: +def build(setup_kwargs: dict[str, Any]) -> None: original_project_dir = os.path.dirname(os.path.realpath(__file__)) cargo_toml_path = os.path.join(original_project_dir, "rust", "Cargo.toml") @@ -27,12 +27,12 @@ def build(setup_kwargs: Dict[str, Any]) -> None: setup_kwargs["zip_safe"] = False # We look up the minimum supported Python version with - # `python_requires` (e.g. ">=3.9.0,<4.0.0") and finding the first Python + # `python_requires` (e.g. ">=3.10.0,<4.0.0") and finding the first Python # version that matches. We then convert that into the `py_limited_api` form, - # e.g. cp39 for Python 3.9. + # e.g. cp310 for Python 3.10. py_limited_api: str python_bounds = SpecifierSet(setup_kwargs["python_requires"]) - for minor_version in itertools.count(start=8): + for minor_version in itertools.count(start=10): if f"3.{minor_version}.0" in python_bounds: py_limited_api = f"cp3{minor_version}" break diff --git a/changelog.d/19615.doc b/changelog.d/19615.doc new file mode 100644 index 0000000000..9e28ac8312 --- /dev/null +++ b/changelog.d/19615.doc @@ -0,0 +1 @@ +Include a workaround for running the unit tests with SQLite under recent versions of MacOS. diff --git a/changelog.d/19633.misc b/changelog.d/19633.misc new file mode 100644 index 0000000000..37efd5309f --- /dev/null +++ b/changelog.d/19633.misc @@ -0,0 +1 @@ +Document context for why increase timeout for policy server requests. diff --git a/changelog.d/19636.misc b/changelog.d/19636.misc new file mode 100644 index 0000000000..9ea0f04603 --- /dev/null +++ b/changelog.d/19636.misc @@ -0,0 +1 @@ +Run lint script to format Complement tests introduced in [#19509](https://github.com/element-hq/synapse/pull/19509). diff --git a/changelog.d/19643.feature b/changelog.d/19643.feature new file mode 100644 index 0000000000..0851623fbf --- /dev/null +++ b/changelog.d/19643.feature @@ -0,0 +1 @@ +Report the Rust compiler version used in the Prometheus metrics. Contributed by Noah Markert. \ No newline at end of file diff --git a/complement/.golangci.yml b/complement/.golangci.yml new file mode 100644 index 0000000000..6ef564d4c4 --- /dev/null +++ b/complement/.golangci.yml @@ -0,0 +1,38 @@ +# Docs: https://golangci-lint.run/docs/configuration/file/ +# +# Go formatting/linting rules +# +# This is run as part of the normal linting utility script, +# `poetry run ./scripts-dev/lint.sh` + +version: "2" + +linters: + # Default set of linters. + # The value can be: + # - `standard`: https://golangci-lint.run/docs/linters/#enabled-by-default + # - `all`: enables all linters by default. + # - `none`: disables all linters by default. + # - `fast`: enables only linters considered as "fast" (`golangci-lint help linters --json | jq '[ .[] | select(.fast==true) ] | map(.name)'`). + # Default: standard + default: standard + + # Enable specific linter. + # enable: + # - example + + # Disable specific linters. + disable: + # FIXME: Ideally, we'd enable the `bodyclose` lint but there are many + # false-positives (like https://github.com/timakin/bodyclose/issues/39) and just is + # not well-suited for our use case (https://github.com/timakin/bodyclose/issues/11 and + # https://github.com/timakin/bodyclose/issues/76). + - bodyclose + +formatters: + # Enable specific formatter. + # Default: [] (uses standard Go formatting) + enable: + - gofmt + - goimports + - golines diff --git a/complement/README.md b/complement/README.md new file mode 100644 index 0000000000..77f7ee182d --- /dev/null +++ b/complement/README.md @@ -0,0 +1,95 @@ +# Complement testing + +Complement is a black box integration testing framework for Matrix homeservers. It +allows us to write end-to-end tests that interact with real Synapse homeservers to +ensure everything works at a holistic level. + + +## Setup + +Nothing beyond a [normal Complement +setup](https://github.com/matrix-org/complement#running) (just Go and Docker). + + +## Running tests + +Run tests from the [Complement](https://github.com/matrix-org/complement) repo: + +```shell +# Run the tests +./scripts-dev/complement.sh + +# To run a whole group of tests, you can specify part of the test path: +scripts-dev/complement.sh ./tests/csapi/... -run TestRoomCreate +# To run a specific test, you can specify the whole name structure: +scripts-dev/complement.sh ./tests/csapi/... -run TestRoomCreate/Parallel/POST_/createRoom_makes_a_public_room +# Generally though, the `-run` parameter accepts regex patterns, so you can match however you like: +scripts-dev/complement.sh ./tests/... -run 'TestRoomCreate/Parallel/POST_/createRoom_makes_a_(.*)' +``` + +It's often nice to develop on Synapse and write Complement tests at the same time. +Here is how to run your local Synapse checkout against your local Complement checkout. + +```shell +# To run a specific test +COMPLEMENT_DIR=../complement ./scripts-dev/complement.sh ./tests/csapi/... -run TestRoomCreate +``` + +The above will run a monolithic (single-process) Synapse with SQLite as the database. +For other configurations, try: + +- Passing `POSTGRES=1` as an environment variable to use the Postgres database instead. +- Passing `WORKERS=1` as an environment variable to use a workerised setup instead. This + option implies the use of Postgres. + - If setting `WORKERS=1`, optionally set `WORKER_TYPES=` to declare which worker types + you wish to test. A simple comma-delimited string containing the worker types + defined from the `WORKERS_CONFIG` template in + [here](https://github.com/element-hq/synapse/blob/develop/docker/configure_workers_and_start.py#L54). + A safe example would be `WORKER_TYPES="federation_inbound, federation_sender, + synchrotron"`. See the [worker documentation](../workers.md) for additional + information on workers. +- Passing `ASYNCIO_REACTOR=1` as an environment variable to use the asyncio-backed + reactor with Twisted instead of the default one. +- Passing `PODMAN=1` will use the [podman](https://podman.io/) container runtime, + instead of docker. +- Passing `UNIX_SOCKETS=1` will utilise Unix socket functionality for Synapse, Redis, + and Postgres(when applicable). + +To increase the log level for the tests, set `SYNAPSE_TEST_LOG_LEVEL`, e.g: +```sh +SYNAPSE_TEST_LOG_LEVEL=DEBUG COMPLEMENT_DIR=../complement ./scripts-dev/complement.sh -run TestRoomCreate +``` + + +### Running in-repo tests + +In-repo Complement tests are tests that are vendored into this project. We use the +in-repo test suite to test Synapse specific behaviors like the admin API. + +To run the in-repo Complement tests, use the `--in-repo` command line argument. + +```shell +# Run only a specific test package. +# Note: test packages are relative to the `./complement` directory in this project +./scripts-dev/complement.sh --in-repo ./tests/... + +# Similarly, you can also use `-run` to specify all or part of a specific test path to run +scripts-dev/complement.sh --in-repo ./tests/... -run TestIntraShardFederation +``` + +### Access database for homeserver after Complement test runs. + +If you're curious what the database looks like after you run some tests, here are some +steps to get you going in Synapse: + +1. In your Complement test comment out `defer deployment.Destroy(t)` and replace with + `defer time.Sleep(2 * time.Hour)` to keep the homeserver running after the tests + complete +1. Start the Complement tests +1. Find the name of the container, `docker ps -f name=complement_` (this will filter for + just the Complement related Docker containers) +1. Access the container replacing the name with what you found in the previous step: + `docker exec -it complement_1_hs_with_application_service.hs1_2 /bin/bash` +1. Install sqlite (database driver), `apt-get update && apt-get install -y sqlite3` +1. Then run `sqlite3` and open the database `.open /conf/homeserver.db` (this db path + comes from the Synapse homeserver.yaml) diff --git a/complement/go.mod b/complement/go.mod new file mode 100644 index 0000000000..716aabdf32 --- /dev/null +++ b/complement/go.mod @@ -0,0 +1,58 @@ +module github.com/element-hq/synapse + +go 1.24.1 + +toolchain go1.24.4 + +require ( + github.com/matrix-org/complement v0.0.0-20251120181401-44111a2a8a9d + github.com/matrix-org/gomatrixserverlib v0.0.0-20250813150445-9f5070a65744 +) + +require ( + github.com/docker/docker v28.3.3+incompatible + github.com/docker/go-connections v0.5.0 // indirect + github.com/hashicorp/go-set/v3 v3.0.0 // indirect + github.com/moby/sys/atomicwriter v0.1.0 // indirect + github.com/oleiade/lane/v2 v2.0.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 // indirect + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + gotest.tools/v3 v3.4.0 // indirect +) + +require ( + github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/containerd/errdefs v1.0.0 // indirect + github.com/containerd/errdefs/pkg v0.3.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/distribution/reference v0.6.0 // indirect + github.com/docker/go-units v0.5.0 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530 // indirect + github.com/matrix-org/util v0.0.0-20221111132719-399730281e66 // indirect + github.com/moby/docker-image-spec v1.3.1 // indirect + github.com/moby/term v0.5.2 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.1 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + github.com/tidwall/gjson v1.18.0 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.1 // indirect + github.com/tidwall/sjson v1.2.5 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect + go.opentelemetry.io/otel v1.36.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 // indirect + go.opentelemetry.io/otel/metric v1.36.0 // indirect + go.opentelemetry.io/otel/trace v1.36.0 // indirect + go.opentelemetry.io/proto/otlp v1.7.0 // indirect + golang.org/x/crypto v0.45.0 // indirect + golang.org/x/sys v0.38.0 // indirect + golang.org/x/time v0.11.0 // indirect + google.golang.org/protobuf v1.36.6 // indirect +) diff --git a/complement/go.sum b/complement/go.sum new file mode 100644 index 0000000000..79a35aa14c --- /dev/null +++ b/complement/go.sum @@ -0,0 +1,181 @@ +github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg= +github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= +github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= +github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE= +github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk= +github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= +github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= +github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/docker/docker v28.3.3+incompatible h1:Dypm25kh4rmk49v1eiVbsAtpAsYURjYkaKubwuBdxEI= +github.com/docker/docker v28.3.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= +github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= +github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= +github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= +github.com/hashicorp/go-set/v3 v3.0.0 h1:CaJBQvQCOWoftrBcDt7Nwgo0kdpmrKxar/x2o6pV9JA= +github.com/hashicorp/go-set/v3 v3.0.0/go.mod h1:IEghM2MpE5IaNvL+D7X480dfNtxjRXZ6VMpK3C8s2ok= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/matrix-org/complement v0.0.0-20251120181401-44111a2a8a9d h1:s2Xc9GB2E/pXdElP18h8+04Y3SmhaII7xh2YmCM7oZc= +github.com/matrix-org/complement v0.0.0-20251120181401-44111a2a8a9d/go.mod h1:HioTV089DHLBfljH9QLGifJRE4Avnyk08BXXhCwd4gs= +github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530 h1:kHKxCOLcHH8r4Fzarl4+Y3K5hjothkVW5z7T1dUM11U= +github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s= +github.com/matrix-org/gomatrixserverlib v0.0.0-20250813150445-9f5070a65744 h1:5GvC2FD9O/PhuyY95iJQdNYHbDioEhMWdeMP9maDUL8= +github.com/matrix-org/gomatrixserverlib v0.0.0-20250813150445-9f5070a65744/go.mod h1:b6KVfDjXjA5Q7vhpOaMqIhFYvu5BuFVZixlNeTV/CLc= +github.com/matrix-org/util v0.0.0-20221111132719-399730281e66 h1:6z4KxomXSIGWqhHcfzExgkH3Z3UkIXry4ibJS4Aqz2Y= +github.com/matrix-org/util v0.0.0-20221111132719-399730281e66/go.mod h1:iBI1foelCqA09JJgPV0FYz4qA5dUXYOxMi57FxKBdd4= +github.com/miekg/dns v1.1.66 h1:FeZXOS3VCVsKnEAd+wBkjMC3D2K+ww66Cq3VnCINuJE= +github.com/miekg/dns v1.1.66/go.mod h1:jGFzBsSNbJw6z1HYut1RKBKHA9PBdxeHrZG8J+gC2WE= +github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= +github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= +github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw= +github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs= +github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU= +github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko= +github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ= +github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/oleiade/lane/v2 v2.0.0 h1:XW/ex/Inr+bPkLd3O240xrFOhUkTd4Wy176+Gv0E3Qw= +github.com/oleiade/lane/v2 v2.0.0/go.mod h1:i5FBPFAYSWCgLh58UkUGCChjcCzef/MI7PlQm2TKCeg= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= +github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/shoenig/test v1.11.0 h1:NoPa5GIoBwuqzIviCrnUJa+t5Xb4xi5Z+zODJnIDsEQ= +github.com/shoenig/test v1.11.0/go.mod h1:UxJ6u/x2v/TNs/LoLxBNJRV9DiwBBKYxXSyczsBHFoI= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= +github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= +github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= +go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg= +go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 h1:dNzwXjZKpMpE2JhmO+9HsPl42NIXFIFSUSSs0fiqra0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0/go.mod h1:90PoxvaEB5n6AOdZvi+yWJQoE95U8Dhhw2bSyRqnTD0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 h1:BEj3SPM81McUZHYjRS5pEgNgnmzGJ5tRpU5krWnV8Bs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0/go.mod h1:9cKLGBDzI/F3NoHLQGm4ZrYdIHsvGt6ej6hUowxY0J4= +go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE= +go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs= +go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs= +go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY= +go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis= +go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4= +go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w= +go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= +go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os= +go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= +golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= +golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= +golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= +golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc= +golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a h1:SGktgSolFCo75dnHJF2yMvnns6jCmHFJ0vE4Vn2JKvQ= +google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a/go.mod h1:a77HrdMjoeKbnd2jmgcWdaS++ZLZAEq3orIOAEIKiVw= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/grpc v1.72.2 h1:TdbGzwb82ty4OusHWepvFWGLgIbNo1/SUynEN0ssqv8= +google.golang.org/grpc v1.72.2/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY= +gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= +gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g= diff --git a/complement/tests/federation_test.go b/complement/tests/federation_test.go new file mode 100644 index 0000000000..d423792a72 --- /dev/null +++ b/complement/tests/federation_test.go @@ -0,0 +1,65 @@ +// This file is licensed under the Affero General Public License (AGPL) version 3. +// +// Copyright (C) 2026 Element Creations Ltd +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// See the GNU Affero General Public License for more details: +// . + +package synapse_tests + +import ( + "testing" + + "github.com/matrix-org/complement" + "github.com/matrix-org/complement/client" + "github.com/matrix-org/complement/helpers" + "github.com/matrix-org/gomatrixserverlib/spec" +) + +// Stub test to ensure that homeservers can communicate with each other (federation works correctly). +// +// TODO: This test will disappear once we have other real Synapse specific tests in +// place. This is simply here as an example without bloating the PR with some specific +// new tests. +func TestFederation(t *testing.T) { + // Create two homeservers + deployment := complement.Deploy(t, 2) + defer deployment.Destroy(t) + + alice := deployment.Register(t, "hs1", helpers.RegistrationOpts{}) + bob := deployment.Register(t, "hs2", helpers.RegistrationOpts{}) + + aliceRoomID := alice.MustCreateRoom(t, map[string]any{ + "preset": "public_chat", + }) + bobRoomID := bob.MustCreateRoom(t, map[string]any{ + "preset": "public_chat", + }) + + t.Run("parallel", func(t *testing.T) { + t.Run("HS1 -> HS2", func(t *testing.T) { + t.Parallel() + + alice.MustJoinRoom(t, bobRoomID, []spec.ServerName{ + deployment.GetFullyQualifiedHomeserverName(t, "hs2"), + }) + + bob.MustSyncUntil(t, client.SyncReq{}, client.SyncJoinedTo(alice.UserID, bobRoomID)) + }) + + t.Run("HS2 -> HS1", func(t *testing.T) { + t.Parallel() + + bob.MustJoinRoom(t, aliceRoomID, []spec.ServerName{ + deployment.GetFullyQualifiedHomeserverName(t, "hs1"), + }) + + alice.MustSyncUntil(t, client.SyncReq{}, client.SyncJoinedTo(bob.UserID, aliceRoomID)) + }) + }) +} diff --git a/complement/tests/internal/dockerutil/files.go b/complement/tests/internal/dockerutil/files.go new file mode 100644 index 0000000000..e19f684368 --- /dev/null +++ b/complement/tests/internal/dockerutil/files.go @@ -0,0 +1,68 @@ +package dockerutil + +import ( + "archive/tar" + "bytes" + "fmt" + "testing" + + "github.com/docker/docker/api/types/container" + "github.com/docker/docker/client" +) + +// Write `data` as a file into a container at the given `path`. +// +// Internally, produces an uncompressed single-file tape archive (tar) that is sent to the docker +// daemon to be unpacked into the container filesystem. +func WriteFileIntoContainer( + t *testing.T, + docker *client.Client, + containerID string, + path string, + data []byte, +) error { + // Create a fake/virtual tar file in memory that we can copy to the container + // via https://stackoverflow.com/a/52131297/796832 + var buf bytes.Buffer + tw := tar.NewWriter(&buf) + err := tw.WriteHeader(&tar.Header{ + Name: path, + Mode: 0777, + Size: int64(len(data)), + }) + if err != nil { + return fmt.Errorf( + "WriteIntoContainer: failed to write tarball header for %s: %v", + path, + err, + ) + } + _, err = tw.Write([]byte(data)) + if err != nil { + return fmt.Errorf("WriteIntoContainer: failed to write tarball data for %s: %w", path, err) + } + + err = tw.Close() + if err != nil { + return fmt.Errorf( + "WriteIntoContainer: failed to close tarball writer for %s: %w", + path, + err, + ) + } + + // Put our new fake file in the container volume + err = docker.CopyToContainer( + t.Context(), + containerID, + "/", + &buf, + container.CopyToContainerOptions{ + AllowOverwriteDirWithFile: false, + }, + ) + if err != nil { + return fmt.Errorf("WriteIntoContainer: failed to copy: %s", err) + } + return nil +} diff --git a/complement/tests/main_test.go b/complement/tests/main_test.go new file mode 100644 index 0000000000..1d62900d38 --- /dev/null +++ b/complement/tests/main_test.go @@ -0,0 +1,23 @@ +// This file is licensed under the Affero General Public License (AGPL) version 3. +// +// Copyright (C) 2026 Element Creations Ltd +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// See the GNU Affero General Public License for more details: +// . + +package synapse_tests + +import ( + "testing" + + "github.com/matrix-org/complement" +) + +func TestMain(m *testing.M) { + complement.TestMain(m, "synapse") +} diff --git a/complement/tests/oidc_test.go b/complement/tests/oidc_test.go new file mode 100644 index 0000000000..deabf49950 --- /dev/null +++ b/complement/tests/oidc_test.go @@ -0,0 +1,120 @@ +// This file is licensed under the Affero General Public License (AGPL) version 3. +// +// Copyright (C) 2026 Element Creations Ltd +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// See the GNU Affero General Public License for more details: +// . + +package synapse_tests + +import ( + "net/http" + "net/url" + "strings" + "testing" + + dockerClient "github.com/docker/docker/client" + "github.com/element-hq/synapse/tests/internal/dockerutil" + "github.com/matrix-org/complement" + "github.com/matrix-org/complement/client" + "github.com/matrix-org/complement/match" + "github.com/matrix-org/complement/must" +) + +const OIDC_HOMESERVER_CONFIG string = ` +oidc_providers: + - idp_id: "test_provider" + idp_name: "Test OIDC Provider" + issuer: "https://example.invalid" + client_id: "test_client_id" + client_secret: "test_secret" + scopes: ["openid"] + discover: true + user_mapping_provider: + module: "synapse.handlers.oidc.JinjaOidcMappingProvider" + config: + display_name_template: "{{ user.given_name }}" + email_template: "{{ user.email }}" +` + +// Test that Synapse still starts up when configured with an OIDC provider that is unavailable. +// +// This is a regression test: Synapse previously would fail to start up +// at all if the OIDC provider was down on startup. +// https://github.com/element-hq/synapse/issues/8088 +// +// Now instead of failing to start, Synapse will produce a 503 response on the +// `/_matrix/client/v3/login/sso/redirect/oidc-test_provider` endpoint. +func TestOIDCProviderUnavailable(t *testing.T) { + // Deploy a single homeserver + deployment := complement.Deploy(t, 1) + defer deployment.Destroy(t) + + // Get Docker client to manipulate container + dc, err := dockerClient.NewClientWithOpts( + dockerClient.FromEnv, + dockerClient.WithAPIVersionNegotiation(), + ) + must.NotError(t, "failed creating docker client", err) + + // Configure the OIDC Provider by writing a config fragment + err = dockerutil.WriteFileIntoContainer( + t, + dc, + deployment.ContainerID(t, "hs1"), + "/conf/homeserver.d/oidc_provider.yaml", + []byte(OIDC_HOMESERVER_CONFIG), + ) + if err != nil { + t.Fatalf("Failed to write updated config to container: %v", err) + } + + // Restart the homeserver to apply the new config + deployment.StopServer(t, "hs1") + // Careful: port number changes here + deployment.StartServer(t, "hs1") + // Must get after the restart so the port number is correct + unauthedClient := deployment.UnauthenticatedClient(t, "hs1") + + // Test that trying to log in with an OIDC provider that is down + // causes an HTML error page to be shown to the user. + // (This replaces the redirect that would happen if the provider was + // up.) + // + // More importantly, implicitly tests that Synapse can start up + // and answer requests even though an OIDC provider is down. + t.Run("/login/sso/redirect shows HTML error", func(t *testing.T) { + // Build a request to the /redirect/ endpoint, that would normally be navigated to + // by the user's browser in order to start the login flow. + queryParams := url.Values{} + queryParams.Add("redirectUrl", "http://redirect.invalid/redirect") + res := unauthedClient.Do( + t, + "GET", + []string{"_matrix", "client", "v3", "login", "sso", "redirect", "oidc-test_provider"}, + client.WithQueries(queryParams), + ) + + body := must.MatchResponse(t, res, match.HTTPResponse{ + // Should get a 503 + StatusCode: http.StatusServiceUnavailable, + + Headers: map[string]string{ + // Should get an HTML page explaining the problem to the user + "Content-Type": "text/html; charset=utf-8", + }, + }) + + bodyText := string(body) + + // The HTML page contains phrases from the template we expect + if !strings.Contains(bodyText, "login provider is unavailable right now") { + t.Fatalf("Keyword not found in HTML error page, got %s", bodyText) + } + }) +} diff --git a/complement/tests/synapse_version_check_test.go b/complement/tests/synapse_version_check_test.go new file mode 100644 index 0000000000..790a6a40ce --- /dev/null +++ b/complement/tests/synapse_version_check_test.go @@ -0,0 +1,101 @@ +// This file is licensed under the Affero General Public License (AGPL) version 3. +// +// Copyright (C) 2026 Element Creations Ltd +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// See the GNU Affero General Public License for more details: +// . + +package synapse_tests + +import ( + "net/http" + "os/exec" + "strings" + "testing" + + "github.com/matrix-org/complement" + "github.com/matrix-org/complement/match" + "github.com/matrix-org/complement/must" + "github.com/tidwall/gjson" +) + +func TestSynapseVersion(t *testing.T) { + deployment := complement.Deploy(t, 1) + defer deployment.Destroy(t) + + unauthedClient := deployment.UnauthenticatedClient(t, "hs1") + + // Sanity check that the version of Synapse used in the `COMPLEMENT_BASE_IMAGE` + // matches the same git commit we have checked out. This ensures that the image being + // used in Complement is the one that we just built locally with `complement.sh` + // instead of accidentally pulling in some remote one. + // + // This test is expected to pass if you use `complement.sh`. + // + // If this test fails, it probably means that Complement is using an image that + // doesn't encompass the changes you have checked out (unexpected). We want to yell + // loudly and point out what's wrong instead of silently letting your PRs pass + // without actually being tested. + t.Run("Synapse version matches current git checkout", func(t *testing.T) { + // Get the Synapse version details of the current git checkout + checkoutSynapseVersion := runCommand( + t, + []string{ + "poetry", + "run", + "python", + "-c", + "from synapse.util import SYNAPSE_VERSION; print(SYNAPSE_VERSION)", + }, + ) + + // Find the version details of the Synapse instance deployed from the Docker image + res := unauthedClient.MustDo(t, "GET", []string{"_matrix", "federation", "v1", "version"}) + body := must.MatchResponse(t, res, match.HTTPResponse{ + StatusCode: http.StatusOK, + JSON: []match.JSON{ + match.JSONKeyPresent("server"), + }, + }) + rawSynapseVersionString := gjson.GetBytes(body, "server.version").Str + t.Logf( + "Synapse version string from federation version endpoint: %s", + rawSynapseVersionString, + ) + + must.Equal( + t, + rawSynapseVersionString, + checkoutSynapseVersion, + "Synapse version in the checkout doesn't match the Synapse version that Complement is running. "+ + "If this test fails, it probably means that Complement is using an image that "+ + "doesn't encompass the changes you have checked out (unexpected). We want to yell "+ + "loudly and point out what's wrong instead of silently letting your PRs pass "+ + "without actually being tested.", + ) + }) +} + +// runCommand will run the given command and return the stdout (whitespace +// trimmed). +func runCommand(t *testing.T, commandPieces []string) string { + t.Helper() + + // Then run our actual command + cmd := exec.Command(commandPieces[0], commandPieces[1:]...) + output, err := cmd.Output() + if err != nil { + t.Fatalf( + "runCommand: failed to run command (%s): %v", + strings.Join(commandPieces, " "), + err, + ) + } + + return strings.TrimSpace(string(output)) +} diff --git a/contrib/cmdclient/console.py b/contrib/cmdclient/console.py index 9b5d33d2b1..1c867d5336 100755 --- a/contrib/cmdclient/console.py +++ b/contrib/cmdclient/console.py @@ -33,7 +33,6 @@ import sys import time import urllib from http import TwistedHttpClient -from typing import Optional import urlparse from signedjson.key import NACL_ED25519, decode_verify_key_bytes @@ -726,7 +725,7 @@ class SynapseCmd(cmd.Cmd): method, path, data=None, - query_params: Optional[dict] = None, + query_params: dict | None = None, alt_text=None, ): """Runs an HTTP request and pretty prints the output. diff --git a/contrib/cmdclient/http.py b/contrib/cmdclient/http.py index 54363e4259..b92ccdd932 100644 --- a/contrib/cmdclient/http.py +++ b/contrib/cmdclient/http.py @@ -22,7 +22,6 @@ import json import urllib from pprint import pformat -from typing import Optional from twisted.internet import defer, reactor from twisted.web.client import Agent, readBody @@ -90,7 +89,7 @@ class TwistedHttpClient(HttpClient): body = yield readBody(response) return json.loads(body) - def _create_put_request(self, url, json_data, headers_dict: Optional[dict] = None): + def _create_put_request(self, url, json_data, headers_dict: dict | None = None): """Wrapper of _create_request to issue a PUT request""" headers_dict = headers_dict or {} @@ -101,7 +100,7 @@ class TwistedHttpClient(HttpClient): "PUT", url, producer=_JsonProducer(json_data), headers_dict=headers_dict ) - def _create_get_request(self, url, headers_dict: Optional[dict] = None): + def _create_get_request(self, url, headers_dict: dict | None = None): """Wrapper of _create_request to issue a GET request""" return self._create_request("GET", url, headers_dict=headers_dict or {}) @@ -113,7 +112,7 @@ class TwistedHttpClient(HttpClient): data=None, qparams=None, jsonreq=True, - headers: Optional[dict] = None, + headers: dict | None = None, ): headers = headers or {} @@ -138,7 +137,7 @@ class TwistedHttpClient(HttpClient): @defer.inlineCallbacks def _create_request( - self, method, url, producer=None, headers_dict: Optional[dict] = None + self, method, url, producer=None, headers_dict: dict | None = None ): """Creates and sends a request to the given url""" headers_dict = headers_dict or {} diff --git a/contrib/grafana/synapse.json b/contrib/grafana/synapse.json index e23afcf2d3..ceacc10369 100644 --- a/contrib/grafana/synapse.json +++ b/contrib/grafana/synapse.json @@ -1,17 +1,21 @@ { + "__inputs": [ + { + "name": "DS_PROMETHEUS", + "label": "prometheus", + "description": "", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + } + ], "__elements": {}, "__requires": [ { "type": "grafana", "id": "grafana", "name": "Grafana", - "version": "9.2.2" - }, - { - "type": "panel", - "id": "graph", - "name": "Graph (old)", - "version": "" + "version": "12.3.1" }, { "type": "panel", @@ -53,7 +57,8 @@ "uid": "${DS_PROMETHEUS}" }, "enable": true, - "expr": "changes(process_start_time_seconds{instance=\"$instance\",job=~\"synapse\"}[$bucket_size]) * on (instance, job) group_left(version) synapse_build_info{instance=\"$instance\",job=\"synapse\"}", + "expr": "(\n changes(process_start_time_seconds{job=\"synapse\"}[$bucket_size]) * on (instance, job, index) group_left(server_name)\n synapse_server_name_info{server_name=\"$server_name\"}\n) * on (instance, job, index) group_left(version) synapse_build_info{job=\"synapse\"}", + "hide": false, "iconColor": "purple", "name": "deploys", "titleFormat": "Deployed {{version}}" @@ -77,14 +82,9 @@ "type": "dashboards" } ], - "liveNow": false, "panels": [ { "collapsed": false, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, "gridPos": { "h": 1, "w": 24, @@ -93,31 +93,10 @@ }, "id": 73, "panels": [], - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" - } - ], "title": "Overview", "type": "row" }, { - "cards": { - "cardPadding": -1, - "cardRound": 0 - }, - "color": { - "cardColor": "#b4ff00", - "colorScale": "sqrt", - "colorScheme": "interpolateInferno", - "exponent": 0.5, - "mode": "spectrum" - }, - "dataFormat": "tsbuckets", "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -142,14 +121,7 @@ "x": 0, "y": 1 }, - "heatmap": {}, - "hideZeroBuckets": false, - "highlightCards": true, "id": 189, - "legend": { - "show": false - }, - "links": [], "options": { "calculate": false, "calculation": {}, @@ -179,7 +151,8 @@ }, "showValue": "never", "tooltip": { - "show": true, + "mode": "single", + "showColorScale": false, "yHistogram": true }, "yAxis": { @@ -188,14 +161,13 @@ "unit": "s" } }, - "pluginVersion": "9.2.2", - "reverseYBuckets": false, + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "sum(rate(synapse_http_server_response_time_seconds_bucket{servlet='RoomSendEventRestServlet',instance=\"$instance\",code=~\"2..\"}[$bucket_size])) by (le)", + "expr": "sum(rate(synapse_http_server_response_time_seconds_bucket{servlet='RoomSendEventRestServlet',server_name=\"$server_name\",code=~\"2..\"}[$bucket_size])) by (le)", "format": "heatmap", "interval": "", "intervalFactor": 1, @@ -204,33 +176,285 @@ } ], "title": "Event Send Time (excluding errors, all workers)", - "tooltip": { - "show": true, - "showHistogram": true - }, - "type": "heatmap", - "xAxis": { - "show": true - }, - "yAxis": { - "format": "s", - "logBase": 2, - "show": true - }, - "yBucketBound": "auto" + "type": "heatmap" }, { "datasource": { - "uid": "${DS_PROMETHEUS}", - "type": "prometheus" + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" }, - "aliasColors": {}, - "dashLength": 10, + "description": "", "fieldConfig": { "defaults": { - "links": [] + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 35, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 0, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "line" + } + }, + "links": [], + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "transparent", + "value": 0 + }, + { + "color": "orange", + "value": 1 + }, + { + "color": "red", + "value": 2 + } + ] + }, + "unit": "s" }, - "overrides": [] + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Avg" + }, + "properties": [ + { + "id": "custom.fillOpacity", + "value": 0 + }, + { + "id": "custom.lineWidth", + "value": 3 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "99%" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "#C4162A", + "mode": "fixed" + } + }, + { + "id": "custom.fillBelowTo", + "value": "90%" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "90%" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "#FF7383", + "mode": "fixed" + } + }, + { + "id": "custom.fillBelowTo", + "value": "75%" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "75%" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "#FFEE52", + "mode": "fixed" + } + }, + { + "id": "custom.fillBelowTo", + "value": "50%" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "50%" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "#73BF69", + "mode": "fixed" + } + }, + { + "id": "custom.fillBelowTo", + "value": "25%" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "25%" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "#1F60C4", + "mode": "fixed" + } + }, + { + "id": "custom.fillBelowTo", + "value": "5%" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "5%" + }, + "properties": [ + { + "id": "custom.lineWidth", + "value": 0 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Average" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "rgb(255, 255, 255)", + "mode": "fixed" + } + }, + { + "id": "custom.drawStyle", + "value": "line" + }, + { + "id": "custom.lineWidth", + "value": 3 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Local events being persisted" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "#96d98D", + "mode": "fixed" + } + }, + { + "id": "custom.showPoints", + "value": "always" + }, + { + "id": "unit", + "value": "hertz" + }, + { + "id": "custom.axisPlacement", + "value": "right" + }, + { + "id": "custom.fillOpacity", + "value": 0 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "All events being persisted" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "#B877D9", + "mode": "fixed" + } + }, + { + "id": "custom.showPoints", + "value": "always" + }, + { + "id": "unit", + "value": "hertz" + }, + { + "id": "custom.axisPlacement", + "value": "right" + }, + { + "id": "custom.fillOpacity", + "value": 0 + } + ] + } + ] }, "gridPos": { "h": 9, @@ -239,98 +463,27 @@ "y": 1 }, "id": 152, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "nullPointMode": "connected", "options": { - "alertThreshold": true - }, - "paceLength": 10, - "pluginVersion": "10.4.3", - "pointradius": 5, - "renderer": "flot", - "seriesOverrides": [ - { - "alias": "Avg", - "fill": 0, - "linewidth": 3, - "$$hashKey": "object:48" + "alertThreshold": true, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true }, - { - "alias": "99%", - "color": "#C4162A", - "fillBelowTo": "90%", - "$$hashKey": "object:49" - }, - { - "alias": "90%", - "color": "#FF7383", - "fillBelowTo": "75%", - "$$hashKey": "object:50" - }, - { - "alias": "75%", - "color": "#FFEE52", - "fillBelowTo": "50%", - "$$hashKey": "object:51" - }, - { - "alias": "50%", - "color": "#73BF69", - "fillBelowTo": "25%", - "$$hashKey": "object:52" - }, - { - "alias": "25%", - "color": "#1F60C4", - "fillBelowTo": "5%", - "$$hashKey": "object:53" - }, - { - "alias": "5%", - "lines": false, - "$$hashKey": "object:54" - }, - { - "alias": "Average", - "color": "rgb(255, 255, 255)", - "lines": true, - "linewidth": 3, - "$$hashKey": "object:55" - }, - { - "alias": "Local events being persisted", - "color": "#96d98D", - "points": true, - "yaxis": 2, - "zindex": -3, - "$$hashKey": "object:56" - }, - { - "$$hashKey": "object:329", - "color": "#B877D9", - "alias": "All events being persisted", - "points": true, - "yaxis": 2, - "zindex": -3 + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" } - ], - "spaceLength": 10, + }, + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.99, sum(rate(synapse_http_server_response_time_seconds_bucket{servlet='RoomSendEventRestServlet',index=~\"$index\",instance=\"$instance\",code=~\"2..\"}[$bucket_size])) by (le))", + "expr": "histogram_quantile(0.99, sum(rate(synapse_http_server_response_time_seconds_bucket{servlet='RoomSendEventRestServlet',index=~\"$index\",server_name=\"$server_name\",code=~\"2..\"}[$bucket_size])) by (le))", "format": "time_series", "intervalFactor": 1, "legendFormat": "99%", @@ -340,7 +493,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.9, sum(rate(synapse_http_server_response_time_seconds_bucket{servlet='RoomSendEventRestServlet',index=~\"$index\",instance=\"$instance\",code=~\"2..\"}[$bucket_size])) by (le))", + "expr": "histogram_quantile(0.9, sum(rate(synapse_http_server_response_time_seconds_bucket{servlet='RoomSendEventRestServlet',index=~\"$index\",server_name=\"$server_name\",code=~\"2..\"}[$bucket_size])) by (le))", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -351,7 +504,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.75, sum(rate(synapse_http_server_response_time_seconds_bucket{servlet='RoomSendEventRestServlet',index=~\"$index\",instance=\"$instance\",code=~\"2..\"}[$bucket_size])) by (le))", + "expr": "histogram_quantile(0.75, sum(rate(synapse_http_server_response_time_seconds_bucket{servlet='RoomSendEventRestServlet',index=~\"$index\",server_name=\"$server_name\",code=~\"2..\"}[$bucket_size])) by (le))", "format": "time_series", "intervalFactor": 1, "legendFormat": "75%", @@ -361,7 +514,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.5, sum(rate(synapse_http_server_response_time_seconds_bucket{servlet='RoomSendEventRestServlet',index=~\"$index\",instance=\"$instance\",code=~\"2..\"}[$bucket_size])) by (le))", + "expr": "histogram_quantile(0.5, sum(rate(synapse_http_server_response_time_seconds_bucket{servlet='RoomSendEventRestServlet',index=~\"$index\",server_name=\"$server_name\",code=~\"2..\"}[$bucket_size])) by (le))", "format": "time_series", "intervalFactor": 1, "legendFormat": "50%", @@ -371,7 +524,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.25, sum(rate(synapse_http_server_response_time_seconds_bucket{servlet='RoomSendEventRestServlet',index=~\"$index\",instance=\"$instance\",code=~\"2..\"}[$bucket_size])) by (le))", + "expr": "histogram_quantile(0.25, sum(rate(synapse_http_server_response_time_seconds_bucket{servlet='RoomSendEventRestServlet',index=~\"$index\",server_name=\"$server_name\",code=~\"2..\"}[$bucket_size])) by (le))", "legendFormat": "25%", "refId": "F" }, @@ -379,7 +532,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.05, sum(rate(synapse_http_server_response_time_seconds_bucket{servlet='RoomSendEventRestServlet',index=~\"$index\",instance=\"$instance\",code=~\"2..\"}[$bucket_size])) by (le))", + "expr": "histogram_quantile(0.05, sum(rate(synapse_http_server_response_time_seconds_bucket{servlet='RoomSendEventRestServlet',index=~\"$index\",server_name=\"$server_name\",code=~\"2..\"}[$bucket_size])) by (le))", "legendFormat": "5%", "refId": "G" }, @@ -387,161 +540,130 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "sum(rate(synapse_http_server_response_time_seconds_sum{servlet='RoomSendEventRestServlet',index=~\"$index\",instance=\"$instance\",code=~\"2..\"}[$bucket_size])) / sum(rate(synapse_http_server_response_time_seconds_count{servlet='RoomSendEventRestServlet',index=~\"$index\",instance=\"$instance\",code=~\"2..\"}[$bucket_size]))", - "legendFormat": "Average", - "refId": "H", "editorMode": "code", - "range": true + "expr": "sum(rate(synapse_http_server_response_time_seconds_sum{servlet='RoomSendEventRestServlet',index=~\"$index\",server_name=\"$server_name\",code=~\"2..\"}[$bucket_size])) / sum(rate(synapse_http_server_response_time_seconds_count{servlet='RoomSendEventRestServlet',index=~\"$index\",server_name=\"$server_name\",code=~\"2..\"}[$bucket_size]))", + "legendFormat": "Average", + "range": true, + "refId": "H" }, { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "sum(rate(synapse_http_server_response_time_seconds_count{servlet='RoomSendEventRestServlet',index=~\"$index\",instance=\"$instance\",code=~\"2..\"}[$bucket_size]))", + "editorMode": "code", + "expr": "sum(rate(synapse_http_server_response_time_seconds_count{servlet='RoomSendEventRestServlet',index=~\"$index\",server_name=\"$server_name\",code=~\"2..\"}[$bucket_size]))", "hide": false, "instant": false, "legendFormat": "Local events being persisted", - "refId": "E", - "editorMode": "code" + "refId": "E" }, { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "sum(rate(synapse_storage_events_persisted_events_total{instance=\"$instance\"}[$bucket_size]))", + "editorMode": "code", + "expr": "sum(rate(synapse_storage_events_persisted_events_total{server_name=\"$server_name\"}[$bucket_size]))", "hide": false, "instant": false, "legendFormat": "All events being persisted", - "refId": "I", - "editorMode": "code" + "refId": "I" } ], - "thresholds": [ - { - "$$hashKey": "object:283", - "colorMode": "warning", - "fill": false, - "line": true, - "op": "gt", - "value": 1, - "yaxis": "left" - }, - { - "$$hashKey": "object:284", - "colorMode": "critical", - "fill": false, - "line": true, - "op": "gt", - "value": 2, - "yaxis": "left" - } - ], - "timeRegions": [], "title": "Event Send Time Quantiles (excluding errors, all workers)", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [], - "name": null, - "buckets": null - }, - "yaxes": [ - { - "$$hashKey": "object:255", - "format": "s", - "label": "", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:256", - "format": "hertz", - "label": "", - "logBase": 1, - "min": "0", - "show": true - } - ], - "yaxis": { - "align": false - }, - "bars": false, - "dashes": false, - "description": "", - "fill": 0, - "fillGradient": 0, - "hiddenSeries": false, - "linewidth": 0, - "percentage": false, - "points": false, - "stack": false, - "steppedLine": false, - "timeFrom": null, - "timeShift": null + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, "fieldConfig": { "defaults": { - "links": [] + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 3, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "line+area" + } + }, + "links": [], + "mappings": [], + "max": 1.5, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "transparent", + "value": 0 + }, + { + "color": "red", + "value": 1 + } + ] + }, + "unit": "percentunit" }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 0, "y": 10 }, - "hiddenSeries": false, "id": 75, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 3, - "links": [], - "nullPointMode": "null", "options": { - "alertThreshold": true + "alertThreshold": true, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } }, - "paceLength": 10, - "percentage": false, - "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(process_cpu_seconds_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", + "expr": "rate(process_cpu_seconds_total{job=~\"$job\",index=~\"$index\"}[$bucket_size]) * on (instance, job, index) group_left(server_name)\nsynapse_server_name_info{server_name=\"$server_name\"}", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -549,109 +671,100 @@ "refId": "A" } ], - "thresholds": [ - { - "$$hashKey": "object:566", - "colorMode": "critical", - "fill": true, - "line": true, - "op": "gt", - "value": 1, - "yaxis": "left" - } - ], - "timeRegions": [], "title": "CPU usage", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:538", - "format": "percentunit", - "logBase": 1, - "max": "1.5", - "min": "0", - "show": true - }, - { - "$$hashKey": "object:539", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, - "editable": true, - "error": false, "fieldConfig": { "defaults": { - "links": [] + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 3, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "links": [], + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "bytes" }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, - "grid": {}, "gridPos": { "h": 9, "w": 12, "x": 12, "y": 10 }, - "hiddenSeries": false, "id": 198, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 3, - "links": [], - "nullPointMode": "null", "options": { - "alertThreshold": true + "alertThreshold": true, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } }, - "paceLength": 10, - "percentage": false, - "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "process_resident_memory_bytes{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}", + "expr": "process_resident_memory_bytes{job=~\"$job\",index=~\"$index\"} * on (instance, job, index) group_left(server_name)\nsynapse_server_name_info{server_name=\"$server_name\"}", "format": "time_series", "interval": "", "intervalFactor": 2, @@ -664,46 +777,15 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "sum(process_resident_memory_bytes{instance=\"$instance\",job=~\"$job\",index=~\"$index\"})", + "expr": "sum(process_resident_memory_bytes{job=~\"$job\",index=~\"$index\"}) * on (instance, job, index) group_left(server_name)\nsynapse_server_name_info{server_name=\"$server_name\"}", "hide": true, "interval": "", "legendFormat": "total", "refId": "B" } ], - "thresholds": [], - "timeRegions": [], "title": "Memory", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "cumulative" - }, - "transformations": [], - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:1560", - "format": "bytes", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:1561", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { "datasource": { @@ -716,12 +798,14 @@ "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "axisSoftMax": 1, "barAlignment": 0, + "barWidthFactor": 0.6, "drawStyle": "line", "fillOpacity": 0, "gradientMode": "none", @@ -730,6 +814,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 10, "pointSize": 5, @@ -737,6 +822,7 @@ "type": "linear" }, "showPoints": "never", + "showValues": false, "spanNulls": false, "stacking": { "group": "A", @@ -752,7 +838,7 @@ "steps": [ { "color": "green", - "value": null + "value": 0 } ] } @@ -774,10 +860,12 @@ "showLegend": true }, "tooltip": { + "hideZeros": false, "mode": "single", "sort": "none" } }, + "pluginVersion": "12.3.1", "targets": [ { "datasource": { @@ -785,7 +873,7 @@ "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "synapse_build_info{instance=\"$instance\", job=\"synapse\"} - 1", + "expr": "(\n synapse_build_info{job=\"synapse\"} * on (instance, job, index) group_left(server_name)\n synapse_server_name_info{server_name=\"$server_name\"}\n) - 1", "legendFormat": "version {{version}}", "range": true, "refId": "deployed_synapse_versions" @@ -795,69 +883,115 @@ "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, "fieldConfig": { "defaults": { - "links": [] + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "links": [], + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" }, - "overrides": [] + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/max$/" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "#890F02", + "mode": "fixed" + } + }, + { + "id": "custom.fillOpacity", + "value": 0 + } + ] + } + ] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 7, "w": 12, "x": 12, "y": 19 }, - "hiddenSeries": false, "id": 37, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { - "alertThreshold": true - }, - "paceLength": 10, - "percentage": false, - "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "$$hashKey": "object:639", - "alias": "/max$/", - "color": "#890F02", - "fill": 0, - "legend": false + "alertThreshold": true, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" } - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, + }, + "pluginVersion": "12.3.1", "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "process_open_fds{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}", + "expr": "process_open_fds{job=~\"$job\",index=~\"$index\"} * on (instance, job, index) group_left(server_name)\nsynapse_server_name_info{server_name=\"$server_name\"}", "format": "time_series", "hide": false, "interval": "", @@ -870,7 +1004,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "process_max_fds{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}", + "expr": "process_max_fds{job=~\"$job\",index=~\"$index\"} * on (instance, job, index) group_left(server_name)\nsynapse_server_name_info{server_name=\"$server_name\"}", "format": "time_series", "hide": true, "interval": "", @@ -880,45 +1014,11 @@ "step": 20 } ], - "thresholds": [], - "timeRegions": [], "title": "Open FDs", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:650", - "format": "none", - "label": "", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:651", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { "collapsed": true, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, "gridPos": { "h": 1, "w": 24, @@ -928,79 +1028,34 @@ "id": 54, "panels": [ { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "editable": true, - "error": false, "fieldConfig": { "defaults": { "links": [] }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, - "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 0, "y": 27 }, - "hiddenSeries": false, "id": 5, - "legend": { - "alignAsTable": false, - "avg": false, - "current": false, - "hideEmpty": false, - "hideZero": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 3, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "$$hashKey": "object:1240", - "alias": "/user/" - }, - { - "$$hashKey": "object:1241", - "alias": "/system/" - } - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "rate(process_cpu_system_seconds_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", + "expr": "rate(process_cpu_system_seconds_total{job=~\"$job\",index=~\"$index\"}[$bucket_size]) * on (instance, job, index) group_left(server_name)\nsynapse_server_name_info{server_name=\"$server_name\"}", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{job}}-{{index}} system ", @@ -1013,7 +1068,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(process_cpu_user_seconds_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", + "expr": "rate(process_cpu_user_seconds_total{job=~\"$job\",index=~\"$index\"}[$bucket_size]) * on (instance, job, index) group_left(server_name)\nsynapse_server_name_info{server_name=\"$server_name\"}", "format": "time_series", "hide": false, "interval": "", @@ -1023,70 +1078,8 @@ "step": 20 } ], - "thresholds": [ - { - "$$hashKey": "object:1278", - "colorMode": "custom", - "fillColor": "rgba(255, 255, 255, 1)", - "line": true, - "lineColor": "rgba(216, 200, 27, 0.27)", - "op": "gt", - "value": 0.5, - "yaxis": "left" - }, - { - "$$hashKey": "object:1279", - "colorMode": "custom", - "fillColor": "rgba(255, 255, 255, 1)", - "line": true, - "lineColor": "rgb(87, 6, 16)", - "op": "gt", - "value": 0.8, - "yaxis": "left" - }, - { - "$$hashKey": "object:1498", - "colorMode": "critical", - "fill": true, - "line": true, - "op": "gt", - "value": 1, - "yaxis": "left" - } - ], - "timeRegions": [], "title": "CPU", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:1250", - "format": "percentunit", - "label": "", - "logBase": 1, - "max": "1.2", - "min": 0, - "show": true - }, - { - "$$hashKey": "object:1251", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { "datasource": { @@ -1154,8 +1147,6 @@ "y": 27 }, "id": 105, - "interval": "", - "links": [], "options": { "legend": { "calcs": [], @@ -1176,7 +1167,7 @@ "uid": "${DS_PROMETHEUS}" }, "exemplar": true, - "expr": "histogram_quantile(0.999, rate(python_twisted_reactor_tick_time_bucket{index=~\"$index\",instance=\"$instance\",job=~\"$job\"}[$bucket_size]))", + "expr": "histogram_quantile(0.999, rate(python_twisted_reactor_tick_time_bucket{index=~\"$index\",job=~\"$job\"}[$bucket_size])) * on (instance, job, index) group_left(server_name)\nsynapse_server_name_info{server_name=\"$server_name\"}", "hide": false, "interval": "", "legendFormat": "{{job}}-{{index}} 99.9%", @@ -1188,7 +1179,7 @@ "uid": "${DS_PROMETHEUS}" }, "exemplar": true, - "expr": "histogram_quantile(0.99, rate(python_twisted_reactor_tick_time_bucket{index=~\"$index\",instance=\"$instance\",job=~\"$job\"}[$bucket_size]))", + "expr": "histogram_quantile(0.99, rate(python_twisted_reactor_tick_time_bucket{index=~\"$index\",job=~\"$job\"}[$bucket_size])) * on (instance, job, index) group_left(server_name)\nsynapse_server_name_info{server_name=\"$server_name\"}", "format": "time_series", "interval": "", "intervalFactor": 2, @@ -1202,7 +1193,7 @@ "uid": "${DS_PROMETHEUS}" }, "exemplar": true, - "expr": "histogram_quantile(0.95, rate(python_twisted_reactor_tick_time_bucket{index=~\"$index\",instance=\"$instance\",job=~\"$job\"}[$bucket_size]))", + "expr": "histogram_quantile(0.95, rate(python_twisted_reactor_tick_time_bucket{index=~\"$index\",job=~\"$job\"}[$bucket_size])) * on (instance, job, index) group_left(server_name)\nsynapse_server_name_info{server_name=\"$server_name\"}", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -1214,7 +1205,7 @@ "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.90, rate(python_twisted_reactor_tick_time_bucket{index=~\"$index\",instance=\"$instance\",job=~\"$job\"}[$bucket_size]))", + "expr": "histogram_quantile(0.90, rate(python_twisted_reactor_tick_time_bucket{index=~\"$index\",job=~\"$job\"}[$bucket_size])) * on (instance, job, index) group_left(server_name)\nsynapse_server_name_info{server_name=\"$server_name\"}", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{job}}-{{index}} 90%", @@ -1225,7 +1216,7 @@ "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(python_twisted_reactor_tick_time_sum{index=~\"$index\",instance=\"$instance\",job=~\"$job\"}[$bucket_size]) / rate(python_twisted_reactor_tick_time_count{index=~\"$index\",instance=\"$instance\",job=~\"$job\"}[$bucket_size])", + "expr": "(\n\trate(python_twisted_reactor_tick_time_sum{index=~\"$index\",job=~\"$job\"}[$bucket_size]) * on (instance, job, index) group_left(server_name)\n\tsynapse_server_name_info{server_name=\"$server_name\"}\n) / (\n\trate(python_twisted_reactor_tick_time_count{index=~\"$index\",job=~\"$job\"}[$bucket_size]) * on (instance, job, index) group_left(server_name)\n\tsynapse_server_name_info{server_name=\"$server_name\"}\n)", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{job}}-{{index}} mean", @@ -1236,64 +1227,32 @@ "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, - "editable": true, - "error": false, "fieldConfig": { "defaults": { "links": [] }, "overrides": [] }, - "fill": 0, - "fillGradient": 0, - "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 0, "y": 34 }, - "hiddenSeries": false, "id": 34, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "process_resident_memory_bytes{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}", + "expr": "process_resident_memory_bytes{job=~\"$job\",index=~\"$index\"} * on (instance, job, index) group_left(server_name)\nsynapse_server_name_info{server_name=\"$server_name\"}", "format": "time_series", "interval": "", "intervalFactor": 2, @@ -1306,49 +1265,16 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "sum(process_resident_memory_bytes{instance=\"$instance\",job=~\"$job\",index=~\"$index\"})", + "expr": "sum by (server_name) (\n process_resident_memory_bytes{job=~\"$job\",index=~\"$index\"} * on (instance, job, index) group_left(server_name)\n synapse_server_name_info{server_name=\"$server_name\"}\n)", "interval": "", "legendFormat": "total", "refId": "B" } ], - "thresholds": [], - "timeRegions": [], "title": "Memory", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "cumulative" - }, - "transformations": [], - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "bytes", - "logBase": 1, - "min": "0", - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -1358,54 +1284,23 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 7, "w": 12, "x": 12, "y": 34 }, - "hiddenSeries": false, "id": 49, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "alias": "/^up/", - "legend": false, - "yaxis": 2 - } - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "scrape_duration_seconds{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}", + "expr": "scrape_duration_seconds{job=~\"$job\",index=~\"$index\"} * on (instance, job, index) group_left(server_name)\nsynapse_server_name_info{server_name=\"$server_name\"}", "format": "time_series", "interval": "", "intervalFactor": 2, @@ -1414,46 +1309,10 @@ "step": 20 } ], - "thresholds": [], - "timeRegions": [], "title": "Prometheus scrape time", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "s", - "logBase": 1, - "min": "0", - "show": true - }, - { - "decimals": 0, - "format": "none", - "label": "", - "logBase": 1, - "max": "0", - "min": "-1", - "show": false - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" @@ -1464,57 +1323,24 @@ }, "overrides": [] }, - "fill": 0, - "fillGradient": 0, "gridPos": { "h": 7, "w": 12, "x": 0, "y": 41 }, - "hiddenSeries": false, "id": 53, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "$$hashKey": "object:116", - "alias": "/^version .*/", - "lines": true, - "linewidth": 6, - "points": false - } - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "min_over_time(up{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", + "expr": "min_over_time(up{job=~\"$job\",index=~\"$index\"}[$bucket_size]) * on (instance, job, index) group_left(server_name)\nsynapse_server_name_info{server_name=\"$server_name\"}", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{job}}-{{index}}", @@ -1527,48 +1353,17 @@ "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "synapse_build_info{instance=\"$instance\", job=\"synapse\"} - 1", + "expr": "(\n synapse_build_info{job=\"synapse\"} * on (instance, job, index) group_left(server_name)\n synapse_server_name_info{server_name=\"$server_name\"}\n) - 1", "hide": false, "legendFormat": "version {{version}}", "range": true, "refId": "deployed_synapse_versions" } ], - "thresholds": [], - "timeRegions": [], "title": "Up", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -1578,47 +1373,23 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 7, "w": 12, "x": 12, "y": 41 }, - "hiddenSeries": false, "id": 120, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null as zero", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": true, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_http_server_response_ru_utime_seconds{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])+rate(synapse_http_server_response_ru_stime_seconds{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", + "expr": "rate(synapse_http_server_response_ru_utime_seconds{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])+rate(synapse_http_server_response_ru_stime_seconds{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", "format": "time_series", "hide": false, "instant": false, @@ -1630,7 +1401,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_background_process_ru_utime_seconds_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])+rate(synapse_background_process_ru_stime_seconds_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", + "expr": "rate(synapse_background_process_ru_utime_seconds_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])+rate(synapse_background_process_ru_stime_seconds_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", "format": "time_series", "hide": false, "instant": false, @@ -1640,52 +1411,10 @@ "refId": "B" } ], - "thresholds": [ - { - "colorMode": "critical", - "fill": true, - "line": true, - "op": "gt", - "value": 1, - "yaxis": "left" - } - ], - "timeRegions": [], "title": "Stacked CPU usage", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:572", - "format": "percentunit", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:573", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" @@ -1696,48 +1425,24 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 7, "w": 12, "x": 0, "y": 48 }, - "hiddenSeries": false, "id": 136, - "interval": "", - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "rate(synapse_http_client_requests_total{job=~\"$job\",index=~\"$index\",instance=\"$instance\"}[$bucket_size])", + "expr": "rate(synapse_http_client_requests_total{job=~\"$job\",index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])", "legendFormat": "{{job}}-{{index}} {{method}}", "range": true, "refId": "A" @@ -1747,43 +1452,14 @@ "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "rate(synapse_http_matrixfederationclient_requests_total{job=~\"$job\",index=~\"$index\",instance=\"$instance\"}[$bucket_size])", + "expr": "rate(synapse_http_matrixfederationclient_requests_total{job=~\"$job\",index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])", "legendFormat": "{{job}}-{{index}} {{method}} (federation)", "range": true, "refId": "B" } ], - "thresholds": [], - "timeRegions": [], "title": "Outgoing HTTP request rate", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:123", - "format": "reqps", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:124", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { "datasource": { @@ -1867,7 +1543,7 @@ "uid": "${DS_PROMETHEUS}" }, "exemplar": true, - "expr": "synapse_threadpool_working_threads{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}", + "expr": "synapse_threadpool_working_threads{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}", "interval": "", "legendFormat": "{{job}}-{{index}} {{name}}", "refId": "A" @@ -1877,24 +1553,11 @@ "type": "timeseries" } ], - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" - } - ], "title": "Process info", "type": "row" }, { "collapsed": true, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, "gridPos": { "h": 1, "w": 24, @@ -1904,18 +1567,6 @@ "id": 56, "panels": [ { - "cards": { - "cardPadding": -1, - "cardRound": 0 - }, - "color": { - "cardColor": "#b4ff00", - "colorScale": "sqrt", - "colorScheme": "interpolateInferno", - "exponent": 0.5, - "mode": "spectrum" - }, - "dataFormat": "tsbuckets", "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -1940,14 +1591,7 @@ "x": 0, "y": 28 }, - "heatmap": {}, - "hideZeroBuckets": false, - "highlightCards": true, "id": 85, - "legend": { - "show": false - }, - "links": [], "options": { "calculate": false, "calculation": {}, @@ -1987,13 +1631,12 @@ } }, "pluginVersion": "9.2.2", - "reverseYBuckets": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "sum(rate(synapse_http_server_response_time_seconds_bucket{servlet='RoomSendEventRestServlet',instance=\"$instance\"}[$bucket_size])) by (le)", + "expr": "sum(rate(synapse_http_server_response_time_seconds_bucket{servlet='RoomSendEventRestServlet',server_name=\"$server_name\"}[$bucket_size])) by (le)", "format": "heatmap", "intervalFactor": 1, "legendFormat": "{{le}}", @@ -2001,81 +1644,36 @@ } ], "title": "Event Send Time (Including errors, across all workers)", - "tooltip": { - "show": true, - "showHistogram": true - }, - "type": "heatmap", - "xAxis": { - "show": true - }, - "yAxis": { - "format": "s", - "logBase": 2, - "show": true - }, - "yBucketBound": "auto" + "type": "heatmap" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, "description": "", - "editable": true, - "error": false, "fieldConfig": { "defaults": { "links": [] }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, - "grid": {}, "gridPos": { "h": 9, "w": 12, "x": 12, "y": 28 }, - "hiddenSeries": false, "id": 33, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "sum(rate(synapse_storage_events_persisted_events_total{instance=\"$instance\"}[$bucket_size])) without (job,index)", + "expr": "sum(rate(synapse_storage_events_persisted_events_total{server_name=\"$server_name\"}[$bucket_size])) without (job,index)", "format": "time_series", "interval": "", "intervalFactor": 2, @@ -2085,176 +1683,68 @@ "target": "" } ], - "thresholds": [], - "timeRegions": [], "title": "Events Persisted (all workers)", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:102", - "format": "hertz", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:103", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, - "decimals": 1, - "fill": 1, - "fillGradient": 0, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, "gridPos": { "h": 7, "w": 12, "x": 0, "y": 37 }, - "hiddenSeries": false, "id": 40, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_storage_events_persisted_by_source_type{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", + "expr": "rate(synapse_storage_events_persisted_events_sep_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", "format": "time_series", "intervalFactor": 2, - "legendFormat": "{{type}}", + "legendFormat": "{{origin_type}}", "refId": "D" } ], - "thresholds": [], - "timeRegions": [], "title": "Events/s Local vs Remote", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "hertz", - "label": "", - "logBase": 1, - "min": "0", - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, - "decimals": 1, - "fill": 1, - "fillGradient": 0, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, "gridPos": { "h": 7, "w": 12, "x": 12, "y": 37 }, - "hiddenSeries": false, "id": 46, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_storage_events_persisted_by_event_type{job=~\"$job\",index=~\"$index\",instance=\"$instance\"}[$bucket_size])", + "expr": "sum by(type) (rate(synapse_storage_events_persisted_events_sep_total{job=~\"$job\",index=~\"$index\",server_name=\"$server_name\"}[$bucket_size]))", "format": "time_series", "instant": false, "intervalFactor": 2, @@ -2263,185 +1753,36 @@ "step": 20 } ], - "thresholds": [], - "timeRegions": [], "title": "Events/s by Type", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "hertz", - "logBase": 1, - "min": "0", - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": { - "irc-freenode (local)": "#EAB839" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "decimals": 1, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 12, - "x": 0, - "y": 44 - }, - "hiddenSeries": false, - "id": 44, - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "uid": "${DS_PROMETHEUS}" - }, - "expr": "rate(synapse_storage_events_persisted_by_origin{job=~\"$job\",index=~\"$index\",instance=\"$instance\"}[$bucket_size])", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{origin_entity}} ({{origin_type}})", - "refId": "A", - "step": 20 - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Events/s by Origin", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "hertz", - "logBase": 1, - "min": "0", - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "decimals": 1, - "fill": 1, - "fillGradient": 0, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, "gridPos": { "h": 7, "w": 12, "x": 12, "y": 44 }, - "hiddenSeries": false, "id": 45, - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "sum(rate(synapse_storage_events_persisted_events_sep_total{job=~\"$job\",index=~\"$index\", type=\"m.room.member\",instance=\"$instance\", origin_type=\"local\"}[$bucket_size])) by (origin_type, origin_entity)", + "expr": "sum(rate(synapse_storage_events_persisted_events_sep_total{job=~\"$job\",index=~\"$index\", type=\"m.room.member\",server_name=\"$server_name\", origin_type=\"local\"}[$bucket_size])) by (origin_type, origin_entity)", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{origin_entity}} ({{origin_type}})", @@ -2450,44 +1791,10 @@ "step": 20 } ], - "thresholds": [], - "timeRegions": [], "title": "Memberships/s by Origin", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:232", - "format": "hertz", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:233", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" @@ -2498,49 +1805,17 @@ }, "overrides": [] }, - "fill": 0, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 0, "y": 51 }, - "hiddenSeries": false, "id": 118, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeatDirection": "h", - "seriesOverrides": [ - { - "$$hashKey": "object:316", - "alias": "mean", - "linewidth": 2 - } - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { @@ -2548,7 +1823,7 @@ "uid": "${DS_PROMETHEUS}" }, "exemplar": true, - "expr": "histogram_quantile(0.99, sum(rate(synapse_http_server_response_time_seconds_bucket{servlet='RoomSendEventRestServlet',instance=\"$instance\",code=~\"2..\",job=~\"$job\",index=~\"$index\"}[$bucket_size])) without (method))", + "expr": "histogram_quantile(0.99, sum(rate(synapse_http_server_response_time_seconds_bucket{servlet='RoomSendEventRestServlet',server_name=\"$server_name\",code=~\"2..\",job=~\"$job\",index=~\"$index\"}[$bucket_size])) without (method))", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -2560,7 +1835,7 @@ "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.95, sum(rate(synapse_http_server_response_time_seconds_bucket{servlet='RoomSendEventRestServlet',instance=\"$instance\",code=~\"2..\",job=~\"$job\",index=~\"$index\"}[$bucket_size])) without (method))", + "expr": "histogram_quantile(0.95, sum(rate(synapse_http_server_response_time_seconds_bucket{servlet='RoomSendEventRestServlet',server_name=\"$server_name\",code=~\"2..\",job=~\"$job\",index=~\"$index\"}[$bucket_size])) without (method))", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -2572,7 +1847,7 @@ "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.90, sum(rate(synapse_http_server_response_time_seconds_bucket{servlet='RoomSendEventRestServlet',instance=\"$instance\",code=~\"2..\",job=~\"$job\",index=~\"$index\"}[$bucket_size])) without (method))", + "expr": "histogram_quantile(0.90, sum(rate(synapse_http_server_response_time_seconds_bucket{servlet='RoomSendEventRestServlet',server_name=\"$server_name\",code=~\"2..\",job=~\"$job\",index=~\"$index\"}[$bucket_size])) without (method))", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{job}}-{{index}} 90%", @@ -2583,7 +1858,7 @@ "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.50, sum(rate(synapse_http_server_response_time_seconds_bucket{servlet='RoomSendEventRestServlet',instance=\"$instance\",code=~\"2..\",job=~\"$job\",index=~\"$index\"}[$bucket_size])) without (method))", + "expr": "histogram_quantile(0.50, sum(rate(synapse_http_server_response_time_seconds_bucket{servlet='RoomSendEventRestServlet',server_name=\"$server_name\",code=~\"2..\",job=~\"$job\",index=~\"$index\"}[$bucket_size])) without (method))", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{job}}-{{index}} 50%", @@ -2595,7 +1870,7 @@ "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "sum(rate(synapse_http_server_response_time_seconds_sum{servlet='RoomSendEventRestServlet',instance=\"$instance\",code=~\"2..\",job=~\"$job\",index=~\"$index\"}[$bucket_size])) without (method) / sum(rate(synapse_http_server_response_time_seconds_count{servlet='RoomSendEventRestServlet',instance=\"$instance\",code=~\"2..\",job=~\"$job\",index=~\"$index\"}[$bucket_size])) without (method)", + "expr": "sum(rate(synapse_http_server_response_time_seconds_sum{servlet='RoomSendEventRestServlet',server_name=\"$server_name\",code=~\"2..\",job=~\"$job\",index=~\"$index\"}[$bucket_size])) without (method) / sum(rate(synapse_http_server_response_time_seconds_count{servlet='RoomSendEventRestServlet',server_name=\"$server_name\",code=~\"2..\",job=~\"$job\",index=~\"$index\"}[$bucket_size])) without (method)", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{job}}-{{index}} mean", @@ -2603,37 +1878,8 @@ "refId": "E" } ], - "thresholds": [], - "timeRegions": [], "title": "Event send time quantiles by worker", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:263", - "format": "s", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:264", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { "datasource": { @@ -2719,7 +1965,7 @@ "uid": "${DS_PROMETHEUS}" }, "exemplar": false, - "expr": "sum(rate(synapse_state_res_db_for_biggest_room_seconds_total{instance=\"$instance\"}[1m]))", + "expr": "sum(rate(synapse_state_res_db_for_biggest_room_seconds_total{server_name=\"$server_name\"}[1m]))", "format": "time_series", "hide": false, "instant": false, @@ -2733,7 +1979,7 @@ "uid": "${DS_PROMETHEUS}" }, "exemplar": false, - "expr": "sum(rate(synapse_state_res_cpu_for_biggest_room_seconds_total{instance=\"$instance\"}[1m]))", + "expr": "sum(rate(synapse_state_res_cpu_for_biggest_room_seconds_total{server_name=\"$server_name\"}[1m]))", "format": "time_series", "hide": false, "instant": false, @@ -2746,24 +1992,11 @@ "type": "timeseries" } ], - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" - } - ], "title": "Event persistence", "type": "row" }, { "collapsed": true, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, "gridPos": { "h": 1, "w": 24, @@ -2773,68 +2006,33 @@ "id": 57, "panels": [ { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "editable": true, - "error": false, "fieldConfig": { "defaults": { "links": [] }, "overrides": [] }, - "fill": 2, - "fillGradient": 0, - "grid": {}, "gridPos": { "h": 8, "w": 12, "x": 0, "y": 29 }, - "hiddenSeries": false, "id": 4, - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "hideEmpty": false, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_http_server_requests_received_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", + "expr": "rate(synapse_http_server_requests_received_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", "format": "time_series", "interval": "", "intervalFactor": 2, @@ -2843,116 +2041,37 @@ "step": 20 } ], - "thresholds": [ - { - "$$hashKey": "object:234", - "colorMode": "custom", - "fill": true, - "fillColor": "rgba(216, 200, 27, 0.27)", - "op": "gt", - "value": 100, - "yaxis": "left" - }, - { - "$$hashKey": "object:235", - "colorMode": "custom", - "fill": true, - "fillColor": "rgba(234, 112, 112, 0.22)", - "op": "gt", - "value": 250, - "yaxis": "left" - } - ], - "timeRegions": [], "title": "Request Count by arrival time", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:206", - "format": "hertz", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:207", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "editable": true, - "error": false, "fieldConfig": { "defaults": { "links": [] }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, - "grid": {}, "gridPos": { "h": 8, "w": 12, "x": 12, "y": 29 }, - "hiddenSeries": false, "id": 32, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_http_server_requests_received_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\",method!=\"OPTIONS\"}[$bucket_size]) and topk(10,synapse_http_server_requests_received_total{instance=\"$instance\",job=~\"$job\",method!=\"OPTIONS\"})", + "expr": "rate(synapse_http_server_requests_received_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\",method!=\"OPTIONS\"}[$bucket_size]) and topk(10,synapse_http_server_requests_received_total{server_name=\"$server_name\",job=~\"$job\",method!=\"OPTIONS\"})", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{method}} {{servlet}} {{job}}-{{index}}", @@ -2961,101 +2080,37 @@ "target": "" } ], - "thresholds": [], - "timeRegions": [], "title": "Top 10 Request Counts", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:305", - "format": "hertz", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:306", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "editable": true, - "error": false, "fieldConfig": { "defaults": { "links": [] }, "overrides": [] }, - "fill": 2, - "fillGradient": 0, - "grid": {}, "gridPos": { "h": 8, "w": 12, "x": 0, "y": 37 }, - "hiddenSeries": false, "id": 139, - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "hideEmpty": false, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_http_server_in_flight_requests_ru_utime_seconds_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])+rate(synapse_http_server_in_flight_requests_ru_stime_seconds_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", + "expr": "rate(synapse_http_server_in_flight_requests_ru_utime_seconds_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])+rate(synapse_http_server_in_flight_requests_ru_stime_seconds_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -3064,120 +2119,37 @@ "step": 20 } ], - "thresholds": [ - { - "$$hashKey": "object:135", - "colorMode": "custom", - "fill": true, - "fillColor": "rgba(216, 200, 27, 0.27)", - "op": "gt", - "value": 100, - "yaxis": "left" - }, - { - "$$hashKey": "object:136", - "colorMode": "custom", - "fill": true, - "fillColor": "rgba(234, 112, 112, 0.22)", - "op": "gt", - "value": 250, - "yaxis": "left" - } - ], - "timeRegions": [], "title": "Total CPU Usage by Endpoint", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:107", - "format": "percentunit", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:108", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "editable": true, - "error": false, "fieldConfig": { "defaults": { "links": [] }, "overrides": [] }, - "fill": 0, - "fillGradient": 0, - "grid": {}, "gridPos": { "h": 8, "w": 12, "x": 12, "y": 37 }, - "hiddenSeries": false, "id": 52, - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "hideEmpty": false, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "(rate(synapse_http_server_in_flight_requests_ru_utime_seconds_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])+rate(synapse_http_server_in_flight_requests_ru_stime_seconds_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])) / rate(synapse_http_server_requests_received_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", + "expr": "(rate(synapse_http_server_in_flight_requests_ru_utime_seconds_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])+rate(synapse_http_server_in_flight_requests_ru_stime_seconds_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])) / rate(synapse_http_server_requests_received_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -3186,119 +2158,37 @@ "step": 20 } ], - "thresholds": [ - { - "$$hashKey": "object:417", - "colorMode": "custom", - "fill": true, - "fillColor": "rgba(216, 200, 27, 0.27)", - "op": "gt", - "value": 100, - "yaxis": "left" - }, - { - "$$hashKey": "object:418", - "colorMode": "custom", - "fill": true, - "fillColor": "rgba(234, 112, 112, 0.22)", - "op": "gt", - "value": 250, - "yaxis": "left" - } - ], - "timeRegions": [], "title": "Average CPU Usage by Endpoint", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:389", - "format": "s", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:390", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "editable": true, - "error": false, "fieldConfig": { "defaults": { "links": [] }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, - "grid": {}, "gridPos": { "h": 8, "w": 12, "x": 0, "y": 45 }, - "hiddenSeries": false, "id": 7, - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_http_server_in_flight_requests_db_txn_duration_seconds_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", + "expr": "rate(synapse_http_server_in_flight_requests_db_txn_duration_seconds_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -3307,100 +2197,36 @@ "step": 20 } ], - "thresholds": [], - "timeRegions": [], "title": "DB Usage by endpoint", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:488", - "format": "percentunit", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:489", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, - "editable": true, - "error": false, "fieldConfig": { "defaults": { "links": [] }, "overrides": [] }, - "fill": 2, - "fillGradient": 0, - "grid": {}, "gridPos": { "h": 8, "w": 12, "x": 12, "y": 45 }, - "hiddenSeries": false, "id": 47, - "legend": { - "alignAsTable": true, - "avg": true, - "current": false, - "hideEmpty": false, - "hideZero": true, - "max": true, - "min": false, - "rightSide": false, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "(sum(rate(synapse_http_server_response_time_seconds_sum{instance=\"$instance\",job=~\"$job\",index=~\"$index\",tag!=\"incremental_sync\"}[$bucket_size])) without (code))/(sum(rate(synapse_http_server_response_time_seconds_count{instance=\"$instance\",job=~\"$job\",index=~\"$index\",tag!=\"incremental_sync\"}[$bucket_size])) without (code))", + "expr": "(sum(rate(synapse_http_server_response_time_seconds_sum{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\",tag!=\"incremental_sync\"}[$bucket_size])) without (code))/(sum(rate(synapse_http_server_response_time_seconds_count{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\",tag!=\"incremental_sync\"}[$bucket_size])) without (code))", "format": "time_series", "hide": false, "interval": "", @@ -3410,41 +2236,10 @@ "step": 20 } ], - "thresholds": [], - "timeRegions": [], "title": "Non-sync avg response time", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "s", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": false - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -3454,54 +2249,23 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 0, "y": 53 }, - "hiddenSeries": false, "id": 103, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "alias": "Total", - "color": "rgb(255, 255, 255)", - "fill": 0, - "linewidth": 3 - } - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "topk(10,synapse_http_server_in_flight_requests_count{instance=\"$instance\",job=~\"$job\",index=~\"$index\"})", + "expr": "topk(10,synapse_http_server_in_flight_requests_count{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"})", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -3512,50 +2276,14 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "sum(avg_over_time(synapse_http_server_in_flight_requests_count{job=\"$job\",index=~\"$index\",instance=\"$instance\"}[$bucket_size]))", + "expr": "sum(avg_over_time(synapse_http_server_in_flight_requests_count{job=~\"$job\",index=~\"$index\",server_name=\"$server_name\"}[$bucket_size]))", "interval": "", "legendFormat": "Total", "refId": "B" } ], - "thresholds": [], - "timeRegions": [], "title": "Requests in flight", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - } - ], - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" + "type": "timeseries" } ], "title": "Requests", @@ -3563,10 +2291,6 @@ }, { "collapsed": true, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, "gridPos": { "h": 1, "w": 24, @@ -3576,10 +2300,6 @@ "id": 97, "panels": [ { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -3589,48 +2309,23 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 0, "y": 30 }, - "hiddenSeries": false, "id": 99, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_background_process_ru_utime_seconds_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])+rate(synapse_background_process_ru_stime_seconds_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", + "expr": "rate(synapse_background_process_ru_utime_seconds_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])+rate(synapse_background_process_ru_stime_seconds_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -3638,41 +2333,10 @@ "refId": "A" } ], - "thresholds": [], - "timeRegions": [], "title": "CPU usage by background jobs", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "percentunit", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -3682,48 +2346,23 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 12, "y": 30 }, - "hiddenSeries": false, "id": 101, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_background_process_db_txn_duration_seconds_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size]) + rate(synapse_background_process_db_sched_duration_seconds_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", + "expr": "rate(synapse_background_process_db_txn_duration_seconds_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size]) + rate(synapse_background_process_db_sched_duration_seconds_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", "format": "time_series", "hide": false, "intervalFactor": 1, @@ -3731,41 +2370,10 @@ "refId": "A" } ], - "thresholds": [], - "timeRegions": [], "title": "DB usage by background jobs (including scheduling time)", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "percentunit", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -3775,88 +2383,29 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 8, "w": 12, "x": 0, "y": 39 }, - "hiddenSeries": false, "id": 138, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "synapse_background_process_in_flight_count{job=~\"$job\",index=~\"$index\",instance=\"$instance\"}", + "expr": "synapse_background_process_in_flight_count{job=~\"$job\",index=~\"$index\",server_name=\"$server_name\"}", "legendFormat": "{{job}}-{{index}} {{name}}", "refId": "A" } ], - "thresholds": [], - "timeRegions": [], "title": "Background jobs in flight", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - } - ], - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" + "type": "timeseries" } ], "title": "Background jobs", @@ -3864,10 +2413,6 @@ }, { "collapsed": true, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, "gridPos": { "h": 1, "w": 24, @@ -3877,10 +2422,6 @@ "id": 81, "panels": [ { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -3890,48 +2431,23 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 0, "y": 31 }, - "hiddenSeries": false, "id": 79, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "sum(rate(synapse_federation_client_sent_transactions_total{instance=\"$instance\"}[$bucket_size]))", + "expr": "sum(rate(synapse_federation_client_sent_transactions_total{server_name=\"$server_name\"}[$bucket_size]))", "format": "time_series", "intervalFactor": 1, "legendFormat": "successful txn rate", @@ -3941,46 +2457,15 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "sum(rate(synapse_util_metrics_block_count_total{block_name=\"_send_new_transaction\",instance=\"$instance\"}[$bucket_size]) - ignoring (block_name) rate(synapse_federation_client_sent_transactions_total{instance=\"$instance\"}[$bucket_size]))", + "expr": "sum(rate(synapse_util_metrics_block_count_total{block_name=\"_send_new_transaction\",server_name=\"$server_name\"}[$bucket_size]) - ignoring (block_name) rate(synapse_federation_client_sent_transactions_total{server_name=\"$server_name\"}[$bucket_size]))", "legendFormat": "failed txn rate", "refId": "B" } ], - "thresholds": [], - "timeRegions": [], "title": "Outgoing federation transaction rate", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "hertz", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -3990,48 +2475,23 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 12, "y": 31 }, - "hiddenSeries": false, "id": 83, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "sum(rate(synapse_federation_server_received_pdus_total{instance=~\"$instance\"}[$bucket_size]))", + "expr": "sum(rate(synapse_federation_server_received_pdus_total{server_name=\"$server_name\"}[$bucket_size]))", "format": "time_series", "intervalFactor": 1, "legendFormat": "pdus", @@ -4041,48 +2501,17 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "sum(rate(synapse_federation_server_received_edus_total{instance=~\"$instance\"}[$bucket_size]))", + "expr": "sum(rate(synapse_federation_server_received_edus_total{server_name=\"$server_name\"}[$bucket_size]))", "format": "time_series", "intervalFactor": 1, "legendFormat": "edus", "refId": "B" } ], - "thresholds": [], - "timeRegions": [], "title": "Incoming PDU/EDU rate", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "hertz", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" @@ -4093,49 +2522,24 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 0, "y": 40 }, - "hiddenSeries": false, "id": 109, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "sum(rate(synapse_federation_client_sent_pdu_destinations_count_total{instance=\"$instance\"}[$bucket_size]))", + "expr": "sum(rate(synapse_federation_client_sent_pdu_destinations_count_total{server_name=\"$server_name\"}[$bucket_size]))", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -4147,48 +2551,17 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "sum(rate(synapse_federation_client_sent_edus_total{instance=\"$instance\"}[$bucket_size]))", + "expr": "sum(rate(synapse_federation_client_sent_edus_total{server_name=\"$server_name\"}[$bucket_size]))", "format": "time_series", "intervalFactor": 1, "legendFormat": "edus", "refId": "B" } ], - "thresholds": [], - "timeRegions": [], "title": "Outgoing PDU/EDU rate", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "hertz", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" @@ -4199,49 +2572,24 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 12, "y": 40 }, - "hiddenSeries": false, "id": 111, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "rate(synapse_federation_client_sent_edus_by_type_total{instance=\"$instance\"}[$bucket_size])", + "expr": "rate(synapse_federation_client_sent_edus_by_type_total{server_name=\"$server_name\"}[$bucket_size])", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -4250,37 +2598,8 @@ "refId": "A" } ], - "thresholds": [], - "timeRegions": [], "title": "Outgoing EDUs by type", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:462", - "format": "hertz", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:463", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { "datasource": { @@ -4359,7 +2678,7 @@ "id": "custom.hideFrom", "value": { "legend": false, - "tooltip": false, + "tooltip": true, "viz": true } } @@ -4481,7 +2800,7 @@ "id": "custom.hideFrom", "value": { "legend": false, - "tooltip": false, + "tooltip": true, "viz": true } } @@ -4527,10 +2846,6 @@ "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" @@ -4542,40 +2857,17 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 0, "y": 57 }, - "hiddenSeries": false, "id": 142, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { @@ -4583,7 +2875,7 @@ "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "synapse_federation_transaction_queue_pending_pdus{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}", + "expr": "synapse_federation_transaction_queue_pending_pdus{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}", "interval": "", "legendFormat": "pending PDUs {{job}}-{{index}}", "range": true, @@ -4594,52 +2886,16 @@ "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "expr": "synapse_federation_transaction_queue_pending_edus{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}", + "expr": "synapse_federation_transaction_queue_pending_edus{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}", "interval": "", "legendFormat": "pending EDUs {{job}}-{{index}}", "refId": "B" } ], - "thresholds": [], - "timeRegions": [], "title": "In-memory federation transmission queues", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:547", - "format": "short", - "label": "events", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:548", - "format": "short", - "label": "", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -4650,48 +2906,23 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 12, "y": 57 }, - "hiddenSeries": false, "id": 140, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "synapse_federation_send_queue_presence_changed_size{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}", + "expr": "synapse_federation_send_queue_presence_changed_size{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -4702,7 +2933,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "synapse_federation_send_queue_presence_map_size{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}", + "expr": "synapse_federation_send_queue_presence_map_size{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}", "format": "time_series", "hide": false, "interval": "", @@ -4714,7 +2945,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "synapse_federation_send_queue_presence_destinations_size{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}", + "expr": "synapse_federation_send_queue_presence_destinations_size{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}", "format": "time_series", "hide": false, "interval": "", @@ -4726,7 +2957,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "synapse_federation_send_queue_keyed_edu_size{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}", + "expr": "synapse_federation_send_queue_keyed_edu_size{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}", "format": "time_series", "hide": false, "interval": "", @@ -4738,7 +2969,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "synapse_federation_send_queue_edus_size{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}", + "expr": "synapse_federation_send_queue_edus_size{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}", "format": "time_series", "hide": false, "interval": "", @@ -4750,7 +2981,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "synapse_federation_send_queue_pos_time_size{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}", + "expr": "synapse_federation_send_queue_pos_time_size{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}", "format": "time_series", "hide": false, "interval": "", @@ -4759,50 +2990,10 @@ "refId": "F" } ], - "thresholds": [], - "timeRegions": [], "title": "Outgoing EDU queues on master", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "none", - "logBase": 1, - "min": "0", - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "cards": { - "cardPadding": -1 - }, - "color": { - "cardColor": "#b4ff00", - "colorScale": "sqrt", - "colorScheme": "interpolateInferno", - "exponent": 0.5, - "min": 0, - "mode": "spectrum" - }, - "dataFormat": "tsbuckets", "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -4827,14 +3018,7 @@ "x": 0, "y": 66 }, - "heatmap": {}, - "hideZeroBuckets": false, - "highlightCards": true, "id": 166, - "legend": { - "show": false - }, - "links": [], "options": { "calculate": false, "calculation": {}, @@ -4877,13 +3061,12 @@ } }, "pluginVersion": "9.2.2", - "reverseYBuckets": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "sum(rate(synapse_event_processing_lag_by_event_bucket{instance=\"$instance\",name=\"federation_sender\"}[$bucket_size])) by (le)", + "expr": "sum(rate(synapse_event_processing_lag_by_event_bucket{server_name=\"$server_name\",name=\"federation_sender\"}[$bucket_size])) by (le)", "format": "heatmap", "instant": false, "interval": "", @@ -4893,28 +3076,9 @@ } ], "title": "Federation send PDU lag", - "tooltip": { - "show": true, - "showHistogram": true - }, - "tooltipDecimals": 2, - "type": "heatmap", - "xAxis": { - "show": true - }, - "yAxis": { - "decimals": 0, - "format": "s", - "logBase": 1, - "show": true - }, - "yBucketBound": "auto" + "type": "heatmap" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -4924,90 +3088,23 @@ }, "overrides": [] }, - "fill": 0, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 12, "y": 66 }, - "hiddenSeries": false, "id": 162, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 0, - "links": [], - "nullPointMode": "connected", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "alias": "Avg", - "fill": 0, - "linewidth": 3 - }, - { - "alias": "99%", - "color": "#C4162A", - "fillBelowTo": "90%" - }, - { - "alias": "90%", - "color": "#FF7383", - "fillBelowTo": "75%" - }, - { - "alias": "75%", - "color": "#FFEE52", - "fillBelowTo": "50%" - }, - { - "alias": "50%", - "color": "#73BF69", - "fillBelowTo": "25%" - }, - { - "alias": "25%", - "color": "#1F60C4", - "fillBelowTo": "5%" - }, - { - "alias": "5%", - "lines": false - }, - { - "alias": "Average", - "color": "rgb(255, 255, 255)", - "lines": true, - "linewidth": 3 - } - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.99, sum(rate(synapse_event_processing_lag_by_event_bucket{name='federation_sender',index=~\"$index\",instance=\"$instance\"}[$bucket_size])) by (le))", + "expr": "histogram_quantile(0.99, sum(rate(synapse_event_processing_lag_by_event_bucket{name='federation_sender',index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])) by (le))", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -5018,7 +3115,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.9, sum(rate(synapse_event_processing_lag_by_event_bucket{name='federation_sender',index=~\"$index\",instance=\"$instance\"}[$bucket_size])) by (le))", + "expr": "histogram_quantile(0.9, sum(rate(synapse_event_processing_lag_by_event_bucket{name='federation_sender',index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])) by (le))", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -5029,7 +3126,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.75, sum(rate(synapse_event_processing_lag_by_event_bucket{name='federation_sender',index=~\"$index\",instance=\"$instance\"}[$bucket_size])) by (le))", + "expr": "histogram_quantile(0.75, sum(rate(synapse_event_processing_lag_by_event_bucket{name='federation_sender',index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])) by (le))", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -5040,7 +3137,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.5, sum(rate(synapse_event_processing_lag_by_event_bucket{name='federation_sender',index=~\"$index\",instance=\"$instance\"}[$bucket_size])) by (le))", + "expr": "histogram_quantile(0.5, sum(rate(synapse_event_processing_lag_by_event_bucket{name='federation_sender',index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])) by (le))", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -5051,7 +3148,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.25, sum(rate(synapse_event_processing_lag_by_event_bucket{name='federation_sender',index=~\"$index\",instance=\"$instance\"}[$bucket_size])) by (le))", + "expr": "histogram_quantile(0.25, sum(rate(synapse_event_processing_lag_by_event_bucket{name='federation_sender',index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])) by (le))", "interval": "", "legendFormat": "25%", "refId": "F" @@ -5060,7 +3157,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.05, sum(rate(synapse_event_processing_lag_by_event_bucket{name='federation_sender',index=~\"$index\",instance=\"$instance\"}[$bucket_size])) by (le))", + "expr": "histogram_quantile(0.05, sum(rate(synapse_event_processing_lag_by_event_bucket{name='federation_sender',index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])) by (le))", "interval": "", "legendFormat": "5%", "refId": "G" @@ -5069,76 +3166,16 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "sum(rate(synapse_event_processing_lag_by_event_sum{name='federation_sender',index=~\"$index\",instance=\"$instance\"}[$bucket_size])) / sum(rate(synapse_event_processing_lag_by_event_count{name='federation_sender',index=~\"$index\",instance=\"$instance\"}[$bucket_size]))", + "expr": "sum(rate(synapse_event_processing_lag_by_event_sum{name='federation_sender',index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])) / sum(rate(synapse_event_processing_lag_by_event_count{name='federation_sender',index=~\"$index\",server_name=\"$server_name\"}[$bucket_size]))", "interval": "", "legendFormat": "Average", "refId": "H" } ], - "thresholds": [ - { - "colorMode": "warning", - "fill": false, - "line": true, - "op": "gt", - "value": 0.25, - "yaxis": "left" - }, - { - "colorMode": "critical", - "fill": false, - "line": true, - "op": "gt", - "value": 1, - "yaxis": "left" - } - ], - "timeRegions": [], "title": "Federation send PDU lag quantiles", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "s", - "label": "", - "logBase": 1, - "min": "0", - "show": true - }, - { - "format": "hertz", - "label": "", - "logBase": 1, - "min": "0", - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "cards": { - "cardPadding": -1 - }, - "color": { - "cardColor": "#b4ff00", - "colorScale": "sqrt", - "colorScheme": "interpolateInferno", - "exponent": 0.5, - "min": 0, - "mode": "spectrum" - }, - "dataFormat": "tsbuckets", "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -5163,14 +3200,7 @@ "x": 0, "y": 75 }, - "heatmap": {}, - "hideZeroBuckets": false, - "highlightCards": true, "id": 164, - "legend": { - "show": false - }, - "links": [], "options": { "calculate": false, "calculation": {}, @@ -5213,13 +3243,12 @@ } }, "pluginVersion": "9.2.2", - "reverseYBuckets": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "sum(rate(synapse_federation_server_pdu_process_time_bucket{instance=\"$instance\"}[$bucket_size])) by (le)", + "expr": "sum(rate(synapse_federation_server_pdu_process_time_bucket{server_name=\"$server_name\"}[$bucket_size])) by (le)", "format": "heatmap", "instant": false, "interval": "", @@ -5229,84 +3258,37 @@ } ], "title": "Handle inbound PDU time", - "tooltip": { - "show": true, - "showHistogram": true - }, - "tooltipDecimals": 2, - "type": "heatmap", - "xAxis": { - "show": true - }, - "yAxis": { - "decimals": 0, - "format": "s", - "logBase": 1, - "show": true - }, - "yBucketBound": "auto" + "type": "heatmap" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "editable": true, - "error": false, "fieldConfig": { "defaults": { "links": [] }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, - "grid": {}, "gridPos": { "h": 9, "w": 12, "x": 12, "y": 75 }, - "hiddenSeries": false, "id": 203, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "synapse_federation_server_oldest_inbound_pdu_in_staging{job=~\"$job\",index=~\"$index\",instance=\"$instance\"}", + "expr": "synapse_federation_server_oldest_inbound_pdu_in_staging{job=~\"$job\",index=~\"$index\",server_name=\"$server_name\"}", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -5316,101 +3298,38 @@ "step": 4 } ], - "thresholds": [], - "timeRegions": [], "title": "Age of oldest event in staging area", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:92", - "format": "ms", - "logBase": 1, - "min": 0, - "show": true - }, - { - "$$hashKey": "object:93", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "editable": true, - "error": false, "fieldConfig": { "defaults": { "links": [] }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, - "grid": {}, "gridPos": { "h": 9, "w": 12, "x": 0, "y": 84 }, - "hiddenSeries": false, "id": 202, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "synapse_federation_server_number_inbound_pdu_in_staging{job=~\"$job\",index=~\"$index\",instance=\"$instance\"}", + "expr": "synapse_federation_server_number_inbound_pdu_in_staging{job=~\"$job\",index=~\"$index\",server_name=\"$server_name\"}", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -5420,135 +3339,43 @@ "step": 4 } ], - "thresholds": [], - "timeRegions": [], "title": "Number of events in federation staging area", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:92", - "format": "none", - "logBase": 1, - "min": 0, - "show": true - }, - { - "$$hashKey": "object:93", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "fill": 1, - "fillGradient": 0, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, "gridPos": { "h": 8, "w": 12, "x": 12, "y": 84 }, - "hiddenSeries": false, "id": 205, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "expr": "sum(rate(synapse_federation_soft_failed_events_total{instance=\"$instance\"}[$bucket_size]))", + "expr": "sum(rate(synapse_federation_soft_failed_events_total{server_name=\"$server_name\"}[$bucket_size]))", "interval": "", "legendFormat": "soft-failed events", "refId": "A" } ], - "thresholds": [], - "timeRegions": [], "title": "Soft-failed event rate", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:131", - "format": "hertz", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:132", - "format": "short", - "logBase": 1, - "show": false - } - ], - "yaxis": { - "align": false - } - } - ], - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" + "type": "timeseries" } ], "title": "Federation", @@ -5645,7 +3472,7 @@ "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "expr": "sum(increase(synapse_rate_limit_reject_total{instance=\"$instance\"}[$bucket_size]))", + "expr": "sum(increase(synapse_rate_limit_reject_total{server_name=\"$server_name\"}[$bucket_size]))", "refId": "A" } ], @@ -5733,7 +3560,7 @@ "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "expr": "sum(increase(synapse_rate_limit_sleep_total{instance=\"$instance\"}[$bucket_size]))", + "expr": "sum(increase(synapse_rate_limit_sleep_total{server_name=\"$server_name\"}[$bucket_size]))", "refId": "A" } ], @@ -5823,7 +3650,7 @@ "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "expr": "sum(increase(synapse_rate_limit_reject_affected_hosts{instance=\"$instance\"}[$bucket_size]))", + "expr": "sum(increase(synapse_rate_limit_reject_affected_hosts{server_name=\"$server_name\"}[$bucket_size]))", "refId": "A" } ], @@ -5913,7 +3740,7 @@ "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "expr": "sum(increase(synapse_rate_limit_sleep_affected_hosts{instance=\"$instance\"}[$bucket_size]))", + "expr": "sum(increase(synapse_rate_limit_sleep_affected_hosts{server_name=\"$server_name\"}[$bucket_size]))", "refId": "A" } ], @@ -5921,10 +3748,6 @@ "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" @@ -5936,106 +3759,24 @@ }, "overrides": [] }, - "fill": 0, - "fillGradient": 0, "gridPos": { "h": 8, "w": 12, "x": 0, "y": 170 }, - "hiddenSeries": false, "id": 229, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 0, - "links": [], - "nullPointMode": "connected", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "$$hashKey": "object:276", - "alias": "Avg", - "fill": 0, - "linewidth": 3 - }, - { - "$$hashKey": "object:277", - "alias": "99%", - "color": "#C4162A", - "fillBelowTo": "90%" - }, - { - "$$hashKey": "object:278", - "alias": "90%", - "color": "#FF7383", - "fillBelowTo": "75%" - }, - { - "$$hashKey": "object:279", - "alias": "75%", - "color": "#FFEE52", - "fillBelowTo": "50%" - }, - { - "$$hashKey": "object:280", - "alias": "50%", - "color": "#73BF69", - "fillBelowTo": "25%" - }, - { - "$$hashKey": "object:281", - "alias": "25%", - "color": "#1F60C4", - "fillBelowTo": "5%" - }, - { - "$$hashKey": "object:282", - "alias": "5%", - "lines": false - }, - { - "$$hashKey": "object:283", - "alias": "Average", - "color": "rgb(255, 255, 255)", - "lines": true, - "linewidth": 3 - }, - { - "$$hashKey": "object:284", - "alias": ">99%", - "color": "#B877D9", - "fill": 3, - "lines": true - } - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "histogram_quantile(0.9995, sum(rate(synapse_rate_limit_queue_wait_time_seconds_bucket{index=~\"$index\",instance=\"$instance\"}[$bucket_size])) by (le))", + "expr": "histogram_quantile(0.9995, sum(rate(synapse_rate_limit_queue_wait_time_seconds_bucket{index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])) by (le))", "format": "time_series", "hide": false, "intervalFactor": 1, @@ -6048,7 +3789,7 @@ "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "histogram_quantile(0.99, sum(rate(synapse_rate_limit_queue_wait_time_seconds_bucket{index=~\"$index\",instance=\"$instance\"}[$bucket_size])) by (le))", + "expr": "histogram_quantile(0.99, sum(rate(synapse_rate_limit_queue_wait_time_seconds_bucket{index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])) by (le))", "format": "time_series", "intervalFactor": 1, "legendFormat": "99%", @@ -6059,7 +3800,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.9, sum(rate(synapse_rate_limit_queue_wait_time_seconds_bucket{index=~\"$index\",instance=\"$instance\"}[$bucket_size])) by (le))", + "expr": "histogram_quantile(0.9, sum(rate(synapse_rate_limit_queue_wait_time_seconds_bucket{index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])) by (le))", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -6070,7 +3811,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.75, sum(rate(synapse_rate_limit_queue_wait_time_seconds_bucket{index=~\"$index\",instance=\"$instance\"}[$bucket_size])) by (le))", + "expr": "histogram_quantile(0.75, sum(rate(synapse_rate_limit_queue_wait_time_seconds_bucket{index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])) by (le))", "format": "time_series", "intervalFactor": 1, "legendFormat": "75%", @@ -6080,7 +3821,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.5, sum(rate(synapse_rate_limit_queue_wait_time_seconds_bucket{index=~\"$index\",instance=\"$instance\"}[$bucket_size])) by (le))", + "expr": "histogram_quantile(0.5, sum(rate(synapse_rate_limit_queue_wait_time_seconds_bucket{index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])) by (le))", "format": "time_series", "intervalFactor": 1, "legendFormat": "50%", @@ -6090,7 +3831,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.25, sum(rate(synapse_rate_limit_queue_wait_time_seconds_bucket{index=~\"$index\",instance=\"$instance\"}[$bucket_size])) by (le))", + "expr": "histogram_quantile(0.25, sum(rate(synapse_rate_limit_queue_wait_time_seconds_bucket{index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])) by (le))", "legendFormat": "25%", "refId": "F" }, @@ -6098,7 +3839,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.05, sum(rate(synapse_rate_limit_queue_wait_time_seconds_bucket{index=~\"$index\",instance=\"$instance\"}[$bucket_size])) by (le))", + "expr": "histogram_quantile(0.05, sum(rate(synapse_rate_limit_queue_wait_time_seconds_bucket{index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])) by (le))", "legendFormat": "5%", "refId": "G" }, @@ -6106,65 +3847,13 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "sum(rate(synapse_rate_limit_queue_wait_time_seconds_sum{index=~\"$index\",instance=\"$instance\"}[$bucket_size])) / sum(rate(synapse_rate_limit_queue_wait_time_seconds_count{index=~\"$index\",instance=\"$instance\"}[$bucket_size]))", + "expr": "sum(rate(synapse_rate_limit_queue_wait_time_seconds_sum{index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])) / sum(rate(synapse_rate_limit_queue_wait_time_seconds_count{index=~\"$index\",server_name=\"$server_name\"}[$bucket_size]))", "legendFormat": "Average", "refId": "H" } ], - "thresholds": [ - { - "$$hashKey": "object:283", - "colorMode": "warning", - "fill": false, - "line": true, - "op": "gt", - "value": 1, - "yaxis": "left" - }, - { - "$$hashKey": "object:284", - "colorMode": "critical", - "fill": false, - "line": true, - "op": "gt", - "value": 2, - "yaxis": "left" - } - ], - "timeRegions": [], "title": "Rate limit queue wait time Quantiles (all workers)", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:255", - "format": "s", - "label": "", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:256", - "format": "hertz", - "label": "", - "logBase": 1, - "min": "0", - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { "datasource": { @@ -6264,7 +3953,7 @@ "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "expr": "sum(rate(synapse_rate_limit_sleep_total{instance=\"$instance\"}[$bucket_size]))", + "expr": "sum(rate(synapse_rate_limit_sleep_total{server_name=\"$server_name\"}[$bucket_size]))", "refId": "A" }, { @@ -6289,10 +3978,6 @@ }, { "collapsed": true, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, "gridPos": { "h": 1, "w": 24, @@ -6366,7 +4051,6 @@ "y": 155 }, "id": 51, - "links": [], "options": { "legend": { "calcs": [], @@ -6386,7 +4070,7 @@ "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "rate(synapse_http_httppusher_http_pushes_processed_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size]) and on (instance, job, index) (synapse_http_httppusher_http_pushes_failed_total + synapse_http_httppusher_http_pushes_processed_total) > 0", + "expr": "rate(synapse_http_httppusher_http_pushes_processed_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size]) and on (instance, job, index) (synapse_http_httppusher_http_pushes_failed_total + synapse_http_httppusher_http_pushes_processed_total) > 0", "format": "time_series", "interval": "", "intervalFactor": 2, @@ -6400,7 +4084,7 @@ "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "rate(synapse_http_httppusher_http_pushes_failed_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size]) and on (instance, job, index) (synapse_http_httppusher_http_pushes_failed_total + synapse_http_httppusher_http_pushes_processed_total) > 0", + "expr": "rate(synapse_http_httppusher_http_pushes_failed_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size]) and on (instance, job, index) (synapse_http_httppusher_http_pushes_failed_total + synapse_http_httppusher_http_pushes_processed_total) > 0", "format": "time_series", "intervalFactor": 2, "legendFormat": "failed {{job}}-{{index}}", @@ -6413,10 +4097,6 @@ "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -6427,89 +4107,29 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 8, "w": 12, "x": 12, "y": 155 }, - "hiddenSeries": false, "id": 134, - "legend": { - "avg": false, - "current": false, - "hideZero": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "topk(10,synapse_pushers{job=~\"$job\",index=~\"$index\", instance=\"$instance\"})", + "expr": "topk(10,synapse_pushers{job=~\"$job\",index=~\"$index\", server_name=\"$server_name\"})", "legendFormat": "{{kind}} {{app_id}}", "refId": "A" } ], - "thresholds": [], - "timeRegions": [], "title": "Active pusher instances by app", - "tooltip": { - "shared": false, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - } - ], - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" + "type": "timeseries" } ], "title": "Pushes", @@ -6517,10 +4137,6 @@ }, { "collapsed": true, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, "gridPos": { "h": 1, "w": 24, @@ -6530,10 +4146,6 @@ "id": 219, "panels": [ { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" @@ -6545,42 +4157,17 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 7, "w": 12, "x": 0, "y": 33 }, - "hiddenSeries": false, "id": 209, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "8.4.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { @@ -6588,7 +4175,7 @@ "uid": "${DS_PROMETHEUS}" }, "exemplar": true, - "expr": "sum(rate(synapse_push_bulk_push_rule_evaluator_push_rules_state_size_counter_total{job=\"$job\",index=~\"$index\",instance=\"$instance\"}[$bucket_size]))", + "expr": "sum(rate(synapse_push_bulk_push_rule_evaluator_push_rules_state_size_counter_total{job=~\"$job\",index=~\"$index\",server_name=\"$server_name\"}[$bucket_size]))", "format": "time_series", "interval": "", "intervalFactor": 2, @@ -6598,43 +4185,10 @@ "step": 2 } ], - "thresholds": [], - "timeRegions": [], "title": "Iterations over State", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "hertz", - "label": "", - "logBase": 1, - "min": "0", - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" @@ -6646,42 +4200,17 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 7, "w": 12, "x": 12, "y": 33 }, - "hiddenSeries": false, "id": 211, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "8.4.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { @@ -6689,7 +4218,7 @@ "uid": "${DS_PROMETHEUS}" }, "exemplar": true, - "expr": "sum(rate(synapse_push_bulk_push_rule_evaluator_push_rules_invalidation_counter_total{job=\"$job\",index=~\"$index\",instance=\"$instance\"}[$bucket_size]))", + "expr": "sum(rate(synapse_push_bulk_push_rule_evaluator_push_rules_invalidation_counter_total{job=~\"$job\",index=~\"$index\",server_name=\"$server_name\"}[$bucket_size]))", "format": "time_series", "interval": "", "intervalFactor": 2, @@ -6699,43 +4228,10 @@ "step": 2 } ], - "thresholds": [], - "timeRegions": [], "title": "Push Rule Invalidations", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "hertz", - "label": "", - "logBase": 1, - "min": "0", - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" @@ -6747,47 +4243,17 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 7, "w": 12, "x": 0, "y": 40 }, - "hiddenSeries": false, "id": 213, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "8.4.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "alias": "Number of calls", - "yaxis": 2 - } - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { @@ -6795,7 +4261,7 @@ "uid": "${DS_PROMETHEUS}" }, "exemplar": true, - "expr": "sum(rate(synapse_util_caches_cache_hits{job=\"$job\",index=~\"$index\",name=\"push_rules_delta_state_cache_metric\",instance=\"$instance\"}[$bucket_size]))/sum(rate(synapse_util_caches_cache{job=\"$job\",index=~\"$index\", name=\"push_rules_delta_state_cache_metric\",instance=\"$instance\"}[$bucket_size]))", + "expr": "sum(rate(synapse_util_caches_cache_hits{job=~\"$job\",index=~\"$index\",name=\"push_rules_delta_state_cache_metric\",server_name=\"$server_name\"}[$bucket_size]))/sum(rate(synapse_util_caches_cache{job=~\"$job\",index=~\"$index\", name=\"push_rules_delta_state_cache_metric\",server_name=\"$server_name\"}[$bucket_size]))", "format": "time_series", "interval": "", "intervalFactor": 2, @@ -6810,7 +4276,7 @@ "uid": "${DS_PROMETHEUS}" }, "exemplar": true, - "expr": "sum(rate(synapse_util_caches_cache{job=\"$job\",index=~\"$index\", name=\"push_rules_delta_state_cache_metric\",instance=\"$instance\"}[$bucket_size]))", + "expr": "sum(rate(synapse_util_caches_cache{job=~\"$job\",index=~\"$index\", name=\"push_rules_delta_state_cache_metric\",server_name=\"$server_name\"}[$bucket_size]))", "format": "time_series", "interval": "", "intervalFactor": 2, @@ -6819,46 +4285,10 @@ "step": 2 } ], - "thresholds": [], - "timeRegions": [], "title": "Delta Optimisation", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "percentunit", - "label": "", - "logBase": 1, - "max": "1", - "min": "0", - "show": true - }, - { - "format": "hertz", - "label": "", - "logBase": 1, - "min": "0", - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" @@ -6870,47 +4300,17 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 7, "w": 12, "x": 12, "y": 40 }, - "hiddenSeries": false, "id": 215, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "8.4.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "alias": "Number of calls", - "yaxis": 2 - } - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { @@ -6918,7 +4318,7 @@ "uid": "${DS_PROMETHEUS}" }, "exemplar": true, - "expr": "sum(rate(synapse_util_caches_cache_hits{job=\"$job\",index=~\"$index\",name=\"room_push_rule_cache\",instance=\"$instance\"}[$bucket_size]))/sum(rate(synapse_util_caches_cache{job=\"$job\",index=~\"$index\", name=\"room_push_rule_cache\",instance=\"$instance\"}[$bucket_size]))", + "expr": "sum(rate(synapse_util_caches_cache_hits{job=~\"$job\",index=~\"$index\",name=\"room_push_rule_cache\",server_name=\"$server_name\"}[$bucket_size]))/sum(rate(synapse_util_caches_cache{job=~\"$job\",index=~\"$index\", name=\"room_push_rule_cache\",server_name=\"$server_name\"}[$bucket_size]))", "format": "time_series", "interval": "", "intervalFactor": 2, @@ -6933,7 +4333,7 @@ "uid": "${DS_PROMETHEUS}" }, "exemplar": true, - "expr": "sum(rate(synapse_util_caches_cache{job=\"$job\",index=~\"$index\", name=\"room_push_rule_cache\",instance=\"$instance\"}[$bucket_size]))", + "expr": "sum(rate(synapse_util_caches_cache{job=~\"$job\",index=~\"$index\", name=\"room_push_rule_cache\",server_name=\"$server_name\"}[$bucket_size]))", "format": "time_series", "interval": "", "intervalFactor": 2, @@ -6942,44 +4342,10 @@ "step": 2 } ], - "thresholds": [], - "timeRegions": [], "title": "How often we reuse existing calculated push rules", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "percentunit", - "label": "", - "logBase": 1, - "max": "1", - "min": "0", - "show": true - }, - { - "format": "hertz", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" @@ -6991,47 +4357,17 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 7, "w": 12, "x": 0, "y": 47 }, - "hiddenSeries": false, "id": 217, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "8.4.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "alias": "Number of calls", - "yaxis": 2 - } - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { @@ -7039,7 +4375,7 @@ "uid": "${DS_PROMETHEUS}" }, "exemplar": true, - "expr": "sum(rate(synapse_util_caches_cache_hits{job=\"$job\",index=~\"$index\",name=\"_get_rules_for_room\",instance=\"$instance\"}[$bucket_size]))/sum(rate(synapse_util_caches_cache{job=\"$job\",index=~\"$index\", name=\"_get_rules_for_room\",instance=\"$instance\"}[$bucket_size]))", + "expr": "sum(rate(synapse_util_caches_cache_hits{job=~\"$job\",index=~\"$index\",name=\"_get_rules_for_room\",server_name=\"$server_name\"}[$bucket_size]))/sum(rate(synapse_util_caches_cache{job=~\"$job\",index=~\"$index\", name=\"_get_rules_for_room\",server_name=\"$server_name\"}[$bucket_size]))", "format": "time_series", "interval": "", "intervalFactor": 2, @@ -7054,7 +4390,7 @@ "uid": "${DS_PROMETHEUS}" }, "exemplar": true, - "expr": "sum(rate(synapse_util_caches_cache{job=\"$job\",index=~\"$index\", name=\"_get_rules_for_room\",instance=\"$instance\"}[$bucket_size]))", + "expr": "sum(rate(synapse_util_caches_cache{job=~\"$job\",index=~\"$index\", name=\"_get_rules_for_room\",server_name=\"$server_name\"}[$bucket_size]))", "format": "time_series", "interval": "", "intervalFactor": 2, @@ -7063,47 +4399,8 @@ "step": 2 } ], - "thresholds": [], - "timeRegions": [], "title": "How often we have the RulesForRoom cached", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "percentunit", - "label": "", - "logBase": 1, - "max": "1", - "min": "0", - "show": true - }, - { - "format": "hertz", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - } - ], - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" + "type": "timeseries" } ], "title": "Push Rule Cache", @@ -7111,10 +4408,6 @@ }, { "collapsed": true, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, "gridPos": { "h": 1, "w": 24, @@ -7186,7 +4479,6 @@ "y": 35 }, "id": 48, - "links": [], "options": { "legend": { "calcs": [], @@ -7205,7 +4497,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_storage_schedule_time_sum{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])/rate(synapse_storage_schedule_time_count[$bucket_size])", + "expr": "rate(synapse_storage_schedule_time_sum{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])/rate(synapse_storage_schedule_time_count[$bucket_size])", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{job}}-{{index}}", @@ -7217,10 +4509,6 @@ "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -7231,49 +4519,23 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 7, "w": 12, "x": 12, "y": 35 }, - "hiddenSeries": false, "id": 104, - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.0.4", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.99, rate(synapse_storage_schedule_time_bucket{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size]))", + "expr": "histogram_quantile(0.99, rate(synapse_storage_schedule_time_bucket{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size]))", "format": "time_series", "hide": false, "intervalFactor": 1, @@ -7285,7 +4547,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.95, rate(synapse_storage_schedule_time_bucket{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size]))", + "expr": "histogram_quantile(0.95, rate(synapse_storage_schedule_time_bucket{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size]))", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{job}} {{index}} 95%", @@ -7295,7 +4557,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.90, rate(synapse_storage_schedule_time_bucket{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size]))", + "expr": "histogram_quantile(0.90, rate(synapse_storage_schedule_time_bucket{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size]))", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{job}} {{index}} 90%", @@ -7305,7 +4567,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_storage_schedule_time_sum{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])/rate(synapse_storage_schedule_time_count{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", + "expr": "rate(synapse_storage_schedule_time_sum{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])/rate(synapse_storage_schedule_time_count{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -7313,99 +4575,36 @@ "refId": "D" } ], - "thresholds": [], - "timeRegions": [], "title": "Db scheduling time quantiles", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "s", - "label": "", - "logBase": 1, - "min": "0", - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": false - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, - "editable": true, - "error": false, "fieldConfig": { "defaults": { "links": [] }, "overrides": [] }, - "fill": 0, - "fillGradient": 0, - "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 0, "y": 42 }, - "hiddenSeries": false, "id": 10, - "legend": { - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.0.4", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "topk(10, rate(synapse_storage_transaction_time_count_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size]))", + "expr": "topk(10, rate(synapse_storage_transaction_time_count_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size]))", "format": "time_series", "interval": "", "intervalFactor": 2, @@ -7414,98 +4613,36 @@ "step": 20 } ], - "thresholds": [], - "timeRegions": [], "title": "Top DB transactions by txn rate", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "hertz", - "logBase": 1, - "min": 0, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, - "editable": true, - "error": false, "fieldConfig": { "defaults": { "links": [] }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, - "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 12, "y": 42 }, - "hiddenSeries": false, "id": 11, - "legend": { - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.0.4", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_storage_transaction_time_sum_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", + "expr": "rate(synapse_storage_transaction_time_sum_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", "format": "time_series", "instant": false, "interval": "", @@ -7515,97 +4652,36 @@ "step": 20 } ], - "thresholds": [], - "timeRegions": [], "title": "DB transactions by total txn time", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "percentunit", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, - "editable": true, - "error": false, "fieldConfig": { "defaults": { "links": [] }, "overrides": [] }, - "fill": 0, - "fillGradient": 0, - "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 0, "y": 49 }, - "hiddenSeries": false, "id": 180, - "legend": { - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": false }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.0.4", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_storage_transaction_time_sum_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])/rate(synapse_storage_transaction_time_count_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", + "expr": "rate(synapse_storage_transaction_time_sum_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])/rate(synapse_storage_transaction_time_count_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", "format": "time_series", "instant": false, "interval": "", @@ -7615,41 +4691,10 @@ "step": 20 } ], - "thresholds": [], - "timeRegions": [], "title": "Average DB txn time", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "s", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -7659,47 +4704,23 @@ }, "overrides": [] }, - "fill": 6, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 12, "y": 49 }, - "hiddenSeries": false, "id": 200, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.0.4", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.99, sum(rate(synapse_storage_schedule_time_bucket{index=~\"$index\",instance=\"$instance\",job=\"$job\"}[$bucket_size])) by (le))", + "expr": "histogram_quantile(0.99, sum(rate(synapse_storage_schedule_time_bucket{index=~\"$index\",server_name=\"$server_name\",job=~\"$job\"}[$bucket_size])) by (le))", "format": "time_series", "intervalFactor": 1, "legendFormat": "99%", @@ -7709,7 +4730,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.9, sum(rate(synapse_storage_schedule_time_bucket{index=~\"$index\",instance=\"$instance\",job=\"$job\"}[$bucket_size])) by (le))", + "expr": "histogram_quantile(0.9, sum(rate(synapse_storage_schedule_time_bucket{index=~\"$index\",server_name=\"$server_name\",job=~\"$job\"}[$bucket_size])) by (le))", "format": "time_series", "intervalFactor": 1, "legendFormat": "90%", @@ -7719,7 +4740,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.75, sum(rate(synapse_storage_schedule_time_bucket{index=~\"$index\",instance=\"$instance\",job=\"$job\"}[$bucket_size])) by (le))", + "expr": "histogram_quantile(0.75, sum(rate(synapse_storage_schedule_time_bucket{index=~\"$index\",server_name=\"$server_name\",job=~\"$job\"}[$bucket_size])) by (le))", "format": "time_series", "intervalFactor": 1, "legendFormat": "75%", @@ -7729,55 +4750,15 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.5, sum(rate(synapse_storage_schedule_time_bucket{index=~\"$index\",instance=\"$instance\",job=\"$job\"}[$bucket_size])) by (le))", + "expr": "histogram_quantile(0.5, sum(rate(synapse_storage_schedule_time_bucket{index=~\"$index\",server_name=\"$server_name\",job=~\"$job\"}[$bucket_size])) by (le))", "format": "time_series", "intervalFactor": 1, "legendFormat": "50%", "refId": "B" } ], - "thresholds": [], - "timeRegions": [], "title": "Time waiting for DB connection quantiles", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:203", - "format": "s", - "label": "", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:204", - "format": "short", - "logBase": 1, - "show": false - } - ], - "yaxis": { - "align": false - } - } - ], - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" + "type": "timeseries" } ], "title": "Database", @@ -7785,10 +4766,6 @@ }, { "collapsed": true, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, "gridPos": { "h": 1, "w": 24, @@ -7798,65 +4775,32 @@ "id": 59, "panels": [ { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, - "editable": true, - "error": false, "fieldConfig": { "defaults": { "links": [] }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, - "grid": {}, "gridPos": { "h": 13, "w": 12, "x": 0, "y": 158 }, - "hiddenSeries": false, "id": 12, - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_util_metrics_block_ru_utime_seconds_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\",block_name!=\"wrapped_request_handler\"}[$bucket_size]) + rate(synapse_util_metrics_block_ru_stime_seconds_total[$bucket_size])", + "expr": "rate(synapse_util_metrics_block_ru_utime_seconds_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\",block_name!=\"wrapped_request_handler\"}[$bucket_size]) + rate(synapse_util_metrics_block_ru_stime_seconds_total[$bucket_size])", "format": "time_series", "interval": "", "intervalFactor": 2, @@ -7865,96 +4809,36 @@ "step": 20 } ], - "thresholds": [], - "timeRegions": [], "title": "Total CPU Usage by Block", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "percentunit", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, - "editable": true, - "error": false, "fieldConfig": { "defaults": { "links": [] }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, - "grid": {}, "gridPos": { "h": 13, "w": 12, "x": 12, "y": 158 }, - "hiddenSeries": false, "id": 26, - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "(rate(synapse_util_metrics_block_ru_utime_seconds_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size]) + rate(synapse_util_metrics_block_ru_stime_seconds_total[$bucket_size])) / rate(synapse_util_metrics_block_count_total[$bucket_size])", + "expr": "(rate(synapse_util_metrics_block_ru_utime_seconds_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size]) + rate(synapse_util_metrics_block_ru_stime_seconds_total[$bucket_size])) / rate(synapse_util_metrics_block_count_total[$bucket_size])", "format": "time_series", "interval": "", "intervalFactor": 2, @@ -7963,91 +4847,31 @@ "step": 20 } ], - "thresholds": [], - "timeRegions": [], "title": "Average CPU Time per Block", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "ms", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "editable": true, - "error": false, "fieldConfig": { "defaults": { "links": [] }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, - "grid": {}, "gridPos": { "h": 13, "w": 12, "x": 0, "y": 171 }, - "hiddenSeries": false, "id": 13, - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { @@ -8055,7 +4879,7 @@ "uid": "${DS_PROMETHEUS}" }, "exemplar": true, - "expr": "rate(synapse_util_metrics_block_db_txn_duration_seconds_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", + "expr": "rate(synapse_util_metrics_block_db_txn_duration_seconds_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", "format": "time_series", "interval": "", "intervalFactor": 2, @@ -8064,100 +4888,37 @@ "step": 20 } ], - "thresholds": [], - "timeRegions": [], "title": "Total DB Usage by Block", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:196", - "format": "percentunit", - "logBase": 1, - "min": 0, - "show": true - }, - { - "$$hashKey": "object:197", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, "description": "The time each database transaction takes to execute, on average, broken down by metrics block.", - "editable": true, - "error": false, "fieldConfig": { "defaults": { "links": [] }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, - "grid": {}, "gridPos": { "h": 13, "w": 12, "x": 12, "y": 171 }, - "hiddenSeries": false, "id": 27, - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_util_metrics_block_db_txn_duration_seconds_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size]) / rate(synapse_util_metrics_block_db_txn_count_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", + "expr": "rate(synapse_util_metrics_block_db_txn_duration_seconds_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size]) / rate(synapse_util_metrics_block_db_txn_count_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", "format": "time_series", "interval": "", "intervalFactor": 2, @@ -8166,95 +4927,36 @@ "step": 20 } ], - "thresholds": [], - "timeRegions": [], "title": "Average Database Transaction time, by Block", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "ms", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, - "editable": true, - "error": false, "fieldConfig": { "defaults": { "links": [] }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, - "grid": {}, "gridPos": { "h": 13, "w": 12, "x": 0, "y": 184 }, - "hiddenSeries": false, "id": 28, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_util_metrics_block_db_txn_duration_seconds_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size]) / rate(synapse_util_metrics_block_db_txn_count_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", + "expr": "rate(synapse_util_metrics_block_db_txn_duration_seconds_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size]) / rate(synapse_util_metrics_block_db_txn_count_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", "format": "time_series", "interval": "", "intervalFactor": 2, @@ -8263,95 +4965,36 @@ "step": 20 } ], - "thresholds": [], - "timeRegions": [], "title": "Average Transactions per Block", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "none", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, - "editable": true, - "error": false, "fieldConfig": { "defaults": { "links": [] }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, - "grid": {}, "gridPos": { "h": 13, "w": 12, "x": 12, "y": 184 }, - "hiddenSeries": false, "id": 25, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": false, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_util_metrics_block_time_seconds_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size]) / rate(synapse_util_metrics_block_count_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", + "expr": "rate(synapse_util_metrics_block_time_seconds_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size]) / rate(synapse_util_metrics_block_count_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", "format": "time_series", "interval": "", "intervalFactor": 2, @@ -8360,130 +5003,41 @@ "step": 20 } ], - "thresholds": [], - "timeRegions": [], "title": "Average Wallclock Time per Block", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:180", - "format": "s", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:181", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, - "fill": 1, - "fillGradient": 0, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, "gridPos": { "h": 15, "w": 12, "x": 0, "y": 197 }, - "hiddenSeries": false, "id": 154, - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_util_metrics_block_count_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", + "expr": "rate(synapse_util_metrics_block_count_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", "interval": "", "legendFormat": "{{job}}-{{index}} {{block_name}}", "refId": "A" } ], - "thresholds": [], - "timeRegions": [], "title": "Block count", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "hertz", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - } - ], - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" + "type": "timeseries" } ], "title": "Per-block metrics", @@ -8491,10 +5045,6 @@ }, { "collapsed": true, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, "gridPos": { "h": 1, "w": 24, @@ -8504,67 +5054,32 @@ "id": 61, "panels": [ { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, - "decimals": 2, - "editable": true, - "error": false, "fieldConfig": { "defaults": { "links": [] }, "overrides": [] }, - "fill": 0, - "fillGradient": 0, - "grid": {}, "gridPos": { "h": 10, "w": 12, "x": 0, "y": 36 }, - "hiddenSeries": false, "id": 1, - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.0.4", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_util_caches_cache_hits{job=~\"$job\",index=~\"$index\",instance=\"$instance\"}[$bucket_size])/rate(synapse_util_caches_cache{job=~\"$job\",index=~\"$index\",instance=\"$instance\"}[$bucket_size])", + "expr": "rate(synapse_util_caches_cache_hits{job=~\"$job\",index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])/rate(synapse_util_caches_cache{job=~\"$job\",index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{name}} {{job}}-{{index}}", @@ -8572,100 +5087,36 @@ "step": 20 } ], - "thresholds": [], - "timeRegions": [], "title": "Cache Hit Ratio", - "tooltip": { - "msResolution": true, - "shared": false, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "percentunit", - "label": "", - "logBase": 1, - "max": "1", - "min": 0, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": false - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, - "editable": true, - "error": false, "fieldConfig": { "defaults": { "links": [] }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, - "grid": {}, "gridPos": { "h": 10, "w": 12, "x": 12, "y": 36 }, - "hiddenSeries": false, "id": 8, - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "hideZero": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.0.4", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "synapse_util_caches_cache_size{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}", + "expr": "synapse_util_caches_cache_size{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}", "format": "time_series", "hide": false, "interval": "", @@ -8675,97 +5126,36 @@ "step": 20 } ], - "thresholds": [], - "timeRegions": [], "title": "Cache Size", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "logBase": 1, - "min": 0, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, - "editable": true, - "error": false, "fieldConfig": { "defaults": { "links": [] }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, - "grid": {}, "gridPos": { "h": 10, "w": 12, "x": 0, "y": 46 }, - "hiddenSeries": false, "id": 38, - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "hideZero": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "connected", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.0.4", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_util_caches_cache{job=~\"$job\",index=~\"$index\",instance=\"$instance\"}[$bucket_size])", + "expr": "rate(synapse_util_caches_cache{job=~\"$job\",index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])", "format": "time_series", "interval": "", "intervalFactor": 2, @@ -8774,42 +5164,10 @@ "step": 20 } ], - "thresholds": [], - "timeRegions": [], "title": "Cache request rate", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "rps", - "logBase": 1, - "min": 0, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -8819,53 +5177,23 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 10, "w": 12, "x": 12, "y": 46 }, - "hiddenSeries": false, "id": 39, - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "hideEmpty": false, - "hideZero": false, - "max": true, - "min": false, - "rightSide": false, - "show": true, - "sort": "max", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.0.4", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "topk(10, rate(synapse_util_caches_cache{job=~\"$job\",index=~\"$index\",instance=\"$instance\"}[$bucket_size]) - rate(synapse_util_caches_cache_hits{job=~\"$job\",index=~\"$index\",instance=\"$instance\"}[$bucket_size]))", + "expr": "topk(10, rate(synapse_util_caches_cache{job=~\"$job\",index=~\"$index\",server_name=\"$server_name\"}[$bucket_size]) - rate(synapse_util_caches_cache_hits{job=~\"$job\",index=~\"$index\",server_name=\"$server_name\"}[$bucket_size]))", "format": "time_series", "interval": "", "intervalFactor": 2, @@ -8874,43 +5202,10 @@ "step": 20 } ], - "thresholds": [], - "timeRegions": [], "title": "Top 10 cache misses", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:101", - "format": "rps", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:102", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -8920,48 +5215,23 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 0, "y": 56 }, - "hiddenSeries": false, "id": 65, - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.0.4", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_util_caches_cache_evicted_size{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", + "expr": "rate(synapse_util_caches_cache_evicted_size{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -8969,45 +5239,8 @@ "refId": "A" } ], - "thresholds": [], - "timeRegions": [], "title": "Cache eviction rate", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "hertz", - "label": "entries / second", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - } - ], - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" + "type": "timeseries" } ], "title": "Caches", @@ -9015,10 +5248,6 @@ }, { "collapsed": true, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, "gridPos": { "h": 1, "w": 24, @@ -9028,10 +5257,6 @@ "id": 148, "panels": [ { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -9042,86 +5267,32 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 8, "w": 12, "x": 0, "y": 29 }, - "hiddenSeries": false, "id": 146, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "7.3.7", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "synapse_util_caches_response_cache_size{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}", + "expr": "synapse_util_caches_response_cache_size{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}", "interval": "", "legendFormat": "{{name}} {{job}}-{{index}}", "refId": "A" } ], - "thresholds": [], - "timeRegions": [], "title": "Response cache size", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -9132,46 +5303,23 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 8, "w": 12, "x": 12, "y": 29 }, - "hiddenSeries": false, "id": 150, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "7.3.7", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_util_caches_response_cache_hits{instance=\"$instance\", job=~\"$job\", index=~\"$index\"}[$bucket_size])/rate(synapse_util_caches_response_cache{instance=\"$instance\", job=~\"$job\", index=~\"$index\"}[$bucket_size])", + "expr": "rate(synapse_util_caches_response_cache_hits{server_name=\"$server_name\", job=~\"$job\", index=~\"$index\"}[$bucket_size])/rate(synapse_util_caches_response_cache{server_name=\"$server_name\", job=~\"$job\", index=~\"$index\"}[$bucket_size])", "interval": "", "legendFormat": "{{name}} {{job}}-{{index}}", "refId": "A" @@ -9186,46 +5334,8 @@ "refId": "B" } ], - "thresholds": [], - "timeRegions": [], "title": "Response cache hit rate", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "percentunit", - "logBase": 1, - "max": "1", - "min": "0", - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - } - ], - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" + "type": "timeseries" } ], "title": "Response caches", @@ -9233,10 +5343,6 @@ }, { "collapsed": true, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, "gridPos": { "h": 1, "w": 24, @@ -9246,10 +5352,6 @@ "id": 62, "panels": [ { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -9260,47 +5362,23 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 0, "y": 30 }, - "hiddenSeries": false, "id": 91, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "7.3.7", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": true, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(python_gc_time_sum{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[10m])", + "expr": "rate(python_gc_time_sum{job=~\"$job\",index=~\"$index\"}[10m]) * on (instance, job, index) group_left(server_name)\nsynapse_server_name_info{server_name=\"$server_name\"}", "format": "time_series", "instant": false, "intervalFactor": 1, @@ -9308,48 +5386,13 @@ "refId": "A" } ], - "thresholds": [], - "timeRegions": [], "title": "Total GC time by bucket (10m smoothing)", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "percentunit", - "logBase": 1, - "min": "0", - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, - "decimals": 3, - "editable": true, - "error": false, "fieldConfig": { "defaults": { "custom": {}, @@ -9357,49 +5400,23 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, - "grid": {}, "gridPos": { "h": 9, "w": 12, "x": 12, "y": 30 }, - "hiddenSeries": false, "id": 21, - "legend": { - "alignAsTable": true, - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 2, - "links": [], - "nullPointMode": "null as zero", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "7.3.7", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(python_gc_time_sum{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])/rate(python_gc_time_count[$bucket_size])", + "expr": "(\n rate(python_gc_time_sum{job=~\"$job\",index=~\"$index\"}[$bucket_size]) * on (instance, job, index) group_left(server_name)\n synapse_server_name_info{server_name=\"$server_name\"}\n) / (\n rate(python_gc_time_count{job=~\"$job\",index=~\"$index\"}[$bucket_size]) * on (instance, job, index) group_left(server_name)\n synapse_server_name_info{server_name=\"$server_name\"}\n)", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{job}} {{index}} gen {{gen}} ", @@ -9408,41 +5425,10 @@ "target": "" } ], - "thresholds": [], - "timeRegions": [], "title": "Average GC Time Per Collection", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "s", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -9454,97 +5440,33 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 0, "y": 39 }, - "hiddenSeries": false, "id": 89, - "legend": { - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "7.3.7", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "alias": "/gen 0$/", - "yaxis": 2 - } - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "python_gc_counts{job=~\"$job\",index=~\"$index\",instance=\"$instance\"}", + "expr": "python_gc_counts{job=~\"$job\",index=~\"$index\"} * on (instance, job, index) group_left(server_name)\nsynapse_server_name_info{server_name=\"$server_name\"}", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{job}}-{{index}} gen {{gen}}", "refId": "A" } ], - "thresholds": [], - "timeRegions": [], "title": "Allocation counts", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": "Gen N-1 GCs since last Gen N GC", - "logBase": 1, - "show": true - }, - { - "format": "short", - "label": "Objects since last Gen 0 GC", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -9555,88 +5477,33 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 12, "y": 39 }, - "hiddenSeries": false, "id": 93, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "connected", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "7.3.7", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(python_gc_unreachable_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])/rate(python_gc_time_count{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", + "expr": "(\n rate(python_gc_unreachable_total{job=~\"$job\",index=~\"$index\"}[$bucket_size]) * on (instance, job, index) group_left(server_name)\n synapse_server_name_info{server_name=\"$server_name\"}\n) / (\n rate(python_gc_time_count{job=~\"$job\",index=~\"$index\"}[$bucket_size]) * on (instance, job, index) group_left(server_name)\n synapse_server_name_info{server_name=\"$server_name\"}\n)", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{job}}-{{index}} gen {{gen}}", "refId": "A" } ], - "thresholds": [], - "timeRegions": [], "title": "Object counts per collection", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -9647,96 +5514,33 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 0, "y": 48 }, - "hiddenSeries": false, "id": 95, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "7.3.7", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(python_gc_time_count{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", + "expr": "rate(python_gc_time_count{job=~\"$job\",index=~\"$index\"}[$bucket_size]) * on (instance, job, index) group_left(server_name)\nsynapse_server_name_info{server_name=\"$server_name\"}", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{job}}-{{index}} gen {{gen}}", "refId": "A" } ], - "thresholds": [], - "timeRegions": [], "title": "GC frequency", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "hertz", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "cards": { - "cardPadding": 0 - }, - "color": { - "cardColor": "#b4ff00", - "colorScale": "sqrt", - "colorScheme": "interpolateSpectral", - "exponent": 0.5, - "min": 0, - "mode": "spectrum" - }, - "dataFormat": "tsbuckets", "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" @@ -9753,15 +5557,8 @@ "x": 12, "y": 48 }, - "heatmap": {}, - "hideZeroBuckets": true, - "highlightCards": true, "id": 87, - "legend": { - "show": true - }, - "links": [], - "reverseYBuckets": false, + "options": {}, "targets": [ { "datasource": { @@ -9776,29 +5573,7 @@ } ], "title": "GC durations", - "tooltip": { - "show": true, - "showHistogram": false - }, - "type": "heatmap", - "xAxis": { - "show": true - }, - "yAxis": { - "format": "s", - "logBase": 1, - "show": true - }, - "yBucketBound": "auto" - } - ], - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" + "type": "heatmap" } ], "title": "GC", @@ -9806,10 +5581,6 @@ }, { "collapsed": true, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, "gridPos": { "h": 1, "w": 24, @@ -9819,10 +5590,6 @@ "id": 63, "panels": [ { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" @@ -9833,48 +5600,23 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 7, "w": 12, "x": 0, "y": 162 }, - "hiddenSeries": false, "id": 43, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "sum (rate(synapse_replication_tcp_protocol_outbound_commands_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])) without (name, conn_id)", + "expr": "sum (rate(synapse_replication_tcp_protocol_outbound_commands_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])) without (name, conn_id)", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{job}}-{{index}} {{command}}", @@ -9882,37 +5624,8 @@ "step": 20 } ], - "thresholds": [], - "timeRegions": [], "title": "Rate of outgoing commands", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:89", - "format": "hertz", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:90", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { "datasource": { @@ -9979,7 +5692,6 @@ "y": 162 }, "id": 41, - "links": [], "options": { "legend": { "calcs": [], @@ -10000,7 +5712,7 @@ "uid": "${DS_PROMETHEUS}" }, "exemplar": true, - "expr": "rate(synapse_replication_tcp_resource_stream_updates_total{job=~\"$job\",index=~\"$index\",instance=\"$instance\"}[$bucket_size])", + "expr": "rate(synapse_replication_tcp_resource_stream_updates_total{job=~\"$job\",index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])", "format": "time_series", "interval": "", "intervalFactor": 2, @@ -10078,7 +5790,6 @@ "y": 169 }, "id": 42, - "links": [], "options": { "legend": { "calcs": [], @@ -10099,7 +5810,7 @@ "uid": "${DS_PROMETHEUS}" }, "exemplar": true, - "expr": "sum (rate(synapse_replication_tcp_protocol_inbound_commands_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])) without (name, conn_id)", + "expr": "sum (rate(synapse_replication_tcp_protocol_inbound_commands_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])) without (name, conn_id)", "format": "time_series", "interval": "", "intervalFactor": 2, @@ -10178,7 +5889,6 @@ "y": 169 }, "id": 220, - "links": [], "options": { "legend": { "calcs": [], @@ -10199,7 +5909,7 @@ "uid": "${DS_PROMETHEUS}" }, "exemplar": true, - "expr": "rate(synapse_replication_tcp_protocol_inbound_rdata_count_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", + "expr": "rate(synapse_replication_tcp_protocol_inbound_rdata_count_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -10212,10 +5922,6 @@ "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" @@ -10227,89 +5933,33 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 7, "w": 12, "x": 0, "y": 176 }, - "hiddenSeries": false, "id": 144, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "expr": "synapse_replication_tcp_command_queue{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}", + "expr": "synapse_replication_tcp_command_queue{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}", "interval": "", "legendFormat": "{{stream_name}} {{job}}-{{index}}", "refId": "A" } ], - "thresholds": [], - "timeRegions": [], "title": "Queued incoming RDATA commands, by stream", - "tooltip": { - "shared": false, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:218", - "format": "short", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:219", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" @@ -10320,91 +5970,33 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 7, "w": 12, "x": 12, "y": 176 }, - "hiddenSeries": false, "id": 115, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_replication_tcp_protocol_close_reason_total{job=~\"$job\",index=~\"$index\",instance=\"$instance\"}[$bucket_size])", + "expr": "rate(synapse_replication_tcp_protocol_close_reason_total{job=~\"$job\",index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{job}}-{{index}} {{reason_type}}", "refId": "A" } ], - "thresholds": [], - "timeRegions": [], "title": "Replication connection close reasons", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:260", - "format": "hertz", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:261", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -10414,48 +6006,23 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 7, "w": 12, "x": 0, "y": 183 }, - "hiddenSeries": false, "id": 113, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "synapse_replication_tcp_resource_connections_per_stream{job=~\"$job\",index=~\"$index\",instance=\"$instance\"}", + "expr": "synapse_replication_tcp_resource_connections_per_stream{job=~\"$job\",index=~\"$index\",server_name=\"$server_name\"}", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{job}}-{{index}} {{stream_name}}", @@ -10465,52 +6032,15 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "synapse_replication_tcp_resource_total_connections{job=~\"$job\",index=~\"$index\",instance=\"$instance\"}", + "expr": "synapse_replication_tcp_resource_total_connections{job=~\"$job\",index=~\"$index\",server_name=\"$server_name\"}", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{job}}-{{index}}", "refId": "B" } ], - "thresholds": [], - "timeRegions": [], "title": "Replication connections", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "logBase": 1, - "min": "0", - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - } - ], - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" + "type": "timeseries" } ], "title": "Replication", @@ -10518,10 +6048,6 @@ }, { "collapsed": true, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, "gridPos": { "h": 1, "w": 24, @@ -10531,10 +6057,6 @@ "id": 69, "panels": [ { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -10544,48 +6066,23 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 0, "y": 163 }, - "hiddenSeries": false, "id": 67, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "connected", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "max(synapse_event_persisted_position{instance=\"$instance\"}) - on() group_right() synapse_event_processing_positions{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}", + "expr": "max(synapse_event_persisted_position{server_name=\"$server_name\"}) - on () group_right() synapse_event_processing_positions{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -10593,43 +6090,10 @@ "refId": "A" } ], - "thresholds": [], - "timeRegions": [], "title": "Event processing lag", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": "events", - "logBase": 1, - "min": "0", - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -10639,48 +6103,23 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 12, "y": 163 }, - "hiddenSeries": false, "id": 71, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "connected", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "time()*1000-synapse_event_processing_last_ts{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}", + "expr": "time()*1000-synapse_event_processing_last_ts{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}", "format": "time_series", "hide": false, "interval": "", @@ -10689,42 +6128,10 @@ "refId": "B" } ], - "thresholds": [], - "timeRegions": [], "title": "Age of last processed event", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "ms", - "logBase": 1, - "min": "0", - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -10734,49 +6141,23 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 9, "w": 12, "x": 0, "y": 172 }, - "hiddenSeries": false, "id": 121, - "interval": "", - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "connected", "options": { "alertThreshold": true }, - "paceLength": 10, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "deriv(synapse_event_processing_last_ts{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])/1000 - 1", + "expr": "deriv(synapse_event_processing_last_ts{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])/1000 - 1", "format": "time_series", "hide": false, "interval": "", @@ -10785,45 +6166,8 @@ "refId": "B" } ], - "thresholds": [], - "timeRegions": [], "title": "Event processing catchup rate", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "none", - "label": "fallbehind(-) / catchup(+): s/sec", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - } - ], - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" + "type": "timeseries" } ], "title": "Event processing loop positions", @@ -10831,10 +6175,6 @@ }, { "collapsed": true, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, "gridPos": { "h": 1, "w": 24, @@ -10844,18 +6184,6 @@ "id": 126, "panels": [ { - "cards": { - "cardPadding": 0 - }, - "color": { - "cardColor": "#B877D9", - "colorScale": "sqrt", - "colorScheme": "interpolateInferno", - "exponent": 0.5, - "min": 0, - "mode": "opacity" - }, - "dataFormat": "tsbuckets", "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -10881,14 +6209,7 @@ "x": 0, "y": 42 }, - "heatmap": {}, - "hideZeroBuckets": true, - "highlightCards": true, "id": 122, - "legend": { - "show": true - }, - "links": [], "options": { "calculate": false, "calculation": {}, @@ -10929,13 +6250,12 @@ } }, "pluginVersion": "9.2.2", - "reverseYBuckets": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "synapse_forward_extremities_bucket{instance=\"$instance\"} and on (index, instance, job) (synapse_storage_events_persisted_events_total > 0)", + "expr": "synapse_forward_extremities_bucket{server_name=\"$server_name\"} and on (instance, job, index) (synapse_storage_events_persisted_events_total > 0)", "format": "heatmap", "intervalFactor": 1, "legendFormat": "{{le}}", @@ -10943,27 +6263,9 @@ } ], "title": "Number of rooms, by number of forward extremities in room", - "tooltip": { - "show": true, - "showHistogram": true - }, - "type": "heatmap", - "xAxis": { - "show": true - }, - "yAxis": { - "decimals": 0, - "format": "short", - "logBase": 1, - "show": true - }, - "yBucketBound": "auto" + "type": "heatmap" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -10974,48 +6276,23 @@ }, "overrides": [] }, - "fill": 0, - "fillGradient": 0, "gridPos": { "h": 8, "w": 12, "x": 12, "y": 42 }, - "hiddenSeries": false, "id": 124, - "interval": "", - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "connected", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "synapse_forward_extremities_bucket{instance=\"$instance\"} > 0", + "expr": "synapse_forward_extremities_bucket{server_name=\"$server_name\"} > 0", "format": "heatmap", "interval": "", "intervalFactor": 1, @@ -11023,50 +6300,10 @@ "refId": "A" } ], - "thresholds": [], - "timeRegions": [], "title": "Room counts, by number of extremities", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "none", - "label": "Number of rooms", - "logBase": 10, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": false - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "cards": { - "cardPadding": 0 - }, - "color": { - "cardColor": "#5794F2", - "colorScale": "sqrt", - "colorScheme": "interpolateInferno", - "exponent": 0.5, - "min": 0, - "mode": "opacity" - }, - "dataFormat": "tsbuckets", "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -11092,14 +6329,7 @@ "x": 0, "y": 50 }, - "heatmap": {}, - "hideZeroBuckets": true, - "highlightCards": true, "id": 127, - "legend": { - "show": true - }, - "links": [], "options": { "calculate": false, "calculation": {}, @@ -11140,13 +6370,12 @@ } }, "pluginVersion": "9.2.2", - "reverseYBuckets": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_storage_events_forward_extremities_persisted_bucket{instance=\"$instance\"}[$bucket_size]) and on (index, instance, job) (synapse_storage_events_persisted_events_total > 0)", + "expr": "rate(synapse_storage_events_forward_extremities_persisted_bucket{server_name=\"$server_name\"}[$bucket_size]) and on (instance, job, index) (synapse_storage_events_persisted_events_total > 0)", "format": "heatmap", "intervalFactor": 1, "legendFormat": "{{le}}", @@ -11154,27 +6383,9 @@ } ], "title": "Events persisted, by number of forward extremities in room (heatmap)", - "tooltip": { - "show": true, - "showHistogram": true - }, - "type": "heatmap", - "xAxis": { - "show": true - }, - "yAxis": { - "decimals": 0, - "format": "short", - "logBase": 1, - "show": true - }, - "yBucketBound": "auto" + "type": "heatmap" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -11185,47 +6396,23 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 8, "w": 12, "x": 12, "y": 50 }, - "hiddenSeries": false, "id": 128, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.5, rate(synapse_storage_events_forward_extremities_persisted_bucket{instance=\"$instance\"}[$bucket_size]) and on (index, instance, job) (synapse_storage_events_persisted_events_total > 0))", + "expr": "histogram_quantile(0.5, rate(synapse_storage_events_forward_extremities_persisted_bucket{server_name=\"$server_name\"}[$bucket_size]) and on (instance, job, index) (synapse_storage_events_persisted_events_total > 0))", "format": "time_series", "intervalFactor": 1, "legendFormat": "50%", @@ -11235,7 +6422,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.75, rate(synapse_storage_events_forward_extremities_persisted_bucket{instance=\"$instance\"}[$bucket_size]) and on (index, instance, job) (synapse_storage_events_persisted_events_total > 0))", + "expr": "histogram_quantile(0.75, rate(synapse_storage_events_forward_extremities_persisted_bucket{server_name=\"$server_name\"}[$bucket_size]) and on (instance, job, index) (synapse_storage_events_persisted_events_total > 0))", "format": "time_series", "intervalFactor": 1, "legendFormat": "75%", @@ -11245,7 +6432,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.90, rate(synapse_storage_events_forward_extremities_persisted_bucket{instance=\"$instance\"}[$bucket_size]) and on (index, instance, job) (synapse_storage_events_persisted_events_total > 0))", + "expr": "histogram_quantile(0.90, rate(synapse_storage_events_forward_extremities_persisted_bucket{server_name=\"$server_name\"}[$bucket_size]) and on (instance, job, index) (synapse_storage_events_persisted_events_total > 0))", "format": "time_series", "intervalFactor": 1, "legendFormat": "90%", @@ -11255,58 +6442,17 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.99, rate(synapse_storage_events_forward_extremities_persisted_bucket{instance=\"$instance\"}[$bucket_size]) and on (index, instance, job) (synapse_storage_events_persisted_events_total > 0))", + "expr": "histogram_quantile(0.99, rate(synapse_storage_events_forward_extremities_persisted_bucket{server_name=\"$server_name\"}[$bucket_size]) and on (instance, job, index) (synapse_storage_events_persisted_events_total > 0))", "format": "time_series", "intervalFactor": 1, "legendFormat": "99%", "refId": "D" } ], - "thresholds": [], - "timeRegions": [], "title": "Events persisted, by number of forward extremities in room (quantiles)", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": "Number of extremities in room", - "logBase": 1, - "min": "0", - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "cards": { - "cardPadding": 0 - }, - "color": { - "cardColor": "#FF9830", - "colorScale": "sqrt", - "colorScheme": "interpolateInferno", - "exponent": 0.5, - "min": 0, - "mode": "opacity" - }, - "dataFormat": "tsbuckets", "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -11332,14 +6478,7 @@ "x": 0, "y": 58 }, - "heatmap": {}, - "hideZeroBuckets": true, - "highlightCards": true, "id": 129, - "legend": { - "show": true - }, - "links": [], "options": { "calculate": false, "calculation": {}, @@ -11380,13 +6519,12 @@ } }, "pluginVersion": "9.2.2", - "reverseYBuckets": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_storage_events_stale_forward_extremities_persisted_bucket{instance=\"$instance\"}[$bucket_size]) and on (index, instance, job) (synapse_storage_events_persisted_events_total > 0)", + "expr": "rate(synapse_storage_events_stale_forward_extremities_persisted_bucket{server_name=\"$server_name\"}[$bucket_size]) and on (instance, job, index) (synapse_storage_events_persisted_events_total > 0)", "format": "heatmap", "intervalFactor": 1, "legendFormat": "{{le}}", @@ -11394,27 +6532,9 @@ } ], "title": "Events persisted, by number of stale forward extremities in room (heatmap)", - "tooltip": { - "show": true, - "showHistogram": true - }, - "type": "heatmap", - "xAxis": { - "show": true - }, - "yAxis": { - "decimals": 0, - "format": "short", - "logBase": 1, - "show": true - }, - "yBucketBound": "auto" + "type": "heatmap" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -11425,47 +6545,23 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 8, "w": 12, "x": 12, "y": 58 }, - "hiddenSeries": false, "id": 130, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.5, rate(synapse_storage_events_stale_forward_extremities_persisted_bucket{instance=\"$instance\"}[$bucket_size]) and on (index, instance, job) (synapse_storage_events_persisted_events_total > 0))", + "expr": "histogram_quantile(0.5, rate(synapse_storage_events_stale_forward_extremities_persisted_bucket{server_name=\"$server_name\"}[$bucket_size]) and on (instance, job, index) (synapse_storage_events_persisted_events_total > 0))", "format": "time_series", "intervalFactor": 1, "legendFormat": "50%", @@ -11475,7 +6571,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.75, rate(synapse_storage_events_stale_forward_extremities_persisted_bucket{instance=\"$instance\"}[$bucket_size]) and on (index, instance, job) (synapse_storage_events_persisted_events_total > 0))", + "expr": "histogram_quantile(0.75, rate(synapse_storage_events_stale_forward_extremities_persisted_bucket{server_name=\"$server_name\"}[$bucket_size]) and on (instance, job, index) (synapse_storage_events_persisted_events_total > 0))", "format": "time_series", "intervalFactor": 1, "legendFormat": "75%", @@ -11485,7 +6581,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.90, rate(synapse_storage_events_stale_forward_extremities_persisted_bucket{instance=\"$instance\"}[$bucket_size]) and on (index, instance, job) (synapse_storage_events_persisted_events_total > 0))", + "expr": "histogram_quantile(0.90, rate(synapse_storage_events_stale_forward_extremities_persisted_bucket{server_name=\"$server_name\"}[$bucket_size]) and on (instance, job, index) (synapse_storage_events_persisted_events_total > 0))", "format": "time_series", "intervalFactor": 1, "legendFormat": "90%", @@ -11495,58 +6591,17 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.99, rate(synapse_storage_events_stale_forward_extremities_persisted_bucket{instance=\"$instance\"}[$bucket_size]) and on (index, instance, job) (synapse_storage_events_persisted_events_total > 0))", + "expr": "histogram_quantile(0.99, rate(synapse_storage_events_stale_forward_extremities_persisted_bucket{server_name=\"$server_name\"}[$bucket_size]) and on (instance, job, index) (synapse_storage_events_persisted_events_total > 0))", "format": "time_series", "intervalFactor": 1, "legendFormat": "99%", "refId": "D" } ], - "thresholds": [], - "timeRegions": [], "title": "Events persisted, by number of stale forward extremities in room (quantiles)", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": "Number of stale forward extremities in room", - "logBase": 1, - "min": "0", - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "cards": { - "cardPadding": 0 - }, - "color": { - "cardColor": "#73BF69", - "colorScale": "sqrt", - "colorScheme": "interpolateInferno", - "exponent": 0.5, - "min": 0, - "mode": "opacity" - }, - "dataFormat": "tsbuckets", "datasource": { "uid": "${DS_PROMETHEUS}" }, @@ -11572,14 +6627,7 @@ "x": 0, "y": 66 }, - "heatmap": {}, - "hideZeroBuckets": true, - "highlightCards": true, "id": 131, - "legend": { - "show": true - }, - "links": [], "options": { "calculate": false, "calculation": {}, @@ -11620,13 +6668,12 @@ } }, "pluginVersion": "9.2.2", - "reverseYBuckets": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_state_number_state_groups_in_resolution_bucket{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", + "expr": "rate(synapse_state_number_state_groups_in_resolution_bucket{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size])", "format": "heatmap", "interval": "", "intervalFactor": 1, @@ -11635,27 +6682,9 @@ } ], "title": "Number of state resolution performed, by number of state groups involved (heatmap)", - "tooltip": { - "show": true, - "showHistogram": true - }, - "type": "heatmap", - "xAxis": { - "show": true - }, - "yAxis": { - "decimals": 0, - "format": "short", - "logBase": 1, - "show": true - }, - "yBucketBound": "auto" + "type": "heatmap" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" @@ -11667,49 +6696,24 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 8, "w": 12, "x": 12, "y": 66 }, - "hiddenSeries": false, "id": 132, - "interval": "", - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "histogram_quantile(0.5, rate(synapse_state_number_state_groups_in_resolution_bucket{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size]))", + "expr": "histogram_quantile(0.5, rate(synapse_state_number_state_groups_in_resolution_bucket{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size]))", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -11721,7 +6725,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.75, rate(synapse_state_number_state_groups_in_resolution_bucket{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size]))", + "expr": "histogram_quantile(0.75, rate(synapse_state_number_state_groups_in_resolution_bucket{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size]))", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -11732,7 +6736,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.90, rate(synapse_state_number_state_groups_in_resolution_bucket{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size]))", + "expr": "histogram_quantile(0.90, rate(synapse_state_number_state_groups_in_resolution_bucket{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size]))", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -11743,7 +6747,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "histogram_quantile(0.99, rate(synapse_state_number_state_groups_in_resolution_bucket{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size]))", + "expr": "histogram_quantile(0.99, rate(synapse_state_number_state_groups_in_resolution_bucket{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size]))", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -11751,87 +6755,35 @@ "refId": "D" } ], - "thresholds": [], - "timeRegions": [], "title": "Number of state resolutions performed, by number of state groups involved (quantiles)", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": "Number of state groups", - "logBase": 1, - "min": "0", - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, "description": "When we do a state res while persisting events we try and see if we can prune any stale extremities.", - "fill": 1, - "fillGradient": 0, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, "gridPos": { "h": 8, "w": 12, "x": 0, "y": 74 }, - "hiddenSeries": false, "id": 179, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "sum(rate(synapse_storage_events_state_resolutions_during_persistence_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size]))", + "expr": "sum(rate(synapse_storage_events_state_resolutions_during_persistence_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size]))", "interval": "", "legendFormat": "State res ", "refId": "A" @@ -11840,7 +6792,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "sum(rate(synapse_storage_events_potential_times_prune_extremities_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size]))", + "expr": "sum(rate(synapse_storage_events_potential_times_prune_extremities_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size]))", "interval": "", "legendFormat": "Potential to prune", "refId": "B" @@ -11849,50 +6801,14 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "sum(rate(synapse_storage_events_times_pruned_extremities_total{instance=\"$instance\",job=~\"$job\",index=~\"$index\"}[$bucket_size]))", + "expr": "sum(rate(synapse_storage_events_times_pruned_extremities_total{server_name=\"$server_name\",job=~\"$job\",index=~\"$index\"}[$bucket_size]))", "interval": "", "legendFormat": "Pruned", "refId": "C" } ], - "thresholds": [], - "timeRegions": [], "title": "Stale extremity dropping", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "hertz", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - } - ], - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" + "type": "timeseries" } ], "title": "Extremities", @@ -11900,10 +6816,6 @@ }, { "collapsed": true, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, "gridPos": { "h": 1, "w": 24, @@ -11913,10 +6825,6 @@ "id": 158, "panels": [ { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" @@ -11927,56 +6835,24 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 8, "w": 12, "x": 0, "y": 43 }, - "hiddenSeries": false, "id": 156, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "$$hashKey": "object:632", - "alias": "Max", - "color": "#bf1b00", - "fill": 0, - "linewidth": 2 - } - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "max(synapse_admin_mau_max{instance=\"$instance\"})", + "expr": "max(synapse_admin_mau_max{server_name=\"$server_name\"})", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -11990,137 +6866,48 @@ "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "max(synapse_admin_mau_current{instance=\"$instance\"})", + "expr": "max(synapse_admin_mau_current{server_name=\"$server_name\"})", "hide": false, "legendFormat": "Current", "range": true, "refId": "C" } ], - "thresholds": [], - "timeRegions": [], "title": "MAU Limits", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:176", - "format": "short", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:177", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, - "fill": 1, - "fillGradient": 0, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, "gridPos": { "h": 8, "w": 12, "x": 12, "y": 43 }, - "hiddenSeries": false, "id": 160, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "synapse_admin_mau_current_mau_by_service{instance=\"$instance\"}", + "expr": "synapse_admin_mau_current_mau_by_service{server_name=\"$server_name\"}", "interval": "", "legendFormat": "{{ app_service }}", "refId": "A" } ], - "thresholds": [], - "timeRegions": [], "title": "MAU by Appservice", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - } - ], - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" + "type": "timeseries" } ], "title": "MAU", @@ -12128,10 +6915,6 @@ }, { "collapsed": true, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, "gridPos": { "h": 1, "w": 24, @@ -12141,10 +6924,6 @@ "id": 177, "panels": [ { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" @@ -12155,48 +6934,24 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 7, "w": 12, "x": 0, "y": 44 }, - "hiddenSeries": false, "id": 173, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "rate(synapse_notifier_users_woken_by_stream_total{job=\"$job\",index=~\"$index\",instance=\"$instance\"}[$bucket_size])", + "expr": "rate(synapse_notifier_users_woken_by_stream_total{job=~\"$job\",index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])", "format": "time_series", "hide": false, "intervalFactor": 2, @@ -12207,43 +6962,10 @@ "step": 2 } ], - "thresholds": [], - "timeRegions": [], "title": "Notifier Streams Woken", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:734", - "format": "hertz", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:735", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" @@ -12254,48 +6976,24 @@ }, "overrides": [] }, - "fill": 1, - "fillGradient": 0, "gridPos": { "h": 7, "w": 12, "x": 12, "y": 44 }, - "hiddenSeries": false, "id": 175, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "rate(synapse_handler_presence_get_updates_total{job=~\"$job\",instance=\"$instance\"}[$bucket_size])", + "expr": "rate(synapse_handler_presence_get_updates_total{job=~\"$job\",server_name=\"$server_name\"}[$bucket_size])", "format": "time_series", "interval": "", "intervalFactor": 2, @@ -12305,47 +7003,8 @@ "step": 2 } ], - "thresholds": [], - "timeRegions": [], "title": "Presence Stream Fetch Type Rates", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:819", - "format": "hertz", - "logBase": 1, - "min": "0", - "show": true - }, - { - "$$hashKey": "object:820", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - } - ], - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" + "type": "timeseries" } ], "title": "Notifier", @@ -12353,10 +7012,6 @@ }, { "collapsed": true, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, "gridPos": { "h": 1, "w": 24, @@ -12366,189 +7021,76 @@ "id": 170, "panels": [ { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "fill": 1, - "fillGradient": 0, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, "gridPos": { "h": 8, "w": 12, "x": 0, "y": 45 }, - "hiddenSeries": false, "id": 168, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "rate(synapse_appservice_api_sent_events_total{instance=\"$instance\"}[$bucket_size])", + "expr": "rate(synapse_appservice_api_sent_events_total{server_name=\"$server_name\"}[$bucket_size])", "interval": "", "legendFormat": "{{service}}", "range": true, "refId": "A" } ], - "thresholds": [], - "timeRegions": [], "title": "Sent Events rate", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:177", - "format": "hertz", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:178", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "fill": 1, - "fillGradient": 0, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, "gridPos": { "h": 8, "w": 12, "x": 12, "y": 45 }, - "hiddenSeries": false, "id": 171, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "rate(synapse_appservice_api_sent_transactions_total{instance=\"$instance\"}[$bucket_size])", + "expr": "rate(synapse_appservice_api_sent_transactions_total{server_name=\"$server_name\"}[$bucket_size])", "interval": "", "legendFormat": "{{exported_service }} {{ service }}", "range": true, "refId": "A" } ], - "thresholds": [], - "timeRegions": [], "title": "Transactions rate", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:260", - "format": "hertz", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:261", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - } - ], - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" + "type": "timeseries" } ], "title": "Appservices", @@ -12556,10 +7098,6 @@ }, { "collapsed": true, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, "gridPos": { "h": 1, "w": 24, @@ -12569,53 +7107,30 @@ "id": 188, "panels": [ { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "uid": "${DS_PROMETHEUS}" }, - "fill": 1, - "fillGradient": 0, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, "gridPos": { "h": 8, "w": 12, "x": 0, "y": 46 }, - "hiddenSeries": false, "id": 182, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_handler_presence_notified_presence_total{job=\"$job\",index=~\"$index\",instance=\"$instance\"}[$bucket_size])", + "expr": "rate(synapse_handler_presence_notified_presence_total{job=~\"$job\",index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])", "interval": "", "legendFormat": "Notified", "refId": "A" @@ -12624,7 +7139,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_handler_presence_federation_presence_out_total{job=\"$job\",index=~\"$index\",instance=\"$instance\"}[$bucket_size])", + "expr": "rate(synapse_handler_presence_federation_presence_out_total{job=~\"$job\",index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])", "interval": "", "legendFormat": "Remote ping", "refId": "B" @@ -12633,7 +7148,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_handler_presence_presence_updates_total{job=\"$job\",index=~\"$index\",instance=\"$instance\"}[$bucket_size])", + "expr": "rate(synapse_handler_presence_presence_updates_total{job=~\"$job\",index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])", "interval": "", "legendFormat": "Total updates", "refId": "C" @@ -12642,7 +7157,7 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_handler_presence_federation_presence_total{job=\"$job\",index=~\"$index\",instance=\"$instance\"}[$bucket_size])", + "expr": "rate(synapse_handler_presence_federation_presence_total{job=~\"$job\",index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])", "interval": "", "legendFormat": "Remote updates", "refId": "D" @@ -12651,226 +7166,86 @@ "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "rate(synapse_handler_presence_bump_active_time_total{job=\"$job\",index=~\"$index\",instance=\"$instance\"}[$bucket_size])", + "expr": "rate(synapse_handler_presence_bump_active_time_total{job=~\"$job\",index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])", "interval": "", "legendFormat": "Bump active time", "refId": "E" } ], - "thresholds": [], - "timeRegions": [], "title": "Presence", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "hertz", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "fill": 1, - "fillGradient": 0, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, "gridPos": { "h": 8, "w": 12, "x": 12, "y": 46 }, - "hiddenSeries": false, "id": 184, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "rate(synapse_handler_presence_state_transition_total{job=\"$job\",index=~\"$index\",instance=\"$instance\"}[$bucket_size])", + "expr": "rate(synapse_handler_presence_state_transition_total{job=~\"$job\",index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])", "interval": "", "legendFormat": "{{from}} -> {{to}}", "range": true, "refId": "A" } ], - "thresholds": [], - "timeRegions": [], "title": "Presence state transitions", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:1090", - "format": "hertz", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:1091", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "fill": 1, - "fillGradient": 0, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, "gridPos": { "h": 8, "w": 12, "x": 0, "y": 54 }, - "hiddenSeries": false, "id": 186, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "rate(synapse_handler_presence_notify_reason_total{job=\"$job\",index=~\"$index\",instance=\"$instance\"}[$bucket_size])", + "expr": "rate(synapse_handler_presence_notify_reason_total{job=~\"$job\",index=~\"$index\",server_name=\"$server_name\"}[$bucket_size])", "interval": "", "legendFormat": "{{reason}}", "range": true, "refId": "A" } ], - "thresholds": [], - "timeRegions": [], "title": "Presence notify reason", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:165", - "format": "hertz", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:166", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } - } - ], - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" + "type": "timeseries" } ], "title": "Presence", @@ -12878,10 +7253,6 @@ }, { "collapsed": true, - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, "gridPos": { "h": 1, "w": 24, @@ -12973,7 +7344,7 @@ "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "rate(synapse_external_cache_set{job=~\"$job\", instance=\"$instance\", index=~\"$index\"}[$bucket_size])", + "expr": "rate(synapse_external_cache_set{job=~\"$job\", server_name=\"$server_name\", index=~\"$index\"}[$bucket_size])", "interval": "", "legendFormat": "{{ cache_name }} {{job}}-{{ index }}", "range": true, @@ -12984,107 +7355,43 @@ "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, "description": "", - "fill": 1, - "fillGradient": 0, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, "gridPos": { "h": 8, "w": 12, "x": 12, "y": 47 }, - "hiddenSeries": false, "id": 193, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", "options": { "alertThreshold": true }, - "percentage": false, "pluginVersion": "9.2.2", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "sum without (hit) (rate(synapse_external_cache_get{job=~\"$job\", instance=\"$instance\", index=~\"$index\"}[$bucket_size]))", + "expr": "sum without (hit) (rate(synapse_external_cache_get{job=~\"$job\", server_name=\"$server_name\", index=~\"$index\"}[$bucket_size]))", "interval": "", "legendFormat": "{{ cache_name }} {{job}}-{{ index }}", "range": true, "refId": "A" } ], - "thresholds": [], - "timeRegions": [], "title": "External Cache Get Rate", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:390", - "format": "hertz", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:391", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "cards": { - "cardPadding": -1 - }, - "color": { - "cardColor": "#b4ff00", - "colorScale": "sqrt", - "colorScheme": "interpolateInferno", - "exponent": 0.5, - "min": 0, - "mode": "spectrum" - }, - "dataFormat": "tsbuckets", "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" @@ -13110,14 +7417,7 @@ "x": 0, "y": 55 }, - "heatmap": {}, - "hideZeroBuckets": false, - "highlightCards": true, "id": 195, - "legend": { - "show": false - }, - "links": [], "options": { "calculate": false, "calculation": {}, @@ -13160,13 +7460,12 @@ } }, "pluginVersion": "9.2.2", - "reverseYBuckets": false, "targets": [ { "datasource": { "uid": "${DS_PROMETHEUS}" }, - "expr": "sum(rate(synapse_external_cache_response_time_seconds_bucket{index=~\"$index\",instance=\"$instance\",job=~\"$job\"}[$bucket_size])) by (le)", + "expr": "sum(rate(synapse_external_cache_response_time_seconds_bucket{index=~\"$index\",server_name=\"$server_name\",job=~\"$job\"}[$bucket_size])) by (le)", "format": "heatmap", "instant": false, "interval": "", @@ -13176,22 +7475,7 @@ } ], "title": "External Cache Response Time", - "tooltip": { - "show": true, - "showHistogram": true - }, - "tooltipDecimals": 2, - "type": "heatmap", - "xAxis": { - "show": true - }, - "yAxis": { - "decimals": 0, - "format": "s", - "logBase": 1, - "show": true - }, - "yBucketBound": "auto" + "type": "heatmap" }, { "datasource": { @@ -13273,7 +7557,7 @@ "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "rate(synapse_external_cache_get{job=~\"$job\", instance=\"$instance\", index=~\"$index\", hit=\"False\"}[$bucket_size])", + "expr": "rate(synapse_external_cache_get{job=~\"$job\", server_name=\"$server_name\", index=~\"$index\", hit=\"False\"}[$bucket_size])", "interval": "", "legendFormat": "{{ cache_name }} {{job}}-{{ index }}", "range": true, @@ -13284,22 +7568,13 @@ "type": "timeseries" } ], - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "refId": "A" - } - ], "title": "External Cache", "type": "row" } ], - "refresh": false, - "schemaVersion": 37, - "style": "dark", + "preload": false, + "refresh": "", + "schemaVersion": 42, "tags": [ "matrix" ], @@ -13307,45 +7582,30 @@ "list": [ { "current": { - "selected": false, - "text": "default", - "value": "default" + "text": "", + "value": "${DS_PROMETHEUS}", + "selected": true }, - "hide": 0, "includeAll": false, - "multi": false, - "name": "DS_PROMETHEUS", "label": "Datasource", + "name": "DS_PROMETHEUS", "options": [], "query": "prometheus", - "queryValue": "", "refresh": 1, "regex": "", - "skipUrlSync": false, "type": "datasource" }, { - "allFormat": "glob", "auto": true, "auto_count": 100, "auto_min": "30s", "current": { - "selected": false, - "text": "auto", - "value": "$__auto_interval_bucket_size" + "text": "$__auto", + "value": "$__auto" }, - "hide": 0, - "includeAll": false, "label": "Bucket Size", - "multi": false, - "multiFormat": "glob", "name": "bucket_size", "options": [ - { - "selected": true, - "text": "auto", - "value": "$__auto_interval_bucket_size" - }, { "selected": false, "text": "30s", @@ -13378,9 +7638,7 @@ } ], "query": "30s,1m,2m,5m,10m,15m", - "queryValue": "", "refresh": 2, - "skipUrlSync": false, "type": "interval" }, { @@ -13389,38 +7647,27 @@ "uid": "${DS_PROMETHEUS}" }, "definition": "", - "hide": 0, "includeAll": false, - "multi": false, - "name": "instance", + "name": "server_name", "options": [], "query": { - "query": "label_values(synapse_util_metrics_block_ru_utime_seconds_total, instance)", + "query": "label_values(synapse_util_metrics_block_ru_utime_seconds_total, server_name)", "refId": "Prometheus-instance-Variable-Query" }, "refresh": 2, "regex": "", - "skipUrlSync": false, "sort": 1, - "tagValuesQuery": "", - "tagsQuery": "", - "type": "query", - "useTags": false + "type": "query" }, { - "allFormat": "regex wildcard", - "allValue": "", "current": {}, "datasource": { "uid": "${DS_PROMETHEUS}" }, "definition": "", - "hide": 0, - "hideLabel": false, "includeAll": true, "label": "Job", "multi": true, - "multiFormat": "regex values", "name": "job", "options": [], "query": { @@ -13428,29 +7675,19 @@ "refId": "Prometheus-job-Variable-Query" }, "refresh": 2, - "refresh_on_load": false, "regex": "", - "skipUrlSync": false, "sort": 1, - "tagValuesQuery": "", - "tagsQuery": "", - "type": "query", - "useTags": false + "type": "query" }, { - "allFormat": "regex wildcard", "allValue": ".*", "current": {}, "datasource": { "uid": "${DS_PROMETHEUS}" }, "definition": "", - "hide": 0, - "hideLabel": false, "includeAll": true, - "label": "", "multi": true, - "multiFormat": "regex values", "name": "index", "options": [], "query": { @@ -13458,14 +7695,9 @@ "refId": "Prometheus-index-Variable-Query" }, "refresh": 2, - "refresh_on_load": false, "regex": "", - "skipUrlSync": false, "sort": 3, - "tagValuesQuery": "", - "tagsQuery": "", - "type": "query", - "useTags": false + "type": "query" } ] }, @@ -13473,35 +7705,10 @@ "from": "now-3h", "to": "now" }, - "timepicker": { - "now": true, - "refresh_intervals": [ - "5s", - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ], - "time_options": [ - "5m", - "15m", - "1h", - "6h", - "12h", - "24h", - "2d", - "7d", - "30d" - ] - }, + "timepicker": {}, "timezone": "", "title": "Synapse", "uid": "000000012", - "version": 160, + "version": 1, "weekStart": "" } diff --git a/contrib/graph/graph.py b/contrib/graph/graph.py index 9d5f3c7f4f..2898bb3448 100644 --- a/contrib/graph/graph.py +++ b/contrib/graph/graph.py @@ -24,7 +24,6 @@ import datetime import html import json import urllib.request -from typing import List import pydot @@ -33,7 +32,7 @@ def make_name(pdu_id: str, origin: str) -> str: return f"{pdu_id}@{origin}" -def make_graph(pdus: List[dict], filename_prefix: str) -> None: +def make_graph(pdus: list[dict], filename_prefix: str) -> None: """ Generate a dot and SVG file for a graph of events in the room based on the topological ordering by querying a homeserver. @@ -127,7 +126,7 @@ def make_graph(pdus: List[dict], filename_prefix: str) -> None: graph.write_svg("%s.svg" % filename_prefix, prog="dot") -def get_pdus(host: str, room: str) -> List[dict]: +def get_pdus(host: str, room: str) -> list[dict]: transaction = json.loads( urllib.request.urlopen( f"http://{host}/_matrix/federation/v1/context/{room}/" diff --git a/contrib/prometheus/synapse-v2.rules b/contrib/prometheus/synapse-v2.rules index dde311322f..3a5de8f528 100644 --- a/contrib/prometheus/synapse-v2.rules +++ b/contrib/prometheus/synapse-v2.rules @@ -44,31 +44,3 @@ groups: ### ### End of 'Prometheus Console Only' rules block ### - - - ### - ### Grafana Only - ### The following rules are only needed if you use the Grafana dashboard - ### in contrib/grafana/synapse.json - ### - - record: synapse_storage_events_persisted_by_source_type - expr: sum without(type, origin_type, origin_entity) (synapse_storage_events_persisted_events_sep_total{origin_type="remote"}) - labels: - type: remote - - record: synapse_storage_events_persisted_by_source_type - expr: sum without(type, origin_type, origin_entity) (synapse_storage_events_persisted_events_sep_total{origin_entity="*client*",origin_type="local"}) - labels: - type: local - - record: synapse_storage_events_persisted_by_source_type - expr: sum without(type, origin_type, origin_entity) (synapse_storage_events_persisted_events_sep_total{origin_entity!="*client*",origin_type="local"}) - labels: - type: bridges - - - record: synapse_storage_events_persisted_by_event_type - expr: sum without(origin_entity, origin_type) (synapse_storage_events_persisted_events_sep_total) - - - record: synapse_storage_events_persisted_by_origin - expr: sum without(type) (synapse_storage_events_persisted_events_sep_total) - ### - ### End of 'Grafana Only' rules block - ### diff --git a/contrib/systemd/README.md b/contrib/systemd/README.md index d12d8ec37b..456b4e9a16 100644 --- a/contrib/systemd/README.md +++ b/contrib/systemd/README.md @@ -16,3 +16,9 @@ appropriate locations of your installation. 5. Start Synapse: `sudo systemctl start matrix-synapse` 6. Verify Synapse is running: `sudo systemctl status matrix-synapse` 7. *optional* Enable Synapse to start at system boot: `sudo systemctl enable matrix-synapse` + +## Logging + +If you use `contrib/systemd/log_config.yaml`, install `systemd-python` in the +same Python environment as Synapse. The config uses +`systemd.journal.JournalHandler`, which requires that package. diff --git a/contrib/systemd/log_config.yaml b/contrib/systemd/log_config.yaml index 22f67a50ce..4c29787647 100644 --- a/contrib/systemd/log_config.yaml +++ b/contrib/systemd/log_config.yaml @@ -1,5 +1,6 @@ version: 1 +# Requires the `systemd-python` package in Synapse's runtime environment. # In systemd's journal, loglevel is implicitly stored, so let's omit it # from the message text. formatters: diff --git a/debian/build_virtualenv b/debian/build_virtualenv index 9e7fb95c8e..7bbf52ddd9 100755 --- a/debian/build_virtualenv +++ b/debian/build_virtualenv @@ -35,12 +35,14 @@ TEMP_VENV="$(mktemp -d)" python3 -m venv "$TEMP_VENV" source "$TEMP_VENV/bin/activate" pip install -U pip -pip install poetry==2.1.1 poetry-plugin-export==1.9.0 +pip install poetry==2.2.1 poetry-plugin-export==1.9.0 poetry export \ --extras all \ --extras test \ - --extras systemd \ -o exported_requirements.txt +# Keep journald logging support in the packaged virtualenv when using +# systemd.journal.JournalHandler in /etc/matrix-synapse/log.yaml. +echo "systemd-python==235 --hash=sha256:4e57f39797fd5d9e2d22b8806a252d7c0106c936039d1e71c8c6b8008e695c0a" >> exported_requirements.txt deactivate rm -rf "$TEMP_VENV" @@ -57,7 +59,7 @@ dh_virtualenv \ --extra-pip-arg="--no-deps" \ --extra-pip-arg="--no-cache-dir" \ --extra-pip-arg="--compile" \ - --extras="all,systemd,test" \ + --extras="all,test" \ --requirements="exported_requirements.txt" PACKAGE_BUILD_DIR="$(pwd)/debian/matrix-synapse-py3" diff --git a/debian/changelog b/debian/changelog index c9b86aea2a..f3dc1eb0c2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,280 @@ +matrix-synapse-py3 (1.151.0) stable; urgency=medium + + * New synapse release 1.151.0. + + -- Synapse Packaging team Tue, 07 Apr 2026 12:15:10 +0000 + +matrix-synapse-py3 (1.151.0~rc1) stable; urgency=medium + + * New synapse release 1.151.0rc1. + + -- Synapse Packaging team Tue, 31 Mar 2026 12:23:34 +0000 + +matrix-synapse-py3 (1.150.0) stable; urgency=medium + + * New synapse release 1.150.0. + + -- Synapse Packaging team Tue, 24 Mar 2026 14:17:04 +0000 + +matrix-synapse-py3 (1.150.0~rc1) stable; urgency=medium + + [ Quentin Gliech ] + * Change how the systemd journald integration is installed. + * Update Poetry used at build time to 2.2.1. + + [ Synapse Packaging team ] + * New synapse release 1.150.0rc1. + + -- Synapse Packaging team Tue, 17 Mar 2026 14:56:35 +0000 + +matrix-synapse-py3 (1.149.1) stable; urgency=medium + + * New synapse release 1.149.1. + + -- Synapse Packaging team Wed, 11 Mar 2026 09:30:24 +0000 + +matrix-synapse-py3 (1.149.0) stable; urgency=medium + + * New synapse release 1.149.0. + + -- Synapse Packaging team Tue, 10 Mar 2026 13:02:53 +0000 + +matrix-synapse-py3 (1.149.0~rc1) stable; urgency=medium + + * New synapse release 1.149.0rc1. + + -- Synapse Packaging team Tue, 03 Mar 2026 14:37:57 +0000 + +matrix-synapse-py3 (1.148.0) stable; urgency=medium + + * New synapse release 1.148.0. + + -- Synapse Packaging team Tue, 24 Feb 2026 11:17:49 +0000 + +matrix-synapse-py3 (1.148.0~rc1) stable; urgency=medium + + * New synapse release 1.148.0rc1. + + -- Synapse Packaging team Tue, 17 Feb 2026 16:44:08 +0000 + +matrix-synapse-py3 (1.147.1) stable; urgency=medium + + * New synapse release 1.147.1. + + -- Synapse Packaging team Thu, 12 Feb 2026 15:45:15 +0000 + +matrix-synapse-py3 (1.147.0) stable; urgency=medium + + * New synapse release 1.147.0. + + -- Synapse Packaging team Tue, 10 Feb 2026 12:39:58 +0000 + +matrix-synapse-py3 (1.147.0~rc1) stable; urgency=medium + + * New Synapse release 1.147.0rc1. + + -- Synapse Packaging team Tue, 03 Feb 2026 08:53:17 -0700 + +matrix-synapse-py3 (1.146.0) stable; urgency=medium + + * New Synapse release 1.146.0. + + -- Synapse Packaging team Tue, 27 Jan 2026 08:43:59 -0700 + +matrix-synapse-py3 (1.146.0~rc1) stable; urgency=medium + + * New Synapse release 1.146.0rc1. + + -- Synapse Packaging team Tue, 20 Jan 2026 08:42:10 -0700 + +matrix-synapse-py3 (1.145.0) stable; urgency=medium + + * New Synapse release 1.145.0. + + -- Synapse Packaging team Tue, 13 Jan 2026 08:37:42 -0700 + +matrix-synapse-py3 (1.145.0~rc4) stable; urgency=medium + + * New Synapse release 1.145.0rc4. + + -- Synapse Packaging team Thu, 08 Jan 2026 12:06:35 -0700 + +matrix-synapse-py3 (1.145.0~rc3) stable; urgency=medium + + * New Synapse release 1.145.0rc3. + + -- Synapse Packaging team Wed, 07 Jan 2026 15:32:07 -0700 + +matrix-synapse-py3 (1.145.0~rc2) stable; urgency=medium + + * New Synapse release 1.145.0rc2. + + -- Synapse Packaging team Wed, 07 Jan 2026 10:10:07 -0700 + +matrix-synapse-py3 (1.145.0~rc1) stable; urgency=medium + + * New Synapse release 1.145.0rc1. + + -- Synapse Packaging team Tue, 06 Jan 2026 09:29:39 -0700 + +matrix-synapse-py3 (1.144.0) stable; urgency=medium + + * New Synapse release 1.144.0. + + -- Synapse Packaging team Tue, 09 Dec 2025 08:30:40 -0700 + +matrix-synapse-py3 (1.144.0~rc1) stable; urgency=medium + + * New Synapse release 1.144.0rc1. + + -- Synapse Packaging team Tue, 02 Dec 2025 09:11:19 -0700 + +matrix-synapse-py3 (1.143.0) stable; urgency=medium + + * New Synapse release 1.143.0. + + -- Synapse Packaging team Tue, 25 Nov 2025 08:44:56 -0700 + +matrix-synapse-py3 (1.143.0~rc2) stable; urgency=medium + + * New Synapse release 1.143.0rc2. + + -- Synapse Packaging team Tue, 18 Nov 2025 17:36:08 -0700 + +matrix-synapse-py3 (1.143.0~rc1) stable; urgency=medium + + * New Synapse release 1.143.0rc1. + + -- Synapse Packaging team Tue, 18 Nov 2025 13:08:39 -0700 + +matrix-synapse-py3 (1.142.1) stable; urgency=medium + + * New Synapse release 1.142.1. + + -- Synapse Packaging team Tue, 18 Nov 2025 12:25:23 -0700 + +matrix-synapse-py3 (1.142.0) stable; urgency=medium + + * New Synapse release 1.142.0. + + -- Synapse Packaging team Tue, 11 Nov 2025 09:45:51 +0000 + +matrix-synapse-py3 (1.142.0~rc4) stable; urgency=medium + + * New Synapse release 1.142.0rc4. + + -- Synapse Packaging team Fri, 07 Nov 2025 10:54:42 +0000 + +matrix-synapse-py3 (1.142.0~rc3) stable; urgency=medium + + * New Synapse release 1.142.0rc3. + + -- Synapse Packaging team Tue, 04 Nov 2025 17:39:11 +0000 + +matrix-synapse-py3 (1.142.0~rc2) stable; urgency=medium + + * New Synapse release 1.142.0rc2. + + -- Synapse Packaging team Tue, 04 Nov 2025 16:21:30 +0000 + +matrix-synapse-py3 (1.142.0~rc1) stable; urgency=medium + + * New Synapse release 1.142.0rc1. + + -- Synapse Packaging team Tue, 04 Nov 2025 13:20:15 +0000 + +matrix-synapse-py3 (1.141.0) stable; urgency=medium + + * New Synapse release 1.141.0. + + -- Synapse Packaging team Wed, 29 Oct 2025 11:01:43 +0000 + +matrix-synapse-py3 (1.141.0~rc2) stable; urgency=medium + + * New Synapse release 1.141.0rc2. + + -- Synapse Packaging team Tue, 28 Oct 2025 10:20:26 +0000 + +matrix-synapse-py3 (1.141.0~rc1) stable; urgency=medium + + * New Synapse release 1.141.0rc1. + + -- Synapse Packaging team Tue, 21 Oct 2025 11:01:44 +0100 + +matrix-synapse-py3 (1.140.0) stable; urgency=medium + + * New Synapse release 1.140.0. + + -- Synapse Packaging team Tue, 14 Oct 2025 15:22:36 +0100 + +matrix-synapse-py3 (1.140.0~rc1) stable; urgency=medium + + * New Synapse release 1.140.0rc1. + + -- Synapse Packaging team Fri, 10 Oct 2025 10:56:51 +0100 + +matrix-synapse-py3 (1.139.2) stable; urgency=medium + + * New Synapse release 1.139.2. + + -- Synapse Packaging team Tue, 07 Oct 2025 16:29:47 +0100 + +matrix-synapse-py3 (1.139.1) stable; urgency=medium + + * New Synapse release 1.139.1. + + -- Synapse Packaging team Tue, 07 Oct 2025 11:46:51 +0100 + +matrix-synapse-py3 (1.138.4) stable; urgency=medium + + * New Synapse release 1.138.4. + + -- Synapse Packaging team Tue, 07 Oct 2025 16:28:38 +0100 + +matrix-synapse-py3 (1.138.3) stable; urgency=medium + + * New Synapse release 1.138.3. + + -- Synapse Packaging team Tue, 07 Oct 2025 12:54:18 +0100 + +matrix-synapse-py3 (1.139.0) stable; urgency=medium + + * New Synapse release 1.139.0. + + -- Synapse Packaging team Tue, 30 Sep 2025 11:58:55 +0100 + +matrix-synapse-py3 (1.139.0~rc3) stable; urgency=medium + + * New Synapse release 1.139.0rc3. + + -- Synapse Packaging team Thu, 25 Sep 2025 12:13:23 +0100 + +matrix-synapse-py3 (1.138.2) stable; urgency=medium + + * The licensing specifier has been updated to add an optional + `LicenseRef-Element-Commercial` license. The code was already licensed in + this manner - the debian metadata was just not updated to reflect it. + + -- Synapse Packaging team Thu, 25 Sep 2025 12:17:17 +0100 + +matrix-synapse-py3 (1.138.1) stable; urgency=medium + + * New Synapse release 1.138.1. + + -- Synapse Packaging team Wed, 24 Sep 2025 11:32:38 +0100 + +matrix-synapse-py3 (1.139.0~rc2) stable; urgency=medium + + * New Synapse release 1.139.0rc2. + + -- Synapse Packaging team Tue, 23 Sep 2025 15:31:42 +0100 + +matrix-synapse-py3 (1.139.0~rc1) stable; urgency=medium + + * New Synapse release 1.139.0rc1. + + -- Synapse Packaging team Tue, 23 Sep 2025 13:24:50 +0100 + matrix-synapse-py3 (1.138.0~rc1) stable; urgency=medium * New synapse release 1.138.0rc1. diff --git a/debian/copyright b/debian/copyright index 9e407ce425..9814133edf 100644 --- a/debian/copyright +++ b/debian/copyright @@ -8,7 +8,7 @@ License: Apache-2.0 Files: * Copyright: 2023 New Vector Ltd -License: AGPL-3.0-or-later +License: AGPL-3.0-or-later or LicenseRef-Element-Commercial Files: synapse/config/saml2.py Copyright: 2015, Ericsson diff --git a/demo/start.sh b/demo/start.sh index e010302bf4..471e881f46 100755 --- a/demo/start.sh +++ b/demo/start.sh @@ -49,7 +49,7 @@ for port in 8080 8081 8082; do # Please don't accidentally bork me with your fancy settings. listeners=$(cat <<-PORTLISTENERS # Configure server to listen on both $https_port and $port - # This overides some of the default settings above + # This overrides some of the default settings above listeners: - port: $https_port type: http @@ -145,6 +145,12 @@ for port in 8080 8081 8082; do rc_delayed_event_mgmt: per_second: 1000 burst_count: 1000 + rc_room_creation: + per_second: 1000 + burst_count: 1000 + rc_user_directory: + per_second: 1000 + burst_count: 1000 RC ) echo "${ratelimiting}" >> "$port.config" diff --git a/docker/Dockerfile b/docker/Dockerfile index 15c458fa28..6070d5c355 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -20,9 +20,9 @@ # `poetry export | pip install -r /dev/stdin`, but beware: we have experienced bugs in # in `poetry export` in the past. -ARG DEBIAN_VERSION=bookworm -ARG PYTHON_VERSION=3.12 -ARG POETRY_VERSION=2.1.1 +ARG DEBIAN_VERSION=trixie +ARG PYTHON_VERSION=3.13 +ARG POETRY_VERSION=2.2.1 ### ### Stage 0: generate requirements.txt @@ -142,10 +142,10 @@ RUN \ libwebp7 \ xmlsec1 \ libjemalloc2 \ - libicu \ | grep '^\w' > /tmp/pkg-list && \ for arch in arm64 amd64; do \ mkdir -p /tmp/debs-${arch} && \ + chown _apt:root /tmp/debs-${arch} && \ cd /tmp/debs-${arch} && \ apt-get -o APT::Architecture="${arch}" download $(cat /tmp/pkg-list); \ done @@ -171,24 +171,37 @@ FROM docker.io/library/python:${PYTHON_VERSION}-slim-${DEBIAN_VERSION} ARG TARGETARCH -LABEL org.opencontainers.image.url='https://matrix.org/docs/projects/server/synapse' -LABEL org.opencontainers.image.documentation='https://github.com/element-hq/synapse/blob/master/docker/README.md' -LABEL org.opencontainers.image.source='https://github.com/element-hq/synapse.git' -LABEL org.opencontainers.image.licenses='AGPL-3.0-or-later' +# If specified, Synapse will use this as the version string in the app. +# +# This can be useful to capture the git info of the build as `.git/` won't be +# available in the Docker image for Synapse to generate from. +ARG SYNAPSE_VERSION_STRING +# Pass it through to Synapse as an environment variable. +ENV SYNAPSE_VERSION_STRING=${SYNAPSE_VERSION_STRING} + +LABEL org.opencontainers.image.url='https://github.com/element-hq/synapse' +LABEL org.opencontainers.image.documentation='https://element-hq.github.io/synapse/latest/' +LABEL org.opencontainers.image.source='https://github.com/element-hq/synapse.git' +LABEL org.opencontainers.image.licenses='AGPL-3.0-or-later OR LicenseRef-Element-Commercial' -# On the runtime image, /lib is a symlink to /usr/lib, so we need to copy the -# libraries to the right place, else the `COPY` won't work. -# On amd64, we'll also have a /lib64 folder with ld-linux-x86-64.so.2, which is -# already present in the runtime image. -COPY --from=runtime-deps /install-${TARGETARCH}/lib /usr/lib COPY --from=runtime-deps /install-${TARGETARCH}/etc /etc COPY --from=runtime-deps /install-${TARGETARCH}/usr /usr COPY --from=runtime-deps /install-${TARGETARCH}/var /var -COPY --from=builder /install /usr/local + +# Copy the installed python packages from the builder stage. +# +# uv will generate a `.lock` file when installing packages, which we don't want +# to copy to the final image. +COPY --from=builder --exclude=.lock /install /usr/local COPY ./docker/start.py /start.py COPY ./docker/conf /conf -EXPOSE 8008/tcp 8009/tcp 8448/tcp +# 8008: CS Matrix API port from Synapse +# 8448: SS Matrix API port from Synapse +EXPOSE 8008/tcp 8448/tcp +# 19090: Metrics listener port for the main process (metrics must be enabled with +# SYNAPSE_ENABLE_METRICS=1). +EXPOSE 19090/tcp ENTRYPOINT ["/start.py"] diff --git a/docker/Dockerfile-workers b/docker/Dockerfile-workers index 6d0fc1440b..52dacad65a 100644 --- a/docker/Dockerfile-workers +++ b/docker/Dockerfile-workers @@ -1,9 +1,10 @@ -# syntax=docker/dockerfile:1 +# syntax=docker/dockerfile:1-labs ARG SYNAPSE_VERSION=latest ARG FROM=matrixdotorg/synapse:$SYNAPSE_VERSION -ARG DEBIAN_VERSION=bookworm -ARG PYTHON_VERSION=3.12 +ARG DEBIAN_VERSION=trixie +ARG PYTHON_VERSION=3.13 +ARG REDIS_VERSION=7.2 # first of all, we create a base image with dependencies which we can copy into the # target image. For repeated rebuilds, this is much faster than apt installing @@ -11,15 +12,27 @@ ARG PYTHON_VERSION=3.12 FROM ghcr.io/astral-sh/uv:python${PYTHON_VERSION}-${DEBIAN_VERSION} AS deps_base + ARG DEBIAN_VERSION + ARG REDIS_VERSION + # Tell apt to keep downloaded package files, as we're using cache mounts. RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache + # The upstream redis-server deb has fewer dynamic libraries than Debian's package which makes it easier to copy later on + RUN \ + curl -fsSL https://packages.redis.io/gpg | gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg && \ + chmod 644 /usr/share/keyrings/redis-archive-keyring.gpg && \ + echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb ${DEBIAN_VERSION} main" | tee /etc/apt/sources.list.d/redis.list + RUN \ --mount=type=cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,target=/var/lib/apt,sharing=locked \ apt-get update -qq && \ DEBIAN_FRONTEND=noninteractive apt-get install -yqq --no-install-recommends \ - nginx-light + nginx-light \ + redis-server="6:${REDIS_VERSION}.*" redis-tools="6:${REDIS_VERSION}.*" \ + # libicu is required by postgres, see `docker/complement/Dockerfile` + libicu76 RUN \ # remove default page @@ -35,19 +48,12 @@ FROM ghcr.io/astral-sh/uv:python${PYTHON_VERSION}-${DEBIAN_VERSION} AS deps_base RUN mkdir -p /uv/etc/supervisor/conf.d -# Similarly, a base to copy the redis server from. -# -# The redis docker image has fewer dynamic libraries than the debian package, -# which makes it much easier to copy (but we need to make sure we use an image -# based on the same debian version as the synapse image, to make sure we get -# the expected version of libc. -FROM docker.io/library/redis:7-${DEBIAN_VERSION} AS redis_base - # now build the final image, based on the the regular Synapse docker image FROM $FROM # Copy over dependencies - COPY --from=redis_base /usr/local/bin/redis-server /usr/local/bin + COPY --from=deps_base --parents /usr/lib/*-linux-gnu/libicu* / + COPY --from=deps_base /usr/bin/redis-server /usr/local/bin COPY --from=deps_base /uv / COPY --from=deps_base /usr/sbin/nginx /usr/sbin COPY --from=deps_base /usr/share/nginx /usr/share/nginx @@ -65,6 +71,15 @@ FROM $FROM # Expose nginx listener port EXPOSE 8080/tcp + # Metrics for workers are on ports starting from 19091 but since these are dynamic + # we don't expose them by default (metrics must be enabled with + # SYNAPSE_ENABLE_METRICS=1) + # + # Instead, we expose a single port used for Prometheus HTTP service discovery + # (`http://:9469/metrics/service_discovery`) and proxy all of the + # workers' metrics endpoints through that + # (`http://:9469/metrics/worker/`). + EXPOSE 9469/tcp # A script to read environment variables and create the necessary # files to run the desired worker configuration. Will start supervisord. diff --git a/docker/README-testing.md b/docker/README-testing.md index db88598b8c..8ce7dffc33 100644 --- a/docker/README-testing.md +++ b/docker/README-testing.md @@ -12,11 +12,9 @@ Note that running Synapse's unit tests from within the docker image is not suppo `scripts-dev/complement.sh` is a script that will automatically build and run Synapse against Complement. -Consult the [contributing guide][guideComplementSh] for instructions on how to use it. +Consult our [Complement docs][https://github.com/element-hq/synapse/tree/develop/complement] for instructions on how to use it. -[guideComplementSh]: https://element-hq.github.io/synapse/latest/development/contributing_guide.html#run-the-integration-tests-complement - ## Building and running the images manually Under some circumstances, you may wish to build the images manually. @@ -31,23 +29,23 @@ release of Synapse, instead of your current checkout, you can skip this step. Fr root of the repository: ```sh -docker build -t matrixdotorg/synapse -f docker/Dockerfile . +docker build -t localhost/synapse -f docker/Dockerfile . ``` Next, build the workerised Synapse docker image, which is a layer over the base image. ```sh -docker build -t matrixdotorg/synapse-workers -f docker/Dockerfile-workers . +docker build -t localhost/synapse-workers --build-arg FROM=localhost/synapse -f docker/Dockerfile-workers . ``` Finally, build the multi-purpose image for Complement, which is a layer over the workers image. ```sh -docker build -t complement-synapse -f docker/complement/Dockerfile docker/complement +docker build -t localhost/complement-synapse -f docker/complement/Dockerfile --build-arg FROM=localhost/synapse-workers docker/complement ``` -This will build an image with the tag `complement-synapse`, which can be handed to +This will build an image with the tag `localhost/complement-synapse`, which can be handed to Complement for testing via the `COMPLEMENT_BASE_IMAGE` environment variable. Refer to [Complement's documentation](https://github.com/matrix-org/complement/#running) for how to run the tests, as well as the various available command line flags. @@ -135,3 +133,49 @@ but it does not serve TLS by default. You can configure `SYNAPSE_TLS_CERT` and `SYNAPSE_TLS_KEY` to point to a TLS certificate and key (respectively), both in PEM (textual) format. In this case, Nginx will additionally serve using HTTPS on port 8448. + + +### Metrics + +Set `SYNAPSE_ENABLE_METRICS=1` to configure `enable_metrics: true` and setup the +`metrics` listener on the main and worker processes. Defaults to `0` (disabled). The +main process will listen on port `19090` and workers on port `19091 + `. + +When using `docker/Dockerfile-workers`, to ease the complexity with the metrics setup, +we also have a [Prometheus HTTP service +discovery](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#http_sd_config) +endpoint available at `http://:9469/metrics/service_discovery`. + +The metrics from each worker can also be accessed via +`http://:9469/metrics/worker/` which is what the service +discovery response points to behind the scenes. This way, you only need to expose a +single port (9469) to access all metrics. + +```yaml +global: + scrape_interval: 15s + scrape_timeout: 15s + evaluation_interval: 15s + +scrape_configs: + - job_name: synapse + scrape_interval: 15s + metrics_path: /_synapse/metrics + scheme: http + # We set `honor_labels` so that each service can set their own `job`/`instance` label + # + # > honor_labels controls how Prometheus handles conflicts between labels that are + # > already present in scraped data and labels that Prometheus would attach + # > server-side ("job" and "instance" labels, manually configured target + # > labels, and labels generated by service discovery implementations). + # > + # > *-- https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config* + honor_labels: true + # Use HTTP service discovery + # + # Reference: + # - https://prometheus.io/docs/prometheus/latest/http_sd/ + # - https://prometheus.io/docs/prometheus/latest/configuration/configuration/#http_sd_config + http_sd_configs: + - url: 'http://localhost:9469/metrics/service_discovery' +``` diff --git a/docker/README.md b/docker/README.md index 3438e9c441..ed5155f541 100644 --- a/docker/README.md +++ b/docker/README.md @@ -75,6 +75,9 @@ The following environment variables are supported in `generate` mode: particularly tricky. * `SYNAPSE_LOG_TESTING`: if set, Synapse will log additional information useful for testing. +* `SYNAPSE_ENABLE_METRICS`: if set to `1`, the metrics listener will be enabled on the + main and worker processes. Defaults to `0` (disabled). The main process will listen on + port `19090` and workers on port `19091 + `. ## Postgres diff --git a/docker/complement/Dockerfile b/docker/complement/Dockerfile index 6ed084fe5d..ec4bca232c 100644 --- a/docker/complement/Dockerfile +++ b/docker/complement/Dockerfile @@ -9,24 +9,24 @@ ARG SYNAPSE_VERSION=latest # This is an intermediate image, to be built locally (not pulled from a registry). ARG FROM=matrixdotorg/synapse-workers:$SYNAPSE_VERSION -ARG DEBIAN_VERSION=bookworm +ARG DEBIAN_VERSION=trixie -FROM docker.io/library/postgres:13-${DEBIAN_VERSION} AS postgres_base +FROM docker.io/library/postgres:14-${DEBIAN_VERSION} AS postgres_base FROM $FROM # First of all, we copy postgres server from the official postgres image, # since for repeated rebuilds, this is much faster than apt installing # postgres each time. -# This trick only works because (a) the Synapse image happens to have all the -# shared libraries that postgres wants, (b) we use a postgres image based on -# the same debian version as Synapse's docker image (so the versions of the -# shared libraries match). +# This trick only works because we use a postgres image based on the same +# debian version as Synapse's docker image (so the versions of the shared +# libraries match). Any missing libraries need to be added to either the +# Synapse image or docker/Dockerfile-workers. RUN adduser --system --uid 999 postgres --home /var/lib/postgresql COPY --from=postgres_base /usr/lib/postgresql /usr/lib/postgresql COPY --from=postgres_base /usr/share/postgresql /usr/share/postgresql COPY --from=postgres_base --chown=postgres /var/run/postgresql /var/run/postgresql -ENV PATH="${PATH}:/usr/lib/postgresql/13/bin" +ENV PATH="${PATH}:/usr/lib/postgresql/14/bin" ENV PGDATA=/var/lib/postgresql/data # We also initialize the database at build time, rather than runtime, so that it's faster to spin up the image. diff --git a/docker/complement/conf/start_for_complement.sh b/docker/complement/conf/start_for_complement.sh index da1b26a283..e0d30abed3 100755 --- a/docker/complement/conf/start_for_complement.sh +++ b/docker/complement/conf/start_for_complement.sh @@ -128,6 +128,10 @@ openssl x509 -req -in /conf/server.tls.csr \ export SYNAPSE_TLS_CERT=/conf/server.tls.crt export SYNAPSE_TLS_KEY=/conf/server.tls.key +# Add a directory for tests to add config overrides if they want +mkdir --parents /conf/homeserver.d +export _SYNAPSE_COMPLEMENT_EXTRA_CONFIG_DIR=/conf/homeserver.d + # Run the script that writes the necessary config files and starts supervisord, which in turn # starts everything else exec /configure_workers_and_start.py "$@" diff --git a/docker/complement/conf/workers-shared-extra.yaml.j2 b/docker/complement/conf/workers-shared-extra.yaml.j2 index 168c385191..9fd7fc954a 100644 --- a/docker/complement/conf/workers-shared-extra.yaml.j2 +++ b/docker/complement/conf/workers-shared-extra.yaml.j2 @@ -102,6 +102,10 @@ rc_room_creation: per_second: 9999 burst_count: 9999 +rc_user_directory: + per_second: 9999 + burst_count: 9999 + federation_rr_transactions_per_room_per_second: 9999 allow_device_name_lookup_over_federation: true @@ -133,6 +137,12 @@ experimental_features: msc3984_appservice_key_query: true # Invite filtering msc4155_enabled: true + # Thread Subscriptions + msc4306_enabled: true + # Sticky Events + msc4354_enabled: true + # `/sync` `state_after` + msc4222_enabled: true server_notices: system_mxid_localpart: _server diff --git a/docker/conf-workers/nginx.conf.j2 b/docker/conf-workers/nginx.conf.j2 index 95d2f760d2..3d5e02c28c 100644 --- a/docker/conf-workers/nginx.conf.j2 +++ b/docker/conf-workers/nginx.conf.j2 @@ -48,3 +48,5 @@ server { proxy_set_header Host $host:$server_port; } } + +{{ nginx_prometheus_metrics_service_discovery }} diff --git a/docker/conf-workers/shared.yaml.j2 b/docker/conf-workers/shared.yaml.j2 index 1dfc60ad11..6efbd05472 100644 --- a/docker/conf-workers/shared.yaml.j2 +++ b/docker/conf-workers/shared.yaml.j2 @@ -20,4 +20,9 @@ app_service_config_files: {%- endfor %} {%- endif %} +{# Controlled by SYNAPSE_ENABLE_METRICS #} +{% if enable_metrics %} +enable_metrics: true +{% endif %} + {{ shared_worker_config }} diff --git a/docker/conf-workers/synapse.supervisord.conf.j2 b/docker/conf-workers/synapse.supervisord.conf.j2 index 4fb11b259e..9388b1ff0e 100644 --- a/docker/conf-workers/synapse.supervisord.conf.j2 +++ b/docker/conf-workers/synapse.supervisord.conf.j2 @@ -5,10 +5,16 @@ command=/usr/local/bin/python -m synapse.app.complement_fork_starter {{ main_config_path }} synapse.app.homeserver --config-path="{{ main_config_path }}" + {%- if extra_config_dir %} + --config-path="{{ extra_config_dir }}" + {%- endif %} --config-path=/conf/workers/shared.yaml {%- for worker in workers %} -- {{ worker.app }} --config-path="{{ main_config_path }}" + {%- if extra_config_dir %} + --config-path="{{ extra_config_dir }}" + {%- endif %} --config-path=/conf/workers/shared.yaml --config-path=/conf/workers/{{ worker.name }}.yaml {%- endfor %} @@ -24,6 +30,9 @@ exitcodes=0 environment=http_proxy="%(ENV_SYNAPSE_HTTP_PROXY)s",https_proxy="%(ENV_SYNAPSE_HTTPS_PROXY)s",no_proxy="%(ENV_SYNAPSE_NO_PROXY)s" command=/usr/local/bin/prefix-log /usr/local/bin/python -m synapse.app.homeserver --config-path="{{ main_config_path }}" + {%- if extra_config_dir %} + --config-path="{{ extra_config_dir }}" + {%- endif %} --config-path=/conf/workers/shared.yaml priority=10 # Log startup failures to supervisord's stdout/err diff --git a/docker/conf-workers/worker.yaml.j2 b/docker/conf-workers/worker.yaml.j2 index 29ec74b4ea..d4d2d4d4cf 100644 --- a/docker/conf-workers/worker.yaml.j2 +++ b/docker/conf-workers/worker.yaml.j2 @@ -21,6 +21,14 @@ worker_listeners: {%- endfor %} {% endif %} +{# Controlled by SYNAPSE_ENABLE_METRICS #} +{% if metrics_port %} + - type: metrics + # Prometheus does not support Unix sockets so we don't bother with + # `SYNAPSE_USE_UNIX_SOCKET`, https://github.com/prometheus/prometheus/issues/12024 + port: {{ metrics_port }} +{% endif %} + worker_log_config: {{ worker_log_config_filepath }} {{ worker_extra_conf }} diff --git a/docker/conf/homeserver.yaml b/docker/conf/homeserver.yaml index 2890990705..e2e1338673 100644 --- a/docker/conf/homeserver.yaml +++ b/docker/conf/homeserver.yaml @@ -53,6 +53,15 @@ listeners: - names: [federation] compress: false +{% if SYNAPSE_ENABLE_METRICS %} + - type: metrics + # The main process always uses the same port 19090 + # + # Prometheus does not support Unix sockets so we don't bother with + # `SYNAPSE_USE_UNIX_SOCKET`, https://github.com/prometheus/prometheus/issues/12024 + port: 19090 +{% endif %} + ## Database ## {% if POSTGRES_PASSWORD %} diff --git a/docker/conf/log.config b/docker/conf/log.config index 5772321202..6fe7db66da 100644 --- a/docker/conf/log.config +++ b/docker/conf/log.config @@ -77,6 +77,13 @@ loggers: #} synapse.visibility.filtered_event_debug: level: DEBUG + + {# + If Synapse is under test, we don't care about seeing the "Applying schema" log + lines at the INFO level every time we run the tests (it's 100 lines of bulk) + #} + synapse.storage.prepare_database: + level: WARN {% endif %} root: diff --git a/docker/configure_workers_and_start.py b/docker/configure_workers_and_start.py index 6f25653bb7..1b8d4f9989 100755 --- a/docker/configure_workers_and_start.py +++ b/docker/configure_workers_and_start.py @@ -49,11 +49,16 @@ # regardless of the SYNAPSE_LOG_LEVEL setting. # * SYNAPSE_LOG_TESTING: if set, Synapse will log additional information useful # for testing. +# * SYNAPSE_USE_UNIX_SOCKET: TODO +# * `SYNAPSE_ENABLE_METRICS`: if set to `1`, the metrics listener will be enabled on the +# main and worker processes. Defaults to `0` (disabled). The main process will listen on +# port `19090` and workers on port `19091 + `. # # NOTE: According to Complement's ENTRYPOINT expectations for a homeserver image (as defined # in the project's README), this script may be run multiple times, and functionality should # continue to work if so. +import json import os import platform import re @@ -65,16 +70,13 @@ from itertools import chain from pathlib import Path from typing import ( Any, - Dict, - List, Mapping, MutableMapping, NoReturn, - Optional, - Set, SupportsIndex, ) +import attr import yaml from jinja2 import Environment, FileSystemLoader @@ -96,7 +98,7 @@ WORKER_PLACEHOLDER_NAME = "placeholder_name" # Watching /_matrix/media and related needs a "media" listener # Stream Writers require "client" and "replication" listeners because they # have to attach by instance_map to the master process and have client endpoints. -WORKERS_CONFIG: Dict[str, Dict[str, Any]] = { +WORKERS_CONFIG: dict[str, dict[str, Any]] = { "pusher": { "app": "synapse.app.generic_worker", "listener_resources": [], @@ -200,6 +202,7 @@ WORKERS_CONFIG: Dict[str, Dict[str, Any]] = { "^/_matrix/client/(api/v1|r0|v3|unstable)/keys/upload", "^/_matrix/client/(api/v1|r0|v3|unstable)/keys/device_signing/upload$", "^/_matrix/client/(api/v1|r0|v3|unstable)/keys/signatures/upload$", + "^/_matrix/client/unstable/org.matrix.msc4140/delayed_events(/.*/restart)?$", ], "shared_extra_conf": {}, "worker_extra_conf": "", @@ -340,7 +343,7 @@ WORKERS_CONFIG: Dict[str, Dict[str, Any]] = { } # Templates for sections that may be inserted multiple times in config files -NGINX_LOCATION_CONFIG_BLOCK = """ +NGINX_LOCATION_REGEX_CONFIG_BLOCK = """ location ~* {endpoint} {{ proxy_pass {upstream}; proxy_set_header X-Forwarded-For $remote_addr; @@ -349,6 +352,25 @@ NGINX_LOCATION_CONFIG_BLOCK = """ }} """ +# Having both **regex** (`NGINX_LOCATION_REGEX_CONFIG_BLOCK`) match vs **exact** +# (`NGINX_LOCATION_EXACT_CONFIG_BLOCK`) match is necessary because we can't use a URI +# path in `proxy_pass http://localhost:19090/_synapse/metrics` with the regex version. +# +# Example of what happens if you try to use `proxy_pass http://localhost:19090/_synapse/metrics` +# with `NGINX_LOCATION_REGEX_CONFIG_BLOCK`: +# ``` +# nginx | 2025/12/31 22:58:34 [emerg] 21#21: "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block in /etc/nginx/conf.d/matrix-synapse.conf:732 +# ``` +NGINX_LOCATION_EXACT_CONFIG_BLOCK = """ + location = {endpoint} {{ + proxy_pass {upstream}; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $host; + }} +""" + + NGINX_UPSTREAM_CONFIG_BLOCK = """ upstream {upstream_worker_base_name} {{ {body} @@ -356,6 +378,63 @@ upstream {upstream_worker_base_name} {{ """ +PROMETHEUS_METRICS_SERVICE_DISCOVERY_FILE_PATH = ( + "/data/prometheus_service_discovery.json" +) +""" +We serve this file with nginx so people can use it with `http_sd_config` in their +Prometheus config. +""" + +NGINX_HOST_PLACEHOLDER = "" +"""Will be replaced with the whatever hostname:port used to access the nginx metrics endpoint.""" + +NGINX_PROMETHEUS_METRICS_SERVICE_DISCOVERY = """ +server {{ + listen 9469; + location = /metrics/service_discovery {{ + alias {service_discovery_file_path}; + default_type application/json; + + # Find/replace the host placeholder in the response body with the actual + # host used to access this endpoint. + # + # We want to reflect back whatever host the client used to access this file. + # For example, if they accessed it via `localhost:9469`, then they + # can also reach all of the proxied metrics endpoints at the same address. + # Or if it's Prometheus in another container, it will access this via + # `host.docker.internal:9469`, etc. Or perhaps it's even some randomly assigned + # port mapping. + sub_filter '{host_placeholder}' '$http_host'; + # By default, `ngx_http_sub_module` only works on `text/html` responses. We want + # to find/replace in `application/JSON`. + sub_filter_types application/json; + # Replace all occurences + sub_filter_once off; + }} + + # Make the service discovery endpoint easy to find; redirect to the correct spot. + location = / {{ + return 302 /metrics/service_discovery; + }} + + {metrics_proxy_locations} +}} +""" +""" +Setup the nginx config necessary to serve the JSON file for Prometheus HTTP service discovery +(`http_sd_config`). Served at `/metrics/service_discovery`. + +Reference: + - https://prometheus.io/docs/prometheus/latest/http_sd/ + - https://prometheus.io/docs/prometheus/latest/configuration/configuration/#http_sd_config + +We also proxy all of the Synapse metrics endpoints through a central place so that +people only need to expose the single 9469 port and service discovery can take care of +the rest: `/metrics/worker/` -> http://localhost:19090/_synapse/metrics +""" + + # Utility functions def log(txt: str) -> None: print(txt) @@ -408,7 +487,7 @@ def convert(src: str, dst: str, **template_vars: object) -> None: def add_worker_roles_to_shared_config( shared_config: dict, - worker_types_set: Set[str], + worker_types_set: set[str], worker_name: str, worker_port: int, ) -> None: @@ -471,9 +550,9 @@ def add_worker_roles_to_shared_config( def merge_worker_template_configs( - existing_dict: Optional[Dict[str, Any]], - to_be_merged_dict: Dict[str, Any], -) -> Dict[str, Any]: + existing_dict: dict[str, Any] | None, + to_be_merged_dict: dict[str, Any], +) -> dict[str, Any]: """When given an existing dict of worker template configuration consisting with both dicts and lists, merge new template data from WORKERS_CONFIG(or create) and return new dict. @@ -484,7 +563,7 @@ def merge_worker_template_configs( existing_dict. Returns: The newly merged together dict values. """ - new_dict: Dict[str, Any] = {} + new_dict: dict[str, Any] = {} if not existing_dict: # It doesn't exist yet, just use the new dict(but take a copy not a reference) new_dict = to_be_merged_dict.copy() @@ -509,8 +588,8 @@ def merge_worker_template_configs( def insert_worker_name_for_worker_config( - existing_dict: Dict[str, Any], worker_name: str -) -> Dict[str, Any]: + existing_dict: dict[str, Any], worker_name: str +) -> dict[str, Any]: """Insert a given worker name into the worker's configuration dict. Args: @@ -526,7 +605,7 @@ def insert_worker_name_for_worker_config( return dict_to_edit -def apply_requested_multiplier_for_worker(worker_types: List[str]) -> List[str]: +def apply_requested_multiplier_for_worker(worker_types: list[str]) -> list[str]: """ Apply multiplier(if found) by returning a new expanded list with some basic error checking. @@ -587,7 +666,7 @@ def is_sharding_allowed_for_worker_type(worker_type: str) -> bool: def split_and_strip_string( given_string: str, split_char: str, max_split: SupportsIndex = -1 -) -> List[str]: +) -> list[str]: """ Helper to split a string on split_char and strip whitespace from each end of each element. @@ -615,9 +694,42 @@ def generate_base_homeserver_config() -> None: subprocess.run([sys.executable, "/start.py", "migrate_config"], check=True) +@attr.s(auto_attribs=True) +class Worker: + worker_name: str + """ + ex. + `event_persister:2` -> `event_persister1` and `event_persister2` + `stream_writers=account_data+presence+receipts+to_device+typing"` -> `stream_writers` + """ + + worker_base_name: str + """ + ex. + `event_persister:2` -> `event_persister` + `stream_writers=account_data+presence+receipts+to_device+typing"` -> `stream_writers` + """ + + worker_index: int + """ + The index of the worker starting from 1 for each worker type requested. + + ex. + `event_persister:2` -> `1` and `2` + `stream_writers=account_data+presence+receipts+to_device+typing"` -> `1` + """ + + worker_types: set[str] + """ + ex. + `event_persister:2` -> `{"event_persister"}` + `stream_writers=account_data+presence+receipts+to_device+typing"` -> `{"account_data", "presence", "receipts","to_device", "typing"} + """ + + def parse_worker_types( - requested_worker_types: List[str], -) -> Dict[str, Set[str]]: + requested_worker_types: list[str], +) -> list[Worker]: """Read the desired list of requested workers and prepare the data for use in generating worker config files while also checking for potential gotchas. @@ -625,22 +737,19 @@ def parse_worker_types( requested_worker_types: The list formed from the split environment variable containing the unprocessed requests for workers. - Returns: A dict of worker names to set of worker types. Format: - {'worker_name': - {'worker_type', 'worker_type2'} - } + Returns: A list of requested workers """ # A counter of worker_base_name -> int. Used for determining the name for a given # worker when generating its config file, as each worker's name is just # worker_base_name followed by instance number - worker_base_name_counter: Dict[str, int] = defaultdict(int) + worker_base_name_counter: dict[str, int] = defaultdict(int) # Similar to above, but more finely grained. This is used to determine we don't have # more than a single worker for cases where multiples would be bad(e.g. presence). - worker_type_shard_counter: Dict[str, int] = defaultdict(int) + worker_type_shard_counter: dict[str, int] = defaultdict(int) - # The final result of all this processing - dict_to_return: Dict[str, Set[str]] = {} + # Map from worker name to `Worker` + worker_dict: dict[str, Worker] = {} # Handle any multipliers requested for given workers. multiple_processed_worker_types = apply_requested_multiplier_for_worker( @@ -684,7 +793,7 @@ def parse_worker_types( # Split the worker_type_string on "+", remove whitespace from ends then make # the list a set so it's deduplicated. - worker_types_set: Set[str] = set( + worker_types_set: set[str] = set( split_and_strip_string(worker_type_string, "+") ) @@ -726,24 +835,30 @@ def parse_worker_types( if worker_number > 1: # If this isn't the first worker, check that we don't have a confusing # mixture of worker types with the same base name. - first_worker_with_base_name = dict_to_return[f"{worker_base_name}1"] - if first_worker_with_base_name != worker_types_set: + first_worker_with_base_name = worker_dict[f"{worker_base_name}1"] + if first_worker_with_base_name.worker_types != worker_types_set: error( f"Can not use worker_name: '{worker_name}' for worker_type(s): " f"{worker_types_set!r}. It is already in use by " - f"worker_type(s): {first_worker_with_base_name!r}" + f"worker_type(s): {first_worker_with_base_name.worker_types!r}" ) - dict_to_return[worker_name] = worker_types_set + worker_dict[worker_name] = Worker( + worker_name=worker_name, + worker_base_name=worker_base_name, + worker_index=worker_number, + worker_types=worker_types_set, + ) - return dict_to_return + return list(worker_dict.values()) def generate_worker_files( environ: Mapping[str, str], config_path: str, + extra_config_dir: str | None, data_dir: str, - requested_worker_types: Dict[str, Set[str]], + requested_workers: list[Worker], ) -> None: """Read the desired workers(if any) that is passed in and generate shared homeserver, nginx and supervisord configs. @@ -751,20 +866,23 @@ def generate_worker_files( Args: environ: os.environ instance. config_path: The location of the generated Synapse main worker config file. + extra_config_dir: A directory in which extra Synapse configuration files will be loaded. data_dir: The location of the synapse data directory. Where log and user-facing config files live. - requested_worker_types: A Dict containing requested workers in the format of - {'worker_name1': {'worker_type', ...}} + requested_workers: A list of requested workers """ # Note that yaml cares about indentation, so care should be taken to insert lines # into files at the correct indentation below. # Convenience helper for if using unix sockets instead of host:port using_unix_sockets = environ.get("SYNAPSE_USE_UNIX_SOCKET", False) + + enable_metrics = environ.get("SYNAPSE_ENABLE_METRICS", "0") == "1" + # First read the original config file and extract the listeners block. Then we'll # add another listener for replication. Later we'll write out the result to the # shared config file. - listeners: List[Any] + listeners: list[Any] if using_unix_sockets: listeners = [ { @@ -792,12 +910,16 @@ def generate_worker_files( # base shared worker jinja2 template. This config file will be passed to all # workers, included Synapse's main process. It is intended mainly for disabling # functionality when certain workers are spun up, and adding a replication listener. - shared_config: Dict[str, Any] = {"listeners": listeners} + shared_config: dict[str, Any] = { + "listeners": listeners, + # Controls `enable_metrics: true` + "enable_metrics": enable_metrics, + } # List of dicts that describe workers. # We pass this to the Supervisor template later to generate the appropriate # program blocks. - worker_descriptors: List[Dict[str, Any]] = [] + worker_descriptors: list[dict[str, Any]] = [] # Upstreams for load-balancing purposes. This dict takes the form of the worker # type to the ports of each worker. For example: @@ -805,20 +927,22 @@ def generate_worker_files( # worker_type: {1234, 1235, ...}} # } # and will be used to construct 'upstream' nginx directives. - nginx_upstreams: Dict[str, Set[int]] = {} + nginx_upstreams: dict[str, set[int]] = {} # A map of: {"endpoint": "upstream"}, where "upstream" is a str representing what # will be placed after the proxy_pass directive. The main benefit to representing # this data as a dict over a str is that we can easily deduplicate endpoints # across multiple instances of the same worker. The final rendering will be combined # with nginx_upstreams and placed in /etc/nginx/conf.d. - nginx_locations: Dict[str, str] = {} + nginx_locations: dict[str, str] = {} # Create the worker configuration directory if it doesn't already exist os.makedirs("/conf/workers", exist_ok=True) # Start worker ports from this arbitrary port worker_port = 18009 + # The main process metrics port is 19090, so start workers from 19091 + worker_metrics_port = 19091 # A list of internal endpoints to healthcheck, starting with the main process # which exists even if no workers do. @@ -835,7 +959,9 @@ def generate_worker_files( healthcheck_urls = ["http://localhost:8080/health"] # Get the set of all worker types that we have configured - all_worker_types_in_use = set(chain(*requested_worker_types.values())) + all_worker_types_in_use = set( + chain(*[worker.worker_types for worker in requested_workers]) + ) # Map locations to upstreams (corresponding to worker types) in Nginx # but only if we use the appropriate worker type for worker_type in all_worker_types_in_use: @@ -844,12 +970,13 @@ def generate_worker_files( # For each worker type specified by the user, create config values and write it's # yaml config file - for worker_name, worker_types_set in requested_worker_types.items(): + worker_name_to_metrics_port_map: dict[str, int] = {} + for worker in requested_workers: # The collected and processed data will live here. - worker_config: Dict[str, Any] = {} + worker_config: dict[str, Any] = {} # Merge all worker config templates for this worker into a single config - for worker_type in worker_types_set: + for worker_type in worker.worker_types: copy_of_template_config = WORKERS_CONFIG[worker_type].copy() # Merge worker type template configuration data. It's a combination of lists @@ -859,16 +986,27 @@ def generate_worker_files( ) # Replace placeholder names in the config template with the actual worker name. - worker_config = insert_worker_name_for_worker_config(worker_config, worker_name) - - worker_config.update( - {"name": worker_name, "port": str(worker_port), "config_path": config_path} + worker_config = insert_worker_name_for_worker_config( + worker_config, worker.worker_name ) - # Update the shared config with any worker_type specific options. The first of a - # given worker_type needs to stay assigned and not be replaced. - worker_config["shared_extra_conf"].update(shared_config) - shared_config = worker_config["shared_extra_conf"] + worker_config.update( + { + "name": worker.worker_name, + "port": str(worker_port), + "config_path": config_path, + } + ) + + # Keep the `shared_config` up to date with the `shared_extra_conf` from each + # worker. + shared_config = { + **worker_config["shared_extra_conf"], + # We combine `shared_config` second to avoid overwriting existing keys just + # for sanity sake (always use the first worker). + **shared_config, + } + if using_unix_sockets: healthcheck_urls.append( f"--unix-socket /run/worker.{worker_port} http://localhost/health" @@ -880,39 +1018,51 @@ def generate_worker_files( # the `events` stream. For other workers, the worker name is the same # name of the stream they write to, but for some reason it is not the # case for event_persister. - if "event_persister" in worker_types_set: - worker_types_set.add("events") + if "event_persister" in worker.worker_types: + worker.worker_types.add("events") # Update the shared config with sharding-related options if necessary add_worker_roles_to_shared_config( - shared_config, worker_types_set, worker_name, worker_port + shared_config, worker.worker_types, worker.worker_name, worker_port ) # Enable the worker in supervisord worker_descriptors.append(worker_config) # Write out the worker's logging config file - log_config_filepath = generate_worker_log_config(environ, worker_name, data_dir) + log_config_filepath = generate_worker_log_config( + environ, worker.worker_name, data_dir + ) + + worker_name_to_metrics_port_map[worker.worker_name] = worker_metrics_port + if enable_metrics: + # Enable prometheus metrics endpoint on this worker + worker_config["metrics_port"] = worker_metrics_port + + if enable_metrics: + # Enable prometheus metrics endpoint on this worker + worker_config["metrics_port"] = worker_metrics_port # Then a worker config file convert( "/conf/worker.yaml.j2", - f"/conf/workers/{worker_name}.yaml", + f"/conf/workers/{worker.worker_name}.yaml", **worker_config, worker_log_config_filepath=log_config_filepath, using_unix_sockets=using_unix_sockets, ) # Save this worker's port number to the correct nginx upstreams - for worker_type in worker_types_set: + for worker_type in worker.worker_types: nginx_upstreams.setdefault(worker_type, set()).add(worker_port) worker_port += 1 + worker_metrics_port += 1 # Build the nginx location config blocks nginx_location_config = "" for endpoint, upstream in nginx_locations.items(): - nginx_location_config += NGINX_LOCATION_CONFIG_BLOCK.format( + nginx_location_config += NGINX_LOCATION_REGEX_CONFIG_BLOCK.format( endpoint=endpoint, upstream=upstream, ) @@ -935,6 +1085,111 @@ def generate_worker_files( body=body, ) + # Provide a Prometheus metrics service discovery endpoint to easily be able to pick + # up all of the workers + nginx_prometheus_metrics_service_discovery = "" + if enable_metrics: + # Write JSON file for Prometheus service discovery pointing to all of the + # workers. We serve this file with nginx so people can use it with + # `http_sd_config` in their Prometheus config. + # + # > It fetches targets from an HTTP endpoint containing a list of zero or more + # > ``s. The target must reply with an HTTP 200 response. The HTTP + # > header `Content-Type` must be `application/json`, and the body must be valid + # > JSON. + # > + # > *-- https://prometheus.io/docs/prometheus/latest/configuration/configuration/#http_sd_config* + # + # Another reference: https://prometheus.io/docs/prometheus/latest/http_sd/ + prometheus_http_service_discovery_content = [ + { + "targets": [NGINX_HOST_PLACEHOLDER], + "labels": { + # The downstream user should also configure `honor_labels: true` in + # their Prometheus config to prevent Prometheus from overwriting the + # `job` labels. + # + # > honor_labels controls how Prometheus handles conflicts between labels that are + # > already present in scraped data and labels that Prometheus would attach + # > server-side ("job" and "instance" labels, manually configured target + # > labels, and labels generated by service discovery implementations). + # > + # > *-- https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config* + # + # Reference: + # - https://prometheus.io/docs/concepts/jobs_instances/ + # - https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config + "job": worker.worker_base_name, + "index": f"{worker.worker_index}", + # This allows us to change the `metrics_path` on a per-target basis. + # We want to grab the metrics from our nginx proxied location (setup + # below). + # + # While there doesn't seem to be official docs on these special + # labels (`__metrics_path__`, `__scheme__`, `__scrape_interval__`, + # `__scrape_timeout__`), this discussion best summarizes how this + # works: https://github.com/prometheus/prometheus/discussions/13217 + "__metrics_path__": f"/metrics/worker/{worker.worker_name}", + }, + } + for worker in requested_workers + ] + # Add the main Synapse process as well + prometheus_http_service_discovery_content.append( + { + "targets": [NGINX_HOST_PLACEHOLDER], + "labels": { + # We use `"synapse"` as the job name for the main process because it + # matches what we expect people to use from a monolith setup with + # their static scrape config. It's `job` name used in our Grafana + # dashboard for the main process. + "job": "synapse", + "index": "1", + "__metrics_path__": "/metrics/worker/main", + }, + } + ) + + # Check to make sure the file doesn't already exist + if os.path.isfile(PROMETHEUS_METRICS_SERVICE_DISCOVERY_FILE_PATH): + error( + f"Prometheus service discovery file " + f"'{PROMETHEUS_METRICS_SERVICE_DISCOVERY_FILE_PATH}' already exists (unexpected)! " + f"This is a problem because the existing file probably doesn't match the " + "Synapse workers we're setting up now." + ) + + # Write the file + with open(PROMETHEUS_METRICS_SERVICE_DISCOVERY_FILE_PATH, "w") as outfile: + outfile.write( + json.dumps(prometheus_http_service_discovery_content, indent=4) + ) + + # Proxy all of the Synapse metrics endpoints through a central place so that + # people only need to expose the single 9469 port and service discovery can take + # care of the rest: `/metrics/worker/` -> + # http://localhost:19090/_synapse/metrics + # + # Build the nginx location config blocks + metrics_proxy_locations = "" + for worker in requested_workers: + metrics_proxy_locations += NGINX_LOCATION_EXACT_CONFIG_BLOCK.format( + endpoint=f"/metrics/worker/{worker.worker_name}", + upstream=f"http://localhost:{worker_name_to_metrics_port_map[worker.worker_name]}/_synapse/metrics", + ) + # Add the main Synapse process as well + metrics_proxy_locations += NGINX_LOCATION_EXACT_CONFIG_BLOCK.format( + endpoint="/metrics/worker/main", + upstream="http://localhost:19090/_synapse/metrics", + ) + + # Add a nginx server/location to serve the JSON file + nginx_prometheus_metrics_service_discovery = NGINX_PROMETHEUS_METRICS_SERVICE_DISCOVERY.format( + service_discovery_file_path=PROMETHEUS_METRICS_SERVICE_DISCOVERY_FILE_PATH, + host_placeholder=NGINX_HOST_PLACEHOLDER, + metrics_proxy_locations=metrics_proxy_locations, + ) + # Finally, we'll write out the config files. # log config for the master process @@ -952,7 +1207,7 @@ def generate_worker_files( if reg_path.suffix.lower() in (".yaml", ".yml") ] - workers_in_use = len(requested_worker_types) > 0 + workers_in_use = len(requested_workers) > 0 # If there are workers, add the main process to the instance_map too. if workers_in_use: @@ -987,6 +1242,7 @@ def generate_worker_files( tls_cert_path=os.environ.get("SYNAPSE_TLS_CERT"), tls_key_path=os.environ.get("SYNAPSE_TLS_KEY"), using_unix_sockets=using_unix_sockets, + nginx_prometheus_metrics_service_discovery=nginx_prometheus_metrics_service_discovery, ) # Supervisord config @@ -1004,6 +1260,7 @@ def generate_worker_files( "/etc/supervisor/conf.d/synapse.conf", workers=worker_descriptors, main_config_path=config_path, + extra_config_dir=extra_config_dir, use_forking_launcher=environ.get("SYNAPSE_USE_EXPERIMENTAL_FORKING_LAUNCHER"), ) @@ -1029,7 +1286,7 @@ def generate_worker_log_config( Returns: the path to the generated file """ # Check whether we should write worker logs to disk, in addition to the console - extra_log_template_args: Dict[str, Optional[str]] = {} + extra_log_template_args: dict[str, str | None] = {} if environ.get("SYNAPSE_WORKERS_WRITE_LOGS_TO_DISK"): extra_log_template_args["LOG_FILE_PATH"] = f"{data_dir}/logs/{worker_name}.log" @@ -1053,7 +1310,7 @@ def generate_worker_log_config( return log_config_filepath -def main(args: List[str], environ: MutableMapping[str, str]) -> None: +def main(args: list[str], environ: MutableMapping[str, str]) -> None: parser = ArgumentParser() parser.add_argument( "--generate-only", @@ -1064,6 +1321,9 @@ def main(args: List[str], environ: MutableMapping[str, str]) -> None: config_dir = environ.get("SYNAPSE_CONFIG_DIR", "/data") config_path = environ.get("SYNAPSE_CONFIG_PATH", config_dir + "/homeserver.yaml") + # All files in this directory will be loaded as `homeserver.yaml` snippets + # Currently only intended for use by Complement + extra_config_dir = environ.get("_SYNAPSE_COMPLEMENT_EXTRA_CONFIG_DIR", None) data_dir = environ.get("SYNAPSE_DATA_DIR", "/data") # override SYNAPSE_NO_TLS, we don't support TLS in worker mode, @@ -1087,15 +1347,21 @@ def main(args: List[str], environ: MutableMapping[str, str]) -> None: if not worker_types_env: # No workers, just the main process worker_types = [] - requested_worker_types: Dict[str, Any] = {} + requested_workers: list[Worker] = [] else: # Split type names by comma, ignoring whitespace. worker_types = split_and_strip_string(worker_types_env, ",") - requested_worker_types = parse_worker_types(worker_types) + requested_workers = parse_worker_types(worker_types) # Always regenerate all other config files log("Generating worker config files") - generate_worker_files(environ, config_path, data_dir, requested_worker_types) + generate_worker_files( + environ=environ, + config_path=config_path, + extra_config_dir=extra_config_dir, + data_dir=data_dir, + requested_workers=requested_workers, + ) # Mark workers as being configured with open(mark_filepath, "w") as f: diff --git a/docker/editable.Dockerfile b/docker/editable.Dockerfile index f18cf6a5d9..b2aff9cb53 100644 --- a/docker/editable.Dockerfile +++ b/docker/editable.Dockerfile @@ -3,14 +3,14 @@ # # Used by `complement.sh`. Not suitable for production use. -ARG PYTHON_VERSION=3.9 +ARG PYTHON_VERSION=3.10 ### ### Stage 0: generate requirements.txt ### -# We hardcode the use of Debian bookworm here because this could change upstream -# and other Dockerfiles used for testing are expecting bookworm. -FROM docker.io/library/python:${PYTHON_VERSION}-slim-bookworm +# We hardcode the use of Debian trixie here because this could change upstream +# and other Dockerfiles used for testing are expecting trixie. +FROM docker.io/library/python:${PYTHON_VERSION}-slim-trixie # Install Rust and other dependencies (stolen from normal Dockerfile) # install the OS build deps diff --git a/docker/start.py b/docker/start.py index 0be9976a0c..19f1ab5075 100755 --- a/docker/start.py +++ b/docker/start.py @@ -6,7 +6,7 @@ import os import platform import subprocess import sys -from typing import Any, Dict, List, Mapping, MutableMapping, NoReturn, Optional +from typing import Any, Mapping, MutableMapping, NoReturn import jinja2 @@ -31,6 +31,25 @@ def flush_buffers() -> None: sys.stderr.flush() +def strtobool(val: str) -> bool: + """Convert a string representation of truth to True or False + + True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values + are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if + 'val' is anything else. + + This is lifted from distutils.util.strtobool, with the exception that it actually + returns a bool, rather than an int. + """ + val = val.lower() + if val in ("y", "yes", "t", "true", "on", "1"): + return True + elif val in ("n", "no", "f", "false", "off", "0"): + return False + else: + raise ValueError("invalid truth value %r" % (val,)) + + def convert(src: str, dst: str, environ: Mapping[str, object]) -> None: """Generate a file from a template @@ -50,7 +69,7 @@ def generate_config_from_template( config_dir: str, config_path: str, os_environ: Mapping[str, str], - ownership: Optional[str], + ownership: str | None, ) -> None: """Generate a homeserver.yaml from environment variables @@ -69,7 +88,7 @@ def generate_config_from_template( ) # populate some params from data files (if they exist, else create new ones) - environ: Dict[str, Any] = dict(os_environ) + environ: dict[str, Any] = dict(os_environ) secrets = { "registration": "SYNAPSE_REGISTRATION_SHARED_SECRET", "macaroon": "SYNAPSE_MACAROON_SECRET_KEY", @@ -98,19 +117,16 @@ def generate_config_from_template( os.mkdir(config_dir) # Convert SYNAPSE_NO_TLS to boolean if exists - if "SYNAPSE_NO_TLS" in environ: - tlsanswerstring = str.lower(environ["SYNAPSE_NO_TLS"]) - if tlsanswerstring in ("true", "on", "1", "yes"): - environ["SYNAPSE_NO_TLS"] = True - else: - if tlsanswerstring in ("false", "off", "0", "no"): - environ["SYNAPSE_NO_TLS"] = False - else: - error( - 'Environment variable "SYNAPSE_NO_TLS" found but value "' - + tlsanswerstring - + '" unrecognized; exiting.' - ) + tlsanswerstring = environ.get("SYNAPSE_NO_TLS") + if tlsanswerstring is not None: + try: + environ["SYNAPSE_NO_TLS"] = strtobool(tlsanswerstring) + except ValueError: + error( + 'Environment variable "SYNAPSE_NO_TLS" found but value "' + + tlsanswerstring + + '" unrecognized; exiting.' + ) if "SYNAPSE_LOG_CONFIG" not in environ: environ["SYNAPSE_LOG_CONFIG"] = config_dir + "/log.config" @@ -147,7 +163,7 @@ def generate_config_from_template( subprocess.run(args, check=True) -def run_generate_config(environ: Mapping[str, str], ownership: Optional[str]) -> None: +def run_generate_config(environ: Mapping[str, str], ownership: str | None) -> None: """Run synapse with a --generate-config param to generate a template config file Args: @@ -164,6 +180,18 @@ def run_generate_config(environ: Mapping[str, str], ownership: Optional[str]) -> config_dir = environ.get("SYNAPSE_CONFIG_DIR", "/data") config_path = environ.get("SYNAPSE_CONFIG_PATH", config_dir + "/homeserver.yaml") data_dir = environ.get("SYNAPSE_DATA_DIR", "/data") + enable_metrics_raw = environ.get("SYNAPSE_ENABLE_METRICS", "0") + + enable_metrics = False + if enable_metrics_raw is not None: + try: + enable_metrics = strtobool(enable_metrics_raw) + except ValueError: + error( + 'Environment variable "SYNAPSE_ENABLE_METRICS" found but value "' + + enable_metrics_raw + + '" unrecognized; exiting.' + ) # create a suitable log config from our template log_config_file = "%s/%s.log.config" % (config_dir, server_name) @@ -190,6 +218,9 @@ def run_generate_config(environ: Mapping[str, str], ownership: Optional[str]) -> "--open-private-ports", ] + if enable_metrics: + args.append("--enable-metrics") + if ownership is not None: # make sure that synapse has perms to write to the data dir. log(f"Setting ownership on {data_dir} to {ownership}") @@ -200,7 +231,7 @@ def run_generate_config(environ: Mapping[str, str], ownership: Optional[str]) -> subprocess.run(args, check=True) -def main(args: List[str], environ: MutableMapping[str, str]) -> None: +def main(args: list[str], environ: MutableMapping[str, str]) -> None: mode = args[1] if len(args) > 1 else "run" # if we were given an explicit user to switch to, do so diff --git a/docs/.htmltest.yml b/docs/.htmltest.yml new file mode 100644 index 0000000000..59d34ce0a0 --- /dev/null +++ b/docs/.htmltest.yml @@ -0,0 +1,5 @@ +# Configuration for htmltest, which we run in CI to check that links aren't broken in the built documentation. +# See all config options: https://github.com/wjdp/htmltest#wrench-configuration + +# Don't check external links, as that requires network access and is slow. +CheckExternal: false \ No newline at end of file diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 52f827c8df..980f51d078 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -5,6 +5,7 @@ # Setup - [Installation](setup/installation.md) + - [Security](setup/security.md) - [Using Postgres](postgres.md) - [Configuring a Reverse Proxy](reverse_proxy.md) - [Configuring a Forward/Outbound Proxy](setup/forward_proxy.md) @@ -60,6 +61,7 @@ - [Admin API](usage/administration/admin_api/README.md) - [Account Validity](admin_api/account_validity.md) - [Background Updates](usage/administration/admin_api/background_updates.md) + - [Fetch Event](admin_api/fetch_event.md) - [Event Reports](admin_api/event_reports.md) - [Experimental Features](admin_api/experimental_features.md) - [Media](admin_api/media_admin_api.md) @@ -115,6 +117,8 @@ - [The Auth Chain Difference Algorithm](auth_chain_difference_algorithm.md) - [Media Repository](media_repository.md) - [Room and User Statistics](room_and_user_statistics.md) + - [Releasing]() + - [Release Notes Review Checklist](development/internal_documentation/release_notes_review_checklist.md) - [Scripts]() # Other diff --git a/docs/admin_api/fetch_event.md b/docs/admin_api/fetch_event.md new file mode 100644 index 0000000000..baf45b8aa7 --- /dev/null +++ b/docs/admin_api/fetch_event.md @@ -0,0 +1,53 @@ +# Fetch Event API + +The fetch event API allows admins to fetch an event regardless of their membership in the room it +originated in. + +To use it, you will need to authenticate by providing an `access_token` +for a server admin: see [Admin API](../usage/administration/admin_api/). + +Request: +```http +GET /_synapse/admin/v1/fetch_event/ +``` + +The API returns a JSON body like the following: + +Response: +```json +{ + "event": { + "auth_events": [ + "$WhLChbYg6atHuFRP7cUd95naUtc8L0f7fqeizlsUVvc", + "$9Wj8dt02lrNEWweeq-KjRABUYKba0K9DL2liRvsAdtQ", + "$qJxBFxBt8_ODd9b3pgOL_jXP98S_igc1_kizuPSZFi4" + ], + "content": { + "body": "Hey now", + "msgtype": "m.text" + }, + "depth": 6, + "event_id": "$hJ_kcXbVMcI82JDrbqfUJIHu61tJD86uIFJ_8hNHi7s", + "hashes": { + "sha256": "LiNw8DtrRVf55EgAH8R42Wz7WCJUqGsPt2We6qZO5Rg" + }, + "origin_server_ts": 799, + "prev_events": [ + "$cnSUrNMnC3Ywh9_W7EquFxYQjC_sT3BAAVzcUVxZq1g" + ], + "room_id": "!aIhKToCqgPTBloWMpf:test", + "sender": "@user:test", + "signatures": { + "test": { + "ed25519:a_lPym": "7mqSDwK1k7rnw34Dd8Fahu0rhPW7jPmcWPRtRDoEN9Yuv+BCM2+Rfdpv2MjxNKy3AYDEBwUwYEuaKMBaEMiKAQ" + } + }, + "type": "m.room.message", + "unsigned": { + "age_ts": 799 + } + } +} +``` + + diff --git a/docs/admin_api/media_admin_api.md b/docs/admin_api/media_admin_api.md index 1177711c1e..6b96eb3356 100644 --- a/docs/admin_api/media_admin_api.md +++ b/docs/admin_api/media_admin_api.md @@ -39,6 +39,40 @@ the use of the [List media uploaded by a user](user_admin_api.md#list-media-uploaded-by-a-user) Admin API. +## Query a piece of media by ID + +This API returns information about a piece of local or cached remote media given the origin server name and media id. If +information is requested for remote media which is not cached the endpoint will return 404. + +Request: +```http +GET /_synapse/admin/v1/media// +``` + +The API returns a JSON body with media info like the following: + +Response: +```json +{ + "media_info": { + "media_origin": "remote.com", + "user_id": null, + "media_id": "sdginwegWEG", + "media_type": "img/png", + "media_length": 67, + "upload_name": "test.png", + "created_ts": 300, + "filesystem_id": "wgeweg", + "url_cache": null, + "last_access_ts": 400, + "quarantined_by": null, + "authenticated": false, + "safe_from_quarantine": null, + "sha256": "ebf4f635a17d10d6eb46ba680b70142419aa3220f228001a036d311a22ee9d2a" + } +} +``` + # Quarantine media Quarantining media means that it is marked as inaccessible by users. It applies @@ -54,6 +88,20 @@ is quarantined, Synapse will: - Quarantine any existing cached remote media. - Quarantine any future remote media. +## Downloading quarantined media + +Normally, when media is quarantined, it will return a 404 error when downloaded. +Admins can bypass this by adding `?admin_unsafely_bypass_quarantine=true` +to the [normal download URL](https://spec.matrix.org/v1.16/client-server-api/#get_matrixclientv1mediadownloadservernamemediaid). + +Bypassing the quarantine check is not recommended. Media is typically quarantined +to prevent harmful content from being served to users, which includes admins. Only +set the bypass parameter if you intentionally want to access potentially harmful +content. + +Non-admin users cannot bypass quarantine checks, even when specifying the above +query parameter. + ## Quarantining media by ID This API quarantines a single piece of local or remote media. diff --git a/docs/admin_api/rooms.md b/docs/admin_api/rooms.md index 12af87148d..11e787c236 100644 --- a/docs/admin_api/rooms.md +++ b/docs/admin_api/rooms.md @@ -1115,3 +1115,76 @@ Example response: ] } ``` + +# Admin Space Hierarchy Endpoint + +This API allows an admin to fetch the space/room hierarchy for a given space, +returning details about that room and any children the room may have, paginating +over the space tree in a depth-first manner to locate child rooms. This is +functionally similar to the [CS Hierarchy](https://spec.matrix.org/v1.16/client-server-api/#get_matrixclientv1roomsroomidhierarchy) endpoint but does not check for +room membership when returning room summaries. + +The endpoint does not query other servers over federation about remote rooms +that the server has not joined. This is a deliberate trade-off: while this +means it will leave some holes in the hierarchy that we could otherwise +sometimes fill in, it significantly improves the endpoint's response time and +the admin endpoint is designed for managing rooms local to the homeserver +anyway. + +**Parameters** + +The following query parameters are available: + +* `from` - An optional pagination token, provided when there are more rooms to + return than the limit. +* `limit` - Maximum amount of rooms to return. Must be a non-negative integer, + defaults to `50`. +* `max_depth` - The maximum depth in the tree to explore, must be a non-negative + integer. 0 would correspond to just the root room, 1 would include just the + root room's children, etc. If not provided will recurse into the space tree without limit. + +Request: + +```http +GET /_synapse/admin/v1/rooms//hierarchy +``` + +Response: + +```json +{ + "rooms": + [ + { "children_state": [ + { + "content": { + "via": ["local_test_server"] + }, + "origin_server_ts": 1500, + "sender": "@user:test", + "state_key": "!QrMkkqBSwYRIFNFCso:test", + "type": "m.space.child" + } + ], + "name": "space room", + "guest_can_join": false, + "join_rule": "public", + "num_joined_members": 1, + "room_id": "!sPOpNyMHbZAoAOsOFL:test", + "room_type": "m.space", + "world_readable": false + }, + + { + "children_state": [], + "guest_can_join": true, + "join_rule": "invite", + "name": "nefarious", + "num_joined_members": 1, + "room_id": "!QrMkkqBSwYRIFNFCso:test", + "topic": "being bad", + "world_readable": false} + ], + "next_batch": "KUYmRbeSpAoaAIgOKGgyaCEn" +} +``` diff --git a/docs/admin_api/scheduled_tasks.md b/docs/admin_api/scheduled_tasks.md index b80da5083c..949a03ee39 100644 --- a/docs/admin_api/scheduled_tasks.md +++ b/docs/admin_api/scheduled_tasks.md @@ -36,9 +36,10 @@ It returns a JSON body like the following: - "scheduled" - Task is scheduled but not active - "active" - Task is active and probably running, and if not will be run on next scheduler loop run - "complete" - Task has completed successfully + - "cancelled" - Task has been cancelled - "failed" - Task is over and either returned a failed status, or had an exception -* `max_timestamp`: int - Is optional. Returns only the scheduled tasks with a timestamp inferior to the specified one. +* `max_timestamp`: int - Is optional. Returns only the scheduled tasks with a timestamp (in milliseconds since the unix epoch) inferior to the specified one. **Response** diff --git a/docs/admin_api/user_admin_api.md b/docs/admin_api/user_admin_api.md index 4de7e85642..14f86fa976 100644 --- a/docs/admin_api/user_admin_api.md +++ b/docs/admin_api/user_admin_api.md @@ -403,6 +403,7 @@ is set to `true`: - Remove the user's display name - Remove the user's avatar URL +- Remove the user's custom profile fields - Mark the user as erased The following actions are **NOT** performed. The list may be incomplete. @@ -505,6 +506,55 @@ with a body of: } ``` +## List room memberships of a user + +Gets a list of room memberships for a specific `user_id`. This +endpoint differs from +[`GET /_synapse/admin/v1/users//joined_rooms`](#list-joined-rooms-of-a-user) +in that it returns rooms with memberships other than "join". + +The API is: + +``` +GET /_synapse/admin/v1/users//memberships +``` + +A response body like the following is returned: + +```json + { + "memberships": { + "!DuGcnbhHGaSZQoNQR:matrix.org": "join", + "!ZtSaPCawyWtxfWiIy:matrix.org": "leave", + } + } +``` + +which is a list of room membership states for the given user. This endpoint can +be used with both local and remote users, with the caveat that the homeserver will +only be aware of the memberships for rooms that one of its local users has joined. + +Remote user memberships may also be out of date if all local users have since left +a room. The homeserver will thus no longer receive membership updates about it. + +The list includes rooms that the user has since left; other membership states (knock, +invite, etc.) are also possible. + +Note that rooms will only disappear from this list if they are +[purged](./rooms.md#delete-room-api) from the homeserver. + +**Parameters** + +The following parameters should be set in the URL: + +- `user_id` - fully qualified: for example, `@user:server.com`. + +**Response** + +The following fields are returned in the JSON response body: + +- `memberships` - A map of `room_id` (string) to `membership` state (string). + ## List joined rooms of a user Gets a list of all `room_id` that a specific `user_id` is joined to and is a member of (participating in). @@ -550,7 +600,7 @@ Fetches the number of invites sent by the provided user ID across all rooms after the given timestamp. ``` -GET /_synapse/admin/v1/users/$user_id/sent_invite_count +GET /_synapse/admin/v1/users//sent_invite_count ``` **Parameters** @@ -584,7 +634,7 @@ Fetches the number of rooms that the user joined after the given timestamp, even if they have subsequently left/been banned from those rooms. ``` -GET /_synapse/admin/v1/users/$/cumulative_joined_room_count ``` **Parameters** @@ -1389,7 +1439,7 @@ The request and response format is the same as the The API is: ``` -GET /_synapse/admin/v1/auth_providers/$provider/users/$external_id +GET /_synapse/admin/v1/auth_providers//users/ ``` When a user matched the given ID for the given provider, an HTTP code `200` with a response body like the following is returned: @@ -1428,7 +1478,7 @@ _Added in Synapse 1.68.0._ The API is: ``` -GET /_synapse/admin/v1/threepid/$medium/users/$address +GET /_synapse/admin/v1/threepid//users/
``` When a user matched the given address for the given medium, an HTTP code `200` with a response body like the following is returned: @@ -1472,7 +1522,7 @@ is provided to override the default and allow the admin to issue the redactions The API is ``` -POST /_synapse/admin/v1/user/$user_id/redact +POST /_synapse/admin/v1/user//redact { "rooms": ["!roomid1", "!roomid2"] @@ -1521,7 +1571,7 @@ or until Synapse is restarted (whichever happens first). The API is: ``` -GET /_synapse/admin/v1/user/redact_status/$redact_id +GET /_synapse/admin/v1/user/redact_status/ ``` A response body like the following is returned: diff --git a/docs/deprecation_policy.md b/docs/deprecation_policy.md index 8403664850..06c724d348 100644 --- a/docs/deprecation_policy.md +++ b/docs/deprecation_policy.md @@ -1,13 +1,11 @@ -Deprecation Policy for Platform Dependencies -============================================ +# Deprecation Policy -Synapse has a number of platform dependencies, including Python, Rust, -PostgreSQL and SQLite. This document outlines the policy towards which versions -we support, and when we drop support for versions in the future. +Synapse has a number of **platform dependencies** (Python, Rust, PostgreSQL, and SQLite) +and **application dependencies** (Python and Rust packages). This document outlines the +policy towards which versions we support, and when we drop support for versions in the +future. - -Policy ------- +## Platform Dependencies Synapse follows the upstream support life cycles for Python and PostgreSQL, i.e. when a version reaches End of Life Synapse will withdraw support for that @@ -23,11 +21,11 @@ people building from source should ensure they can fetch recent versions of Rust (e.g. by using [rustup](https://rustup.rs/)). The oldest supported version of SQLite is the version -[provided](https://packages.debian.org/bullseye/libsqlite3-0) by +[provided](https://packages.debian.org/oldstable/libsqlite3-0) by [Debian oldstable](https://wiki.debian.org/DebianOldStable). -Context -------- + +### Context It is important for system admins to have a clear understanding of the platform requirements of Synapse and its deprecation policies so that they can @@ -50,4 +48,42 @@ the ecosystem. On a similar note, SQLite does not generally have a concept of "supported release"; bugfixes are published for the latest minor release only. We chose to track Debian's oldstable as this is relatively conservative, predictably updated -and is consistent with the `.deb` packages released by Matrix.org. \ No newline at end of file +and is consistent with the `.deb` packages released by Matrix.org. + + +## Application dependencies + +For application-level Python dependencies, we often specify loose version constraints +(ex. `>=X.Y.Z`) to be forwards compatible with any new versions. Upper bounds (`. +3. Wrap any class names, variable names, etc. in back-ticks, if needed. +4. Hoist any relevant security, deprecation, etc. announcements to the top of this version's changelog for visibility. This includes any announcements in RCs for this release. +5. Check the upgrade notes for any important announcements, and link to them from the changelog if warranted. +6. Quickly skim and check that each entry is in the appropriate section. +7. Entries under the Bugfixes section should ideally state what Synapse version the bug was introduced in. For example: "Fixed a bug introduced in v1.x.y" or if no version can be identified, "Fixed a long-standing bug ...". \ No newline at end of file diff --git a/docs/development/synapse_architecture/cancellation.md b/docs/development/synapse_architecture/cancellation.md index ef9e022635..a12f119fb5 100644 --- a/docs/development/synapse_architecture/cancellation.md +++ b/docs/development/synapse_architecture/cancellation.md @@ -299,7 +299,7 @@ logcontext is not finished before the `async` processing completes. **Bad**: ```python -cache: Optional[ObservableDeferred[None]] = None +cache: ObservableDeferred[None] | None = None async def do_something_else( to_resolve: Deferred[None] @@ -326,7 +326,7 @@ with LoggingContext("request-1"): **Good**: ```python -cache: Optional[ObservableDeferred[None]] = None +cache: ObservableDeferred[None] | None = None async def do_something_else( to_resolve: Deferred[None] @@ -358,7 +358,7 @@ with LoggingContext("request-1"): **OK**: ```python -cache: Optional[ObservableDeferred[None]] = None +cache: ObservableDeferred[None] | None = None async def do_something_else( to_resolve: Deferred[None] diff --git a/docs/development/synapse_architecture/streams.md b/docs/development/synapse_architecture/streams.md index 4981416835..364f90af75 100644 --- a/docs/development/synapse_architecture/streams.md +++ b/docs/development/synapse_architecture/streams.md @@ -1,4 +1,4 @@ -## Streams +# Streams Synapse has a concept of "streams", which are roughly described in [`id_generators.py`]( https://github.com/element-hq/synapse/blob/develop/synapse/storage/util/id_generators.py @@ -19,7 +19,7 @@ To that end, let's describe streams formally, paraphrasing from the docstring of https://github.com/element-hq/synapse/blob/a719b703d9bd0dade2565ddcad0e2f3a7a9d4c37/synapse/storage/util/id_generators.py#L96 ). -### Definition +## Definition A stream is an append-only log `T1, T2, ..., Tn, ...` of facts[^1] which grows over time. Only "writers" can add facts to a stream, and there may be multiple writers. @@ -47,7 +47,7 @@ But unhappy cases (e.g. transaction rollback due to an error) also count as comp Once completed, the rows written with that stream ID are fixed, and no new rows will be inserted with that ID. -### Current stream ID +## Current stream ID For any given stream reader (including writers themselves), we may define a per-writer current stream ID: @@ -93,7 +93,7 @@ Consider a single-writer stream which is initially at ID 1. | Complete 6 | 6 | | -### Multi-writer streams +## Multi-writer streams There are two ways to view a multi-writer stream. @@ -115,7 +115,7 @@ The facts this stream holds are instructions to "you should now invalidate these We only ever treat this as a multiple single-writer streams as there is no important ordering between cache invalidations. (Invalidations are self-contained facts; and the invalidations commute/are idempotent). -### Writing to streams +## Writing to streams Writers need to track: - track their current position (i.e. its own per-writer stream ID). @@ -133,7 +133,7 @@ To complete a fact, first remove it from your map of facts currently awaiting co Then, if no earlier fact is awaiting completion, the writer can advance its current position in that stream. Upon doing so it should emit an `RDATA` message[^3], once for every fact between the old and the new stream ID. -### Subscribing to streams +## Subscribing to streams Readers need to track the current position of every writer. @@ -146,10 +146,44 @@ The `RDATA` itself is not a self-contained representation of the fact; readers will have to query the stream tables for the full details. Readers must also advance their record of the writer's current position for that stream. -# Summary +## Summary In a nutshell: we have an append-only log with a "buffer/scratchpad" at the end where we have to wait for the sequence to be linear and contiguous. +--- + +## Cheatsheet for creating a new stream + +These rough notes and links may help you to create a new stream and add all the +necessary registration and event handling. + +**Create your stream:** +- [create a stream class and stream row class](https://github.com/element-hq/synapse/blob/4367fb2d078c52959aeca0fe6874539c53e8360d/synapse/replication/tcp/streams/_base.py#L728) + - will need an [ID generator](https://github.com/element-hq/synapse/blob/4367fb2d078c52959aeca0fe6874539c53e8360d/synapse/storage/databases/main/thread_subscriptions.py#L75) + - may need [writer configuration](https://github.com/element-hq/synapse/blob/4367fb2d078c52959aeca0fe6874539c53e8360d/synapse/config/workers.py#L177), if there isn't already an obvious source of configuration for which workers should be designated as writers to your new stream. + - if adding new writer configuration, add Docker-worker configuration, which lets us configure the writer worker in Complement tests: [[1]](https://github.com/element-hq/synapse/blob/4367fb2d078c52959aeca0fe6874539c53e8360d/docker/configure_workers_and_start.py#L331), [[2]](https://github.com/element-hq/synapse/blob/4367fb2d078c52959aeca0fe6874539c53e8360d/docker/configure_workers_and_start.py#L440) +- most of the time, you will likely introduce a new datastore class for the concept represented by the new stream, unless there is already an obvious datastore that covers it. +- consider whether it may make sense to introduce a handler + +**Register your stream in:** +- [`STREAMS_MAP`](https://github.com/element-hq/synapse/blob/4367fb2d078c52959aeca0fe6874539c53e8360d/synapse/replication/tcp/streams/__init__.py#L71) + +**Advance your stream in:** +- [`process_replication_position` of your appropriate datastore](https://github.com/element-hq/synapse/blob/4367fb2d078c52959aeca0fe6874539c53e8360d/synapse/storage/databases/main/thread_subscriptions.py#L111) + - don't forget the super call + +**If you're going to do any caching that needs invalidation from new rows:** +- add invalidations to [`process_replication_rows` of your appropriate datastore](https://github.com/element-hq/synapse/blob/4367fb2d078c52959aeca0fe6874539c53e8360d/synapse/storage/databases/main/thread_subscriptions.py#L91) + - don't forget the super call +- add local-only [invalidations to your writer transactions](https://github.com/element-hq/synapse/blob/4367fb2d078c52959aeca0fe6874539c53e8360d/synapse/storage/databases/main/thread_subscriptions.py#L201) + +**For streams to be used in sync:** +- add a new field to [`StreamToken`](https://github.com/element-hq/synapse/blob/4367fb2d078c52959aeca0fe6874539c53e8360d/synapse/types/__init__.py#L1003) + - add a new [`StreamKeyType`](https://github.com/element-hq/synapse/blob/4367fb2d078c52959aeca0fe6874539c53e8360d/synapse/types/__init__.py#L999) +- add appropriate wake-up rules + - in [`on_rdata`](https://github.com/element-hq/synapse/blob/4367fb2d078c52959aeca0fe6874539c53e8360d/synapse/replication/tcp/client.py#L260) + - locally on the same worker when completing a write, [e.g. in your handler](https://github.com/element-hq/synapse/blob/4367fb2d078c52959aeca0fe6874539c53e8360d/synapse/handlers/thread_subscriptions.py#L139) +- add the stream in [`bound_future_token`](https://github.com/element-hq/synapse/blob/4367fb2d078c52959aeca0fe6874539c53e8360d/synapse/streams/events.py#L127) --- diff --git a/docs/log_contexts.md b/docs/log_contexts.md index 9d087d11ef..76710e10e0 100644 --- a/docs/log_contexts.md +++ b/docs/log_contexts.md @@ -59,6 +59,28 @@ def do_request_handling(): logger.debug("phew") ``` +### The `sentinel` context + +The default logcontext is `synapse.logging.context.SENTINEL_CONTEXT`, which is an empty +sentinel value to represent the root logcontext. This is what is used when there is no +other logcontext set. The phrase "clear/reset the logcontext" means to set the current +logcontext to the `sentinel` logcontext. + +No CPU/database usage metrics are recorded against the `sentinel` logcontext. + +Ideally, nothing from the Synapse homeserver would be logged against the `sentinel` +logcontext as we want to know which server the logs came from. In practice, this is not +always the case yet especially outside of request handling. + +Global things outside of Synapse (e.g. Twisted reactor code) should run in the +`sentinel` logcontext. It's only when it calls into application code that a logcontext +gets activated. This means the reactor should be started in the `sentinel` logcontext, +and any time an awaitable yields control back to the reactor, it should reset the +logcontext to be the `sentinel` logcontext. This is important to avoid leaking the +current logcontext to the reactor (which would then get picked up and associated with +the next thing the reactor does). + + ## Using logcontexts with awaitables Awaitables break the linear flow of code so that there is no longer a single entry point @@ -121,8 +143,7 @@ cares about. The following sections describe pitfalls and helpful patterns when implementing these rules. -Always await your awaitables ----------------------------- +## Always await your awaitables Whenever you get an awaitable back from a function, you should `await` on it as soon as possible. Do not pass go; do not do any logging; do not @@ -181,6 +202,171 @@ async def sleep(seconds): return await context.make_deferred_yieldable(get_sleep_deferred(seconds)) ``` +## Deferred callbacks + +When a deferred callback is called, it inherits the current logcontext. The deferred +callback chain can resume a coroutine, which if following our logcontext rules, will +restore its own logcontext, then run: + + - until it yields control back to the reactor, setting the sentinel logcontext + - or until it finishes, restoring the logcontext it was started with (calling context) + +This behavior creates two specific issues: + +**Issue 1:** The first issue is that the callback may have reset the logcontext to the +sentinel before returning. This means our calling function will continue with the +sentinel logcontext instead of the logcontext it was started with (bad). + +**Issue 2:** The second issue is that the current logcontext that called the deferred +callback could finish before the callback finishes (bad). + +In the following example, the deferred callback is called with the "main" logcontext and +runs until we yield control back to the reactor in the `await` inside `clock.sleep(0)`. +Since `clock.sleep(0)` follows our logcontext rules, it sets the logcontext to the +sentinel before yielding control back to the reactor. Our `main` function continues with +the sentinel logcontext (first bad thing) instead of the "main" logcontext. Then the +`with LoggingContext("main")` block exits, finishing the "main" logcontext and yielding +control back to the reactor again. Finally, later on when `clock.sleep(0)` completes, +our `with LoggingContext("competing")` block exits, and restores the previous "main" +logcontext which has already finished, resulting in `WARNING: Re-starting finished log +context main` and leaking the `main` logcontext into the reactor which will then +erronously be associated with the next task the reactor picks up. + +```python +async def competing_callback(): + # Since this is run with the "main" logcontext, when the "competing" + # logcontext exits, it will restore the previous "main" logcontext which has + # already finished and results in "WARNING: Re-starting finished log context main" + # and leaking the `main` logcontext into the reactor. + with LoggingContext("competing"): + await clock.sleep(0) + +def main(): + with LoggingContext("main"): + d = defer.Deferred() + d.addCallback(lambda _: defer.ensureDeferred(competing_callback())) + # Call the callback within the "main" logcontext. + d.callback(None) + # Bad: This will be logged against sentinel logcontext + logger.debug("ugh") + +main() +``` + +**Solution 1:** We could of course fix this by following the general rule of "always +await your awaitables": + +```python +async def main(): + with LoggingContext("main"): + d = defer.Deferred() + d.addCallback(lambda _: defer.ensureDeferred(competing_callback())) + d.callback(None) + # Wait for `d` to finish before continuing so the "main" logcontext is + # still active. This works because `d` already follows our logcontext + # rules. If not, we would also have to use `make_deferred_yieldable(d)`. + await d + # Good: This will be logged against the "main" logcontext + logger.debug("phew") +``` + +**Solution 2:** We could also fix this by surrounding the call to `d.callback` with a +`PreserveLoggingContext`, which will reset the logcontext to the sentinel before calling +the callback, and restore the "main" logcontext afterwards before continuing the `main` +function. This solves the problem because when the "competing" logcontext exits, it will +restore the sentinel logcontext which is never finished by its nature, so there is no +warning and no leakage into the reactor. + +```python +async def main(): + with LoggingContext("main"): + d = defer.Deferred() + d.addCallback(lambda _: defer.ensureDeferred(competing_callback())) + d.callback(None) + with PreserveLoggingContext(): + # Call the callback with the sentinel logcontext. + d.callback(None) + # Good: This will be logged against the "main" logcontext + logger.debug("phew") +``` + +**Solution 3:** But let's say you *do* want to run (fire-and-forget) the deferred +callback in the current context without running into issues: + +We can solve the first issue by using `run_in_background(...)` to run the callback in +the current logcontext and it handles the magic behind the scenes of a) restoring the +calling logcontext before returning to the caller and b) resetting the logcontext to the +sentinel after the deferred completes and we yield control back to the reactor to avoid +leaking the logcontext into the reactor. + +To solve the second issue, we can extend the lifetime of the "main" logcontext by +avoiding the `LoggingContext`'s context manager lifetime methods +(`__enter__`/`__exit__`). We can still set "main" as the current logcontext by using +`PreserveLoggingContext` and passing in the "main" logcontext. + + +```python +async def main(): + main_context = LoggingContext("main") + with PreserveLoggingContext(main_context): + d = defer.Deferred() + d.addCallback(lambda _: defer.ensureDeferred(competing_callback())) + # The whole lambda will be run in the "main" logcontext. But we're using + # a trick to return the deferred `d` itself so that `run_in_background` + # will wait on that to complete and reset the logcontext to the sentinel + # when it does to avoid leaking the "main" logcontext into the reactor. + run_in_background(lambda: (d.callback(None), d)[1]) + # Good: This will be logged against the "main" logcontext + logger.debug("phew") + +... + +# Wherever possible, it's best to finish the logcontext by calling `__exit__` at some +# point. This allows us to catch bugs if we later try to erroneously restart a finished +# logcontext. +# +# Since the "main" logcontext stores the `LoggingContext.previous_context` when it is +# created, we can wrap this call in `PreserveLoggingContext()` to restore the correct +# previous logcontext. Our goal is to have the calling context remain unchanged after +# finishing the "main" logcontext. +with PreserveLoggingContext(): + # Finish the "main" logcontext + with main_context: + # Empty block - We're just trying to call `__exit__` on the "main" context + # manager to finish it. We can't call `__exit__` directly as the code expects us + # to `__enter__` before calling `__exit__` to `start`/`stop` things + # appropriately. And in any case, it's probably best not to call the internal + # methods directly. + pass +``` + +The same thing applies if you have some deferreds stored somewhere which you want to +callback in the current logcontext. + + +### Deferred errbacks and cancellations + +The same care should be taken when calling errbacks on deferreds. An errback and +callback act the same in this regard (see section above). + +```python +d = defer.Deferred() +d.addErrback(some_other_function) +d.errback(failure) +``` + +Additionally, cancellation is the same as directly calling the errback with a +`twisted.internet.defer.CancelledError`: + +```python +d = defer.Deferred() +d.addErrback(some_other_function) +d.cancel() +``` + + + + ## Fire-and-forget Sometimes you want to fire off a chain of execution, but not wait for @@ -362,3 +548,19 @@ chain are dropped. Dropping the the reference to an awaitable you're supposed to be awaiting is bad practice, so this doesn't actually happen too much. Unfortunately, when it does happen, it will lead to leaked logcontexts which are incredibly hard to track down. + + +## Debugging logcontext issues + +Debugging logcontext issues can be tricky as leaking or losing a logcontext will surface +downstream and can point to an unrelated part of the codebase. It's best to enable debug +logging for `synapse.logging.context.debug` (needs to be explicitly configured) and go +backwards in the logs from the point where the issue is observed to find the root cause. + +`log.config.yaml` +```yaml +loggers: + # Unlike other loggers, this one needs to be explicitly configured to see debug logs. + synapse.logging.context.debug: + level: DEBUG +``` diff --git a/docs/metrics-howto.md b/docs/metrics-howto.md index eb6b90cec9..d322de9204 100644 --- a/docs/metrics-howto.md +++ b/docs/metrics-howto.md @@ -123,193 +123,21 @@ Example Prometheus target for Synapse with workers: static_configs: - targets: ["my.server.here:port"] labels: - instance: "my.server" job: "master" index: 1 - targets: ["my.workerserver.here:port"] labels: - instance: "my.server" job: "generic_worker" index: 1 - targets: ["my.workerserver.here:port"] labels: - instance: "my.server" job: "generic_worker" index: 2 - targets: ["my.workerserver.here:port"] labels: - instance: "my.server" job: "media_repository" index: 1 ``` -Labels (`instance`, `job`, `index`) can be defined as anything. +Labels (`job`, `index`) can be defined as anything. The labels are used to group graphs in grafana. - -## Renaming of metrics & deprecation of old names in 1.2 - -Synapse 1.2 updates the Prometheus metrics to match the naming -convention of the upstream `prometheus_client`. The old names are -considered deprecated and will be removed in a future version of -Synapse. -**The old names will be disabled by default in Synapse v1.71.0 and removed -altogether in Synapse v1.73.0.** - -| New Name | Old Name | -| ---------------------------------------------------------------------------- | ---------------------------------------------------------------------- | -| python_gc_objects_collected_total | python_gc_objects_collected | -| python_gc_objects_uncollectable_total | python_gc_objects_uncollectable | -| python_gc_collections_total | python_gc_collections | -| process_cpu_seconds_total | process_cpu_seconds | -| synapse_federation_client_sent_transactions_total | synapse_federation_client_sent_transactions | -| synapse_federation_client_events_processed_total | synapse_federation_client_events_processed | -| synapse_event_processing_loop_count_total | synapse_event_processing_loop_count | -| synapse_event_processing_loop_room_count_total | synapse_event_processing_loop_room_count | -| synapse_util_caches_cache_hits | synapse_util_caches_cache:hits | -| synapse_util_caches_cache_size | synapse_util_caches_cache:size | -| synapse_util_caches_cache_evicted_size | synapse_util_caches_cache:evicted_size | -| synapse_util_caches_cache | synapse_util_caches_cache:total | -| synapse_util_caches_response_cache_size | synapse_util_caches_response_cache:size | -| synapse_util_caches_response_cache_hits | synapse_util_caches_response_cache:hits | -| synapse_util_caches_response_cache_evicted_size | synapse_util_caches_response_cache:evicted_size | -| synapse_util_metrics_block_count_total | synapse_util_metrics_block_count | -| synapse_util_metrics_block_time_seconds_total | synapse_util_metrics_block_time_seconds | -| synapse_util_metrics_block_ru_utime_seconds_total | synapse_util_metrics_block_ru_utime_seconds | -| synapse_util_metrics_block_ru_stime_seconds_total | synapse_util_metrics_block_ru_stime_seconds | -| synapse_util_metrics_block_db_txn_count_total | synapse_util_metrics_block_db_txn_count | -| synapse_util_metrics_block_db_txn_duration_seconds_total | synapse_util_metrics_block_db_txn_duration_seconds | -| synapse_util_metrics_block_db_sched_duration_seconds_total | synapse_util_metrics_block_db_sched_duration_seconds | -| synapse_background_process_start_count_total | synapse_background_process_start_count | -| synapse_background_process_ru_utime_seconds_total | synapse_background_process_ru_utime_seconds | -| synapse_background_process_ru_stime_seconds_total | synapse_background_process_ru_stime_seconds | -| synapse_background_process_db_txn_count_total | synapse_background_process_db_txn_count | -| synapse_background_process_db_txn_duration_seconds_total | synapse_background_process_db_txn_duration_seconds | -| synapse_background_process_db_sched_duration_seconds_total | synapse_background_process_db_sched_duration_seconds | -| synapse_storage_events_persisted_events_total | synapse_storage_events_persisted_events | -| synapse_storage_events_persisted_events_sep_total | synapse_storage_events_persisted_events_sep | -| synapse_storage_events_state_delta_total | synapse_storage_events_state_delta | -| synapse_storage_events_state_delta_single_event_total | synapse_storage_events_state_delta_single_event | -| synapse_storage_events_state_delta_reuse_delta_total | synapse_storage_events_state_delta_reuse_delta | -| synapse_federation_server_received_pdus_total | synapse_federation_server_received_pdus | -| synapse_federation_server_received_edus_total | synapse_federation_server_received_edus | -| synapse_handler_presence_notified_presence_total | synapse_handler_presence_notified_presence | -| synapse_handler_presence_federation_presence_out_total | synapse_handler_presence_federation_presence_out | -| synapse_handler_presence_presence_updates_total | synapse_handler_presence_presence_updates | -| synapse_handler_presence_timers_fired_total | synapse_handler_presence_timers_fired | -| synapse_handler_presence_federation_presence_total | synapse_handler_presence_federation_presence | -| synapse_handler_presence_bump_active_time_total | synapse_handler_presence_bump_active_time | -| synapse_federation_client_sent_edus_total | synapse_federation_client_sent_edus | -| synapse_federation_client_sent_pdu_destinations_count_total | synapse_federation_client_sent_pdu_destinations:count | -| synapse_federation_client_sent_pdu_destinations_total | synapse_federation_client_sent_pdu_destinations:total | -| synapse_handlers_appservice_events_processed_total | synapse_handlers_appservice_events_processed | -| synapse_notifier_notified_events_total | synapse_notifier_notified_events | -| synapse_push_bulk_push_rule_evaluator_push_rules_invalidation_counter_total | synapse_push_bulk_push_rule_evaluator_push_rules_invalidation_counter | -| synapse_push_bulk_push_rule_evaluator_push_rules_state_size_counter_total | synapse_push_bulk_push_rule_evaluator_push_rules_state_size_counter | -| synapse_http_httppusher_http_pushes_processed_total | synapse_http_httppusher_http_pushes_processed | -| synapse_http_httppusher_http_pushes_failed_total | synapse_http_httppusher_http_pushes_failed | -| synapse_http_httppusher_badge_updates_processed_total | synapse_http_httppusher_badge_updates_processed | -| synapse_http_httppusher_badge_updates_failed_total | synapse_http_httppusher_badge_updates_failed | -| synapse_admin_mau_current | synapse_admin_mau:current | -| synapse_admin_mau_max | synapse_admin_mau:max | -| synapse_admin_mau_registered_reserved_users | synapse_admin_mau:registered_reserved_users | - -Removal of deprecated metrics & time based counters becoming histograms in 0.31.0 ---------------------------------------------------------------------------------- - -The duplicated metrics deprecated in Synapse 0.27.0 have been removed. - -All time duration-based metrics have been changed to be seconds. This -affects: - -| msec -> sec metrics | -| -------------------------------------- | -| python_gc_time | -| python_twisted_reactor_tick_time | -| synapse_storage_query_time | -| synapse_storage_schedule_time | -| synapse_storage_transaction_time | - -Several metrics have been changed to be histograms, which sort entries -into buckets and allow better analysis. The following metrics are now -histograms: - -| Altered metrics | -| ------------------------------------------------ | -| python_gc_time | -| python_twisted_reactor_pending_calls | -| python_twisted_reactor_tick_time | -| synapse_http_server_response_time_seconds | -| synapse_storage_query_time | -| synapse_storage_schedule_time | -| synapse_storage_transaction_time | - -Block and response metrics renamed for 0.27.0 ---------------------------------------------- - -Synapse 0.27.0 begins the process of rationalising the duplicate -`*:count` metrics reported for the resource tracking for code blocks and -HTTP requests. - -At the same time, the corresponding `*:total` metrics are being renamed, -as the `:total` suffix no longer makes sense in the absence of a -corresponding `:count` metric. - -To enable a graceful migration path, this release just adds new names -for the metrics being renamed. A future release will remove the old -ones. - -The following table shows the new metrics, and the old metrics which -they are replacing. - -| New name | Old name | -| ------------------------------------------------------------- | ---------------------------------------------------------- | -| synapse_util_metrics_block_count | synapse_util_metrics_block_timer:count | -| synapse_util_metrics_block_count | synapse_util_metrics_block_ru_utime:count | -| synapse_util_metrics_block_count | synapse_util_metrics_block_ru_stime:count | -| synapse_util_metrics_block_count | synapse_util_metrics_block_db_txn_count:count | -| synapse_util_metrics_block_count | synapse_util_metrics_block_db_txn_duration:count | -| synapse_util_metrics_block_time_seconds | synapse_util_metrics_block_timer:total | -| synapse_util_metrics_block_ru_utime_seconds | synapse_util_metrics_block_ru_utime:total | -| synapse_util_metrics_block_ru_stime_seconds | synapse_util_metrics_block_ru_stime:total | -| synapse_util_metrics_block_db_txn_count | synapse_util_metrics_block_db_txn_count:total | -| synapse_util_metrics_block_db_txn_duration_seconds | synapse_util_metrics_block_db_txn_duration:total | -| synapse_http_server_response_count | synapse_http_server_requests | -| synapse_http_server_response_count | synapse_http_server_response_time:count | -| synapse_http_server_response_count | synapse_http_server_response_ru_utime:count | -| synapse_http_server_response_count | synapse_http_server_response_ru_stime:count | -| synapse_http_server_response_count | synapse_http_server_response_db_txn_count:count | -| synapse_http_server_response_count | synapse_http_server_response_db_txn_duration:count | -| synapse_http_server_response_time_seconds | synapse_http_server_response_time:total | -| synapse_http_server_response_ru_utime_seconds | synapse_http_server_response_ru_utime:total | -| synapse_http_server_response_ru_stime_seconds | synapse_http_server_response_ru_stime:total | -| synapse_http_server_response_db_txn_count | synapse_http_server_response_db_txn_count:total | -| synapse_http_server_response_db_txn_duration_seconds | synapse_http_server_response_db_txn_duration:total | - -Standard Metric Names ---------------------- - -As of synapse version 0.18.2, the format of the process-wide metrics has -been changed to fit prometheus standard naming conventions. Additionally -the units have been changed to seconds, from milliseconds. - -| New name | Old name | -| ---------------------------------------- | --------------------------------- | -| process_cpu_user_seconds_total | process_resource_utime / 1000 | -| process_cpu_system_seconds_total | process_resource_stime / 1000 | -| process_open_fds (no \'type\' label) | process_fds | - -The python-specific counts of garbage collector performance have been -renamed. - -| New name | Old name | -| -------------------------------- | -------------------------- | -| python_gc_time | reactor_gc_time | -| python_gc_unreachable_total | reactor_gc_unreachable | -| python_gc_counts | reactor_gc_counts | - -The twisted-specific reactor metrics have been renamed. - -| New name | Old name | -| -------------------------------------- | ----------------------- | -| python_twisted_reactor_pending_calls | reactor_pending_calls | -| python_twisted_reactor_tick_time | reactor_tick_time | diff --git a/docs/modules/account_data_callbacks.md b/docs/modules/account_data_callbacks.md index 25de911627..02b8c18bbf 100644 --- a/docs/modules/account_data_callbacks.md +++ b/docs/modules/account_data_callbacks.md @@ -15,7 +15,7 @@ _First introduced in Synapse v1.57.0_ ```python async def on_account_data_updated( user_id: str, - room_id: Optional[str], + room_id: str | None, account_data_type: str, content: "synapse.module_api.JsonDict", ) -> None: @@ -82,7 +82,7 @@ class CustomAccountDataModule: async def log_new_account_data( self, user_id: str, - room_id: Optional[str], + room_id: str | None, account_data_type: str, content: JsonDict, ) -> None: diff --git a/docs/modules/account_validity_callbacks.md b/docs/modules/account_validity_callbacks.md index f5eefcd7d6..2deb43c1be 100644 --- a/docs/modules/account_validity_callbacks.md +++ b/docs/modules/account_validity_callbacks.md @@ -12,7 +12,7 @@ The available account validity callbacks are: _First introduced in Synapse v1.39.0_ ```python -async def is_user_expired(user: str) -> Optional[bool] +async def is_user_expired(user: str) -> bool | None ``` Called when processing any authenticated request (except for logout requests). The module diff --git a/docs/modules/media_repository_callbacks.md b/docs/modules/media_repository_callbacks.md index fc37130439..d7c9074bde 100644 --- a/docs/modules/media_repository_callbacks.md +++ b/docs/modules/media_repository_callbacks.md @@ -11,7 +11,7 @@ The available media repository callbacks are: _First introduced in Synapse v1.132.0_ ```python -async def get_media_config_for_user(user_id: str) -> Optional[JsonDict] +async def get_media_config_for_user(user_id: str) -> JsonDict | None ``` ** @@ -64,3 +64,68 @@ If multiple modules implement this callback, they will be considered in order. I returns `True`, Synapse falls through to the next one. The value of the first callback that returns `False` will be used. If this happens, Synapse will not call any of the subsequent implementations of this callback. + +### `get_media_upload_limits_for_user` + +_First introduced in Synapse v1.139.0_ + +```python +async def get_media_upload_limits_for_user(user_id: str, size: int) -> list[synapse.module_api.MediaUploadLimit] | None +``` + +** +Caution: This callback is currently experimental. The method signature or behaviour +may change without notice. +** + +Called when processing a request to store content in the media repository. This can be used to dynamically override +the [media upload limits configuration](../usage/configuration/config_documentation.html#media_upload_limits). + +The arguments passed to this callback are: + +* `user_id`: The Matrix user ID of the user (e.g. `@alice:example.com`) making the request. + +If the callback returns a list then it will be used as the limits instead of those in the configuration (if any). + +If an empty list is returned then no limits are applied (**warning:** users will be able +to upload as much data as they desire). + +If multiple modules implement this callback, they will be considered in order. If a +callback returns `None`, Synapse falls through to the next one. The value of the first +callback that does not return `None` will be used. If this happens, Synapse will not call +any of the subsequent implementations of this callback. + +If there are no registered modules, or if all modules return `None`, then +the default +[media upload limits configuration](../usage/configuration/config_documentation.html#media_upload_limits) +will be used. + +### `on_media_upload_limit_exceeded` + +_First introduced in Synapse v1.139.0_ + +```python +async def on_media_upload_limit_exceeded(user_id: str, limit: synapse.module_api.MediaUploadLimit, sent_bytes: int, attempted_bytes: int) -> None +``` + +** +Caution: This callback is currently experimental. The method signature or behaviour +may change without notice. +** + +Called when a user attempts to upload media that would exceed a +[configured media upload limit](../usage/configuration/config_documentation.html#media_upload_limits). + +This callback will only be called on workers which handle +[POST /_matrix/media/v3/upload](https://spec.matrix.org/v1.15/client-server-api/#post_matrixmediav3upload) +requests. + +This could be used to inform the user that they have reached a media upload limit through +some external method. + +The arguments passed to this callback are: + +* `user_id`: The Matrix user ID of the user (e.g. `@alice:example.com`) making the request. +* `limit`: The `synapse.module_api.MediaUploadLimit` representing the limit that was reached. +* `sent_bytes`: The number of bytes already sent during the period of the limit. +* `attempted_bytes`: The number of bytes that the user attempted to send. diff --git a/docs/modules/password_auth_provider_callbacks.md b/docs/modules/password_auth_provider_callbacks.md index d66ac7df31..88b22fdf21 100644 --- a/docs/modules/password_auth_provider_callbacks.md +++ b/docs/modules/password_auth_provider_callbacks.md @@ -23,12 +23,7 @@ async def check_auth( user: str, login_type: str, login_dict: "synapse.module_api.JsonDict", -) -> Optional[ - Tuple[ - str, - Optional[Callable[["synapse.module_api.LoginResponse"], Awaitable[None]]] - ] -] +) -> tuple[str, Callable[["synapse.module_api.LoginResponse"], Awaitable[None]] | None] | None ``` The login type and field names should be provided by the user in the @@ -67,12 +62,7 @@ async def check_3pid_auth( medium: str, address: str, password: str, -) -> Optional[ - Tuple[ - str, - Optional[Callable[["synapse.module_api.LoginResponse"], Awaitable[None]]] - ] -] +) -> tuple[str, Callable[["synapse.module_api.LoginResponse"], Awaitable[None]] | None] ``` Called when a user attempts to register or log in with a third party identifier, @@ -98,7 +88,7 @@ _First introduced in Synapse v1.46.0_ ```python async def on_logged_out( user_id: str, - device_id: Optional[str], + device_id: str | None, access_token: str ) -> None ``` @@ -119,7 +109,7 @@ _First introduced in Synapse v1.52.0_ async def get_username_for_registration( uia_results: Dict[str, Any], params: Dict[str, Any], -) -> Optional[str] +) -> str | None ``` Called when registering a new user. The module can return a username to set for the user @@ -180,7 +170,7 @@ _First introduced in Synapse v1.54.0_ async def get_displayname_for_registration( uia_results: Dict[str, Any], params: Dict[str, Any], -) -> Optional[str] +) -> str | None ``` Called when registering a new user. The module can return a display name to set for the @@ -259,12 +249,7 @@ class MyAuthProvider: username: str, login_type: str, login_dict: "synapse.module_api.JsonDict", - ) -> Optional[ - Tuple[ - str, - Optional[Callable[["synapse.module_api.LoginResponse"], Awaitable[None]]], - ] - ]: + ) -> tuple[str, Callable[["synapse.module_api.LoginResponse"], Awaitable[None]] | None] | None: if login_type != "my.login_type": return None @@ -276,12 +261,7 @@ class MyAuthProvider: username: str, login_type: str, login_dict: "synapse.module_api.JsonDict", - ) -> Optional[ - Tuple[ - str, - Optional[Callable[["synapse.module_api.LoginResponse"], Awaitable[None]]], - ] - ]: + ) -> tuple[str, Callable[["synapse.module_api.LoginResponse"], Awaitable[None]] | None] | None: if login_type != "m.login.password": return None diff --git a/docs/modules/presence_router_callbacks.md b/docs/modules/presence_router_callbacks.md index b210f0e3cd..f865e79f53 100644 --- a/docs/modules/presence_router_callbacks.md +++ b/docs/modules/presence_router_callbacks.md @@ -23,7 +23,7 @@ _First introduced in Synapse v1.42.0_ ```python async def get_users_for_states( state_updates: Iterable["synapse.api.UserPresenceState"], -) -> Dict[str, Set["synapse.api.UserPresenceState"]] +) -> dict[str, set["synapse.api.UserPresenceState"]] ``` **Requires** `get_interested_users` to also be registered @@ -45,7 +45,7 @@ _First introduced in Synapse v1.42.0_ ```python async def get_interested_users( user_id: str -) -> Union[Set[str], "synapse.module_api.PRESENCE_ALL_USERS"] +) -> set[str] | "synapse.module_api.PRESENCE_ALL_USERS" ``` **Requires** `get_users_for_states` to also be registered @@ -73,7 +73,7 @@ that `@alice:example.org` receives all presence updates from `@bob:example.com` `@charlie:somewhere.org`, regardless of whether Alice shares a room with any of them. ```python -from typing import Dict, Iterable, Set, Union +from typing import Iterable from synapse.module_api import ModuleApi @@ -90,7 +90,7 @@ class CustomPresenceRouter: async def get_users_for_states( self, state_updates: Iterable["synapse.api.UserPresenceState"], - ) -> Dict[str, Set["synapse.api.UserPresenceState"]]: + ) -> dict[str, set["synapse.api.UserPresenceState"]]: res = {} for update in state_updates: if ( @@ -104,7 +104,7 @@ class CustomPresenceRouter: async def get_interested_users( self, user_id: str, - ) -> Union[Set[str], "synapse.module_api.PRESENCE_ALL_USERS"]: + ) -> set[str] | "synapse.module_api.PRESENCE_ALL_USERS": if user_id == "@alice:example.com": return {"@bob:example.com", "@charlie:somewhere.org"} diff --git a/docs/modules/ratelimit_callbacks.md b/docs/modules/ratelimit_callbacks.md index 30d94024fa..048bdc6f9e 100644 --- a/docs/modules/ratelimit_callbacks.md +++ b/docs/modules/ratelimit_callbacks.md @@ -11,7 +11,7 @@ The available ratelimit callbacks are: _First introduced in Synapse v1.132.0_ ```python -async def get_ratelimit_override_for_user(user: str, limiter_name: str) -> Optional[synapse.module_api.RatelimitOverride] +async def get_ratelimit_override_for_user(user: str, limiter_name: str) -> synapse.module_api.RatelimitOverride | None ``` ** diff --git a/docs/modules/spam_checker_callbacks.md b/docs/modules/spam_checker_callbacks.md index 49b7e06bb3..0d261e844f 100644 --- a/docs/modules/spam_checker_callbacks.md +++ b/docs/modules/spam_checker_callbacks.md @@ -195,12 +195,15 @@ _Changed in Synapse v1.132.0: Added the `room_config` argument. Callbacks that o async def user_may_create_room(user_id: str, room_config: synapse.module_api.JsonDict) -> Union["synapse.module_api.NOT_SPAM", "synapse.module_api.errors.Codes", bool] ``` -Called when processing a room creation request. +Called when processing a room creation or room upgrade request. The arguments passed to this callback are: * `user_id`: The Matrix user ID of the user (e.g. `@alice:example.com`). -* `room_config`: The contents of the body of a [/createRoom request](https://spec.matrix.org/latest/client-server-api/#post_matrixclientv3createroom) as a dictionary. +* `room_config`: The contents of the body of the [`/createRoom` request](https://spec.matrix.org/v1.15/client-server-api/#post_matrixclientv3createroom) as a dictionary. + For a [room upgrade request](https://spec.matrix.org/v1.15/client-server-api/#post_matrixclientv3roomsroomidupgrade) it is a synthesised subset of what an equivalent + `/createRoom` request would have looked like. Specifically, it contains the `creation_content` (linking to the previous room) and `initial_state` (containing a + subset of the state of the previous room). The callback must return one of: - `synapse.module_api.NOT_SPAM`, to allow the operation. Other callbacks may still @@ -328,9 +331,9 @@ search results; otherwise return `False`. The profile is represented as a dictionary with the following keys: * `user_id: str`. The Matrix ID for this user. -* `display_name: Optional[str]`. The user's display name, or `None` if this user +* `display_name: str | None`. The user's display name, or `None` if this user has not set a display name. -* `avatar_url: Optional[str]`. The `mxc://` URL to the user's avatar, or `None` +* `avatar_url: str | None`. The `mxc://` URL to the user's avatar, or `None` if this user has not set an avatar. The module is given a copy of the original dictionary, so modifying it from within the @@ -349,10 +352,10 @@ _First introduced in Synapse v1.37.0_ ```python async def check_registration_for_spam( - email_threepid: Optional[dict], - username: Optional[str], + email_threepid: dict | None, + username: str | None, request_info: Collection[Tuple[str, str]], - auth_provider_id: Optional[str] = None, + auth_provider_id: str | None = None, ) -> "synapse.spam_checker_api.RegistrationBehaviour" ``` @@ -435,10 +438,10 @@ _First introduced in Synapse v1.87.0_ ```python async def check_login_for_spam( user_id: str, - device_id: Optional[str], - initial_display_name: Optional[str], - request_info: Collection[Tuple[Optional[str], str]], - auth_provider_id: Optional[str] = None, + device_id: str | None, + initial_display_name: str | None, + request_info: Collection[tuple[str | None, str]], + auth_provider_id: str | None = None, ) -> Union["synapse.module_api.NOT_SPAM", "synapse.module_api.errors.Codes"] ``` @@ -506,7 +509,7 @@ class ListSpamChecker: resource=IsUserEvilResource(config), ) - async def check_event_for_spam(self, event: "synapse.events.EventBase") -> Union[Literal["NOT_SPAM"], Codes]: + async def check_event_for_spam(self, event: "synapse.events.EventBase") -> Literal["NOT_SPAM"] | Codes: if event.sender in self.evil_users: return Codes.FORBIDDEN else: diff --git a/docs/modules/third_party_rules_callbacks.md b/docs/modules/third_party_rules_callbacks.md index b97e28db11..1474b2dfd5 100644 --- a/docs/modules/third_party_rules_callbacks.md +++ b/docs/modules/third_party_rules_callbacks.md @@ -16,7 +16,7 @@ _First introduced in Synapse v1.39.0_ async def check_event_allowed( event: "synapse.events.EventBase", state_events: "synapse.types.StateMap", -) -> Tuple[bool, Optional[dict]] +) -> tuple[bool, dict | None] ``` ** @@ -340,7 +340,7 @@ class EventCensorer: self, event: "synapse.events.EventBase", state_events: "synapse.types.StateMap", - ) -> Tuple[bool, Optional[dict]]: + ) -> Tuple[bool, dict | None]: event_dict = event.get_dict() new_event_content = await self.api.http_client.post_json_get_json( uri=self._endpoint, post_json=event_dict, diff --git a/docs/openid.md b/docs/openid.md index f86ba189c7..e91d375c41 100644 --- a/docs/openid.md +++ b/docs/openid.md @@ -50,6 +50,11 @@ setting in your configuration file. See the [configuration manual](usage/configuration/config_documentation.md#oidc_providers) for some sample settings, as well as the text below for example configurations for specific providers. +For setups using [`.well-known` delegation](delegate.md), make sure +[`public_baseurl`](usage/configuration/config_documentation.md#public_baseurl) is set +appropriately. If unset, Synapse defaults to `https:///` which is used in +the OIDC callback URL. + ## OIDC Back-Channel Logout Synapse supports receiving [OpenID Connect Back-Channel Logout](https://openid.net/specs/openid-connect-backchannel-1_0.html) notifications. @@ -186,6 +191,7 @@ oidc_providers: 4. Note the slug of your application, Client ID and Client Secret. Note: RSA keys must be used for signing for Authentik, ECC keys do not work. +Note: The provider must have a signing key set and must not use an encryption key. Synapse config: ```yaml @@ -204,6 +210,12 @@ oidc_providers: config: localpart_template: "{{ user.preferred_username }}" display_name_template: "{{ user.preferred_username|capitalize }}" # TO BE FILLED: If your users have names in Authentik and you want those in Synapse, this should be replaced with user.name|capitalize. +[...] +jwt_config: + enabled: true + secret: "your client secret" # TO BE FILLED (same as `client_secret` above) + algorithm: "RS256" + # (...other fields) ``` ### Dex diff --git a/docs/presence_router_module.md b/docs/presence_router_module.md index face54fe2b..092b566c5f 100644 --- a/docs/presence_router_module.md +++ b/docs/presence_router_module.md @@ -76,7 +76,7 @@ possible. #### `get_interested_users` ```python -async def get_interested_users(self, user_id: str) -> Union[Set[str], str] +async def get_interested_users(self, user_id: str) -> set[str] | str ``` **Required.** An asynchronous method that is passed a single Matrix User ID. This @@ -182,7 +182,7 @@ class ExamplePresenceRouter: async def get_interested_users( self, user_id: str, - ) -> Union[Set[str], PresenceRouter.ALL_USERS]: + ) -> set[str] | PresenceRouter.ALL_USERS: """ Retrieve a list of users that `user_id` is interested in receiving the presence of. This will be in addition to those they share a room with. diff --git a/docs/reverse_proxy.md b/docs/reverse_proxy.md index f871a39939..0e3303df57 100644 --- a/docs/reverse_proxy.md +++ b/docs/reverse_proxy.md @@ -86,6 +86,45 @@ server { } ``` +### Nginx Proxy Manager or NPMPlus + +```nginx +Add New Proxy-Host + - Tab Details + - Domain Names: matrix.example.com + - Scheme: http + - Forward Hostname / IP: localhost # IP address or hostname where Synapse is hosted. Bare-metal or Container. + - Forward Port: 8008 + + - Tab Custom locations + - Add Location + - Define Location: /_matrix + - Scheme: http + - Forward Hostname / IP: localhost # IP address or hostname where Synapse is hosted. Bare-metal or Container. + - Forward Port: 8008 + - Click on the gear icon to display a custom configuration field. Increase client_max_body_size to match max_upload_size defined in homeserver.yaml + - Enter this in the Custom Field: client_max_body_size 50M; + + - Tab SSL/TLS + - Choose your SSL/TLS certificate and preferred settings. + + - Tab Advanced + - Enter this in the Custom Field. This means that port 8448 no longer needs to be opened in your Firewall. + The Federation communication use now Port 443. + + location /.well-known/matrix/server { + return 200 '{"m.server": "matrix.example.com:443"}'; + add_header Content-Type application/json; + } + + location /.well-known/matrix/client { + return 200 '{"m.homeserver": {"base_url": "https://matrix.example.com"}}'; + add_header Content-Type application/json; + add_header "Access-Control-Allow-Origin" *; + } + +``` + ### Caddy v2 ``` diff --git a/docs/sample_config.yaml b/docs/sample_config.yaml index 0d75e6d4a1..470e44a8ed 100644 --- a/docs/sample_config.yaml +++ b/docs/sample_config.yaml @@ -24,14 +24,18 @@ server_name: "SERVERNAME" pid_file: DATADIR/homeserver.pid listeners: - - port: 8008 + - bind_addresses: + - ::1 + - 127.0.0.1 + port: 8008 + resources: + - compress: false + names: + - client + - federation tls: false type: http x_forwarded: true - bind_addresses: ['::1', '127.0.0.1'] - resources: - - names: [client, federation] - compress: false database: name: sqlite3 args: diff --git a/docs/setup/installation.md b/docs/setup/installation.md index 0840f532b0..c887f9900c 100644 --- a/docs/setup/installation.md +++ b/docs/setup/installation.md @@ -16,8 +16,15 @@ that your email address is probably `user@example.com` rather than `user@email.example.com`) - but doing so may require more advanced setup: see [Setting up Federation](../federate.md). +⚠️ Before setting up Synapse please consult the [security page](security.md) for +best practices. ⚠️ + ## Installing Synapse +Note: Synapse uses a number of platform dependencies such as Python and PostgreSQL, +and aims to follow supported upstream versions. See the [deprecation +policy](../deprecation_policy.md) for more details. + ### Prebuilt packages Prebuilt packages are available for a number of platforms. These are recommended @@ -87,17 +94,13 @@ file when you upgrade the Debian package to a later version. Andrej Shadura maintains a [`matrix-synapse`](https://packages.debian.org/sid/matrix-synapse) package in the Debian repositories. -For `bookworm` and `sid`, it can be installed simply with: +For `forky` (14) and `sid` (rolling release), it can be installed simply with: ```sh sudo apt install matrix-synapse ``` -Synapse is also available in `bullseye-backports`. Please -see the [Debian documentation](https://backports.debian.org/Instructions/) -for information on how to use backports. - -`matrix-synapse` is no longer maintained for `buster` and older. +The downstream Debian `matrix-synapse` package is not available for `trixie` (13) and older. Consider using the Matrix.org packages (above). ##### Downstream Ubuntu packages @@ -208,7 +211,7 @@ When following this route please make sure that the [Platform-specific prerequis System requirements: - POSIX-compliant system (tested on Linux & OS X) -- Python 3.9 or later, up to Python 3.13. +- Python 3.10 or later, up to Python 3.13. - At least 1GB of free RAM if you want to join large public rooms like #matrix:matrix.org If building on an uncommon architecture for which pre-built wheels are @@ -226,6 +229,11 @@ pip install --upgrade setuptools pip install matrix-synapse ``` +If you want to use a logging configuration that references +`systemd.journal.JournalHandler` (for example `contrib/systemd/log_config.yaml`), +you must install `systemd-python` separately in the same environment. +Synapse no longer provides a `matrix-synapse[systemd]` extra. + This will download Synapse from [PyPI](https://pypi.org/project/matrix-synapse) and install it, along with the python libraries it uses, into a virtual environment under `~/synapse/env`. Feel free to pick a different directory if you @@ -311,11 +319,16 @@ sudo dnf group install "Development Tools" ##### Red Hat Enterprise Linux / Rocky Linux / Oracle Linux -*Note: The term "RHEL" below refers to Red Hat Enterprise Linux, Oracle Linux and Rocky Linux. The distributions are 1:1 binary compatible.* +*Note: The term "RHEL" below refers to Red Hat Enterprise Linux, Oracle Linux and Rocky Linux. +The distributions are 1:1 binary compatible.* It's recommended to use the latest Python versions. -RHEL 8 in particular ships with Python 3.6 by default which is EOL and therefore no longer supported by Synapse. RHEL 9 ships with Python 3.9 which is still supported by the Python core team as of this writing. However, newer Python versions provide significant performance improvements and they're available in official distributions' repositories. Therefore it's recommended to use them. +RHEL 8 & 9 in particular ship with Python 3.6 & 3.9 respectively by default +which are EOL and therefore no longer supported by Synapse. +However, newer Python versions provide significant performance improvements +and they're available in official distributions' repositories. +Therefore it's recommended to use them. Python 3.11 and 3.12 are available for both RHEL 8 and 9. diff --git a/docs/setup/security.md b/docs/setup/security.md new file mode 100644 index 0000000000..2c21b494e5 --- /dev/null +++ b/docs/setup/security.md @@ -0,0 +1,41 @@ +# Security + +This page lays out security best-practices when running Synapse. + +If you believe you have encountered a security issue, see our [Security +Disclosure Policy](https://element.io/en/security/security-disclosure-policy). + +## Content repository + +Matrix serves raw, user-supplied data in some APIs — specifically the [content +repository endpoints](https://matrix.org/docs/spec/client_server/latest.html#get-matrix-media-r0-download-servername-mediaid). + +Whilst we make a reasonable effort to mitigate against XSS attacks (for +instance, by using [CSP](https://github.com/matrix-org/synapse/pull/1021)), a +Matrix homeserver should not be hosted on a domain hosting other web +applications. This especially applies to sharing the domain with Matrix web +clients and other sensitive applications like webmail. See +https://developer.github.com/changes/2014-04-25-user-content-security for more +information. + +Ideally, the homeserver should not simply be on a different subdomain, but on a +completely different [registered +domain](https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-2.3) +(also known as top-level site or eTLD+1). This is because [some +attacks](https://en.wikipedia.org/wiki/Session_fixation#Attacks_using_cross-subdomain_cookie) +are still possible as long as the two applications share the same registered +domain. + + +To illustrate this with an example, if your Element Web or other sensitive web +application is hosted on `A.example1.com`, you should ideally host Synapse on +`example2.com`. Some amount of protection is offered by hosting on +`B.example1.com` instead, so this is also acceptable in some scenarios. +However, you should *not* host your Synapse on `A.example1.com`. + +Note that all of the above refers exclusively to the domain used in Synapse's +`public_baseurl` setting. In particular, it has no bearing on the domain +mentioned in MXIDs hosted on that server. + +Following this advice ensures that even if an XSS is found in Synapse, the +impact to other applications will be minimal. diff --git a/docs/structured_logging.md b/docs/structured_logging.md index 002565b223..761d6466dd 100644 --- a/docs/structured_logging.md +++ b/docs/structured_logging.md @@ -35,7 +35,7 @@ handlers: loggers: synapse: level: INFO - handlers: [remote] + handlers: [file] synapse.storage.SQL: level: WARNING ``` diff --git a/docs/upgrade.md b/docs/upgrade.md index 082d204b58..aeae82c114 100644 --- a/docs/upgrade.md +++ b/docs/upgrade.md @@ -117,6 +117,151 @@ each upgrade are complete before moving on to the next upgrade, to avoid stacking them up. You can monitor the currently running background updates with [the Admin API](usage/administration/admin_api/background_updates.html#status). +# Upgrading to v1.150.0 + +## Removal of the `systemd` pip extra + +The `matrix-synapse[systemd]` pip extra has been removed. +If you use `systemd.journal.JournalHandler` in your logging configuration +(e.g. `contrib/systemd/log_config.yaml`), you must now install +`systemd-python` manually in Synapse's runtime environment: + +```bash +pip install systemd-python +``` + +No action is needed if you do not use journal logging, or if you installed +Synapse from the Debian packages (which handle this automatically). + +## Module API: Deprecation of the `deactivation` parameter in the `set_displayname` method + +If you have Synapse modules installed that use the `set_displayname` method to change +the display name of your users, please ensure that it doesn't pass the optional +`deactivation` parameter. + +This parameter is now deprecated and it is intended to be removed in 2027. +No immediate change is necessary, however once the parameter is removed, modules passing it will produce errors. +[Issue #19546](https://github.com/element-hq/synapse/issues/19546) tracks this removal. + +From this version, when the parameter is passed, an error such as +``Deprecated `deactivation` parameter passed to `set_displayname` Module API (value: False). This will break in 2027.`` will be logged. The method will otherwise continue to work. + +## Updated request log format (`Processed request: ...`) + +The [request log format](usage/administration/request_log.md) has slightly changed to +include `ru=(...)` and `db=(...)` labels to better disambiguate the number groupings. +Previously, these values appeared without labels. + +This only matters if you have third-party tooling that parses the Synapse logs. + +# Upgrading to v1.146.0 + +## Drop support for Ubuntu 25.04 Plucky Puffin, and add support for 25.10 Questing Quokka + +Ubuntu 25.04 Plucky Puffin [is end-of-life as of 17 Jan +2026](https://endoflife.date/ubuntu). This release drops support for Ubuntu +25.04, and in its place adds support for Ubuntu 25.10 Questing Quokka. + +## Removal of MSC2697 (Legacy) Dehydrated devices + +The endpoints for +[MSC2697](https://github.com/matrix-org/matrix-spec-proposals/pull/2697) have now +been removed, since the MSC is closed. Developers who rely on this feature should +migrate to [MSC3814](https://github.com/matrix-org/matrix-spec-proposals/pull/3814) +which introduces support for a newer version of dehydrated devices. + +# Upgrading to v1.144.0 + +## Worker support for unstable MSC4140 `/restart` endpoint + +The following unstable endpoint pattern may now be routed to worker processes: + +``` +^/_matrix/client/unstable/org.matrix.msc4140/delayed_events/.*/restart$ +``` + +## Unstable mutual rooms endpoint is now behind an experimental feature flag + +The unstable mutual rooms endpoint from +[MSC2666](https://github.com/matrix-org/matrix-spec-proposals/pull/2666) +(`/_matrix/client/unstable/uk.half-shot.msc2666/user/mutual_rooms`) is now +disabled by default. If you rely on this unstable endpoint, you must now set +`experimental_features.msc2666_enabled: true` in your configuration to keep +using it. + +# Upgrading to v1.143.0 + +## Dropping support for PostgreSQL 13 + +In line with our [deprecation policy](deprecation_policy.md), we've dropped +support for PostgreSQL 13, as it is no longer supported upstream. +This release of Synapse requires PostgreSQL 14+. + +# Upgrading to v1.142.0 + +## Python 3.10+ is now required + +The minimum supported Python version has been increased from v3.9 to v3.10. +You will need Python 3.10+ to run Synapse v1.142.0. + +If you use current versions of the +[matrixorg/synapse](setup/installation.html#docker-images-and-ansible-playbooks) +Docker images, no action is required. + +## SQLite 3.40.0+ is now required + +The minimum supported SQLite version has been increased from 3.27.0 to 3.40.0. + +If you use current versions of the +[matrixorg/synapse](setup/installation.html#docker-images-and-ansible-playbooks) +Docker images, no action is required. + + +# Upgrading to v1.141.0 + +## Docker images now based on Debian `trixie` with Python 3.13 + +The Docker images are now based on Debian `trixie` and use Python 3.13. If you +are using the Docker images as a base image you may need to e.g. adjust the +paths you mount any additional Python packages at. + +# Upgrading to v1.140.0 + +## Users of `synapse-s3-storage-provider` must update the module to `v1.6.0` + +Deployments that make use of the +[synapse-s3-storage-provider](https://github.com/matrix-org/synapse-s3-storage-provider/) +module must update it to +[v1.6.0](https://github.com/matrix-org/synapse-s3-storage-provider/releases/tag/v1.6.0), +otherwise users will be unable to upload or download media. + +# Upgrading to v1.139.0 + +## `/register` requests from old application service implementations may break when using MAS + +Application Services that do not set `inhibit_login=true` when calling `POST +/_matrix/client/v3/register` will receive the error +`IO.ELEMENT.MSC4190.M_APPSERVICE_LOGIN_UNSUPPORTED` in response. This is a +result of [MSC4190: Device management for application +services](https://github.com/matrix-org/matrix-spec-proposals/pull/4190) which +adds new endpoints for application services to create encryption-ready devices +with other than `/login` or `/register` without `inhibit_login=true`. + +If an application service you use starts to fail with the mentioned error, +ensure it is up to date. If it is, then kindly let the author know that they +need to update their implementation to call `/register` with +`inhibit_login=true`. + +# Upgrading to v1.138.2 + +## Drop support for Ubuntu 24.10 Oracular Oriole, and add support for Ubuntu 25.04 Plucky Puffin + +Ubuntu 24.10 Oracular Oriole [has been end-of-life since 10 Jul +2025](https://endoflife.date/ubuntu). This release drops support for Ubuntu +24.10, and in its place adds support for Ubuntu 25.04 Plucky Puffin. + +This notice also applies to the v1.139.0 release. + # Upgrading to v1.136.0 ## Deprecate `run_as_background_process` exported as part of the module API interface in favor of `ModuleApi.run_as_background_process` @@ -736,7 +881,7 @@ the names of Prometheus metrics. If you want to test your changes before legacy names are disabled by default, you may specify `enable_legacy_metrics: false` in your homeserver configuration. -A list of affected metrics is available on the [Metrics How-to page](https://element-hq.github.io/synapse/v1.69/metrics-howto.html?highlight=metrics%20deprecated#renaming-of-metrics--deprecation-of-old-names-in-12). +A list of affected metrics is available on the [Metrics How-to page](https://element-hq.github.io/synapse/v1.69/metrics-howto.html#renaming-of-metrics--deprecation-of-old-names-in-12). ## Deprecation of the `generate_short_term_login_token` module API method @@ -2331,7 +2476,7 @@ back to v1.3.1, subject to the following: Some counter metrics have been renamed, with the old names deprecated. See [the metrics -documentation](metrics-howto.md#renaming-of-metrics--deprecation-of-old-names-in-12) +documentation](https://element-hq.github.io/synapse/v1.69/metrics-howto.html#renaming-of-metrics--deprecation-of-old-names-in-12) for details. # Upgrading to v1.1.0 diff --git a/docs/usage/administration/request_log.md b/docs/usage/administration/request_log.md index 6154108934..7e3047eb62 100644 --- a/docs/usage/administration/request_log.md +++ b/docs/usage/administration/request_log.md @@ -5,8 +5,8 @@ HTTP request logs are written by synapse (see [`synapse/http/site.py`](https://g See the following for how to decode the dense data available from the default logging configuration. ``` -2020-10-01 12:00:00,000 - synapse.access.http.8008 - 311 - INFO - PUT-1000- 192.168.0.1 - 8008 - {another-matrix-server.com} Processed request: 0.100sec/-0.000sec (0.000sec, 0.000sec) (0.001sec/0.090sec/3) 11B !200 "PUT /_matrix/federation/v1/send/1600000000000 HTTP/1.1" "Synapse/1.20.1" [0 dbevts] --AAAAAAAAAAAAAAAAAAAAA- -BBBBBBBBBBBBBBBBBBBBBB- -C- -DD- -EEEEEE- -FFFFFFFFF- -GG- -HHHHHHHHHHHHHHHHHHHHHHH- -IIIIII- -JJJJJJJ- -KKKKKK-, -LLLLLL- -MMMMMMM- -NNNNNN- O -P- -QQ- -RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR- -SSSSSSSSSSSS- -TTTTTT- +2020-10-01 12:00:00,000 - synapse.access.http.8008 - 311 - INFO - PUT-1000- 192.168.0.1 - 8008 - {another-matrix-server.com} Processed request: 0.100sec/-0.000sec ru=(0.000sec, 0.000sec) db=(0.001sec/0.090sec/3) 11B !200 "PUT /_matrix/federation/v1/send/1600000000000 HTTP/1.1" "Synapse/1.20.1" [0 dbevts] +-AAAAAAAAAAAAAAAAAAAAA- -BBBBBBBBBBBBBBBBBBBBBB- -C- -DD- -EEEEEE- -FFFFFFFFF- -GG- -HHHHHHHHHHHHHHHHHHHHHHH- -IIIIII- -JJJJJJJ- -KKKKKK-, -LLLLLL- -MMMMMM- -NNNNNN- O -P- -QQ- -RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR- -SSSSSSSSSSSS- -TTTTTT- ``` diff --git a/docs/usage/configuration/config_documentation.md b/docs/usage/configuration/config_documentation.md index 68303308cd..48f33d5427 100644 --- a/docs/usage/configuration/config_documentation.md +++ b/docs/usage/configuration/config_documentation.md @@ -653,6 +653,8 @@ This setting has the following sub-options: * `endpoint` (string): The URL where Synapse can reach MAS. This *must* have the `discovery` and `oauth` resources mounted. Defaults to `"http://localhost:8080"`. +* `force_http2` (boolean): Force HTTP/2 over plaintext (H2C) when connecting to MAS. MAS supports this natively, but a reverse proxy between Synapse and MAS may not. Defaults to `false`. + * `secret` (string|null): A shared secret that will be used to authenticate requests from and to MAS. * `secret_path` (string|null): Alternative to `secret`, reading the shared secret from a file. The file should be a plain text file, containing only the secret. Synapse reads the secret from the given file once at startup. @@ -956,7 +958,7 @@ server_context: context --- ### `limit_remote_rooms` -*(object)* When this option is enabled, the room "complexity" will be checked before a user joins a new remote room. If it is above the complexity limit, the server will disallow joining, or will instantly leave. This is useful for homeservers that are resource-constrained. Room complexity is an arbitrary measure based on factors such as the number of users in the room. +*(object)* When this option is enabled, the room "complexity" will be checked before a user joins a new remote room. If it is above the complexity limit, the server will disallow joining, or will instantly leave. This is useful for homeservers that are resource-constrained. In Synapse, the complexity of a room is measured by the number of current state events in a room, divided by 500. "Current" here means the latest state, i.e. if a user joins, then leaves, then joins, that will count as 1 current `m.room.member` state event. This setting has the following sub-options: @@ -2006,9 +2008,8 @@ This setting has the following sub-options: Default configuration: ```yaml rc_reports: - per_user: - per_second: 1.0 - burst_count: 5.0 + per_second: 1.0 + burst_count: 5.0 ``` Example configuration: @@ -2031,9 +2032,8 @@ This setting has the following sub-options: Default configuration: ```yaml rc_room_creation: - per_user: - per_second: 0.016 - burst_count: 10.0 + per_second: 0.016 + burst_count: 10.0 ``` Example configuration: @@ -2043,6 +2043,25 @@ rc_room_creation: burst_count: 5.0 ``` --- +### `rc_user_directory` + +*(object)* This option allows admins to ratelimit searches in the user directory. + +_Added in Synapse 1.145.0._ + +This setting has the following sub-options: + +* `per_second` (number): Maximum number of requests a client can send per second. + +* `burst_count` (number): Maximum number of requests a client can send before being throttled. + +Default configuration: +```yaml +rc_user_directory: + per_second: 0.016 + burst_count: 200.0 +``` +--- ### `federation_rr_transactions_per_room_per_second` *(integer)* Sets outgoing federation transaction frequency for sending read-receipts, per-room. @@ -2094,6 +2113,16 @@ Example configuration: enable_media_repo: false ``` --- +### `enable_local_media_storage` + +*(boolean)* Enable the local on-disk media storage provider. When disabled, media is stored only in configured `media_storage_providers` and temporary files are used for processing. +**Warning:** If this option is set to `false` and no `media_storage_providers` are configured, all media requests will return 404 errors as there will be no storage backend available. Defaults to `true`. + +Example configuration: +```yaml +enable_local_media_storage: false +``` +--- ### `media_store_path` *(string)* Directory where uploaded images and attachments are stored. Defaults to `"media_store"`. @@ -2168,9 +2197,12 @@ max_upload_size: 60M ### `media_upload_limits` *(array)* A list of media upload limits defining how much data a given user can upload in a given time period. +These limits are applied in addition to the `max_upload_size` limit above (which applies to individual uploads). An empty list means no limits are applied. +These settings can be overridden using the `get_media_upload_limits_for_user` module API [callback](../../modules/media_repository_callbacks.md#get_media_upload_limits_for_user). + Defaults to `[]`. Example configuration: @@ -2572,6 +2604,28 @@ Example configuration: turn_allow_guests: false ``` --- +### `matrix_rtc` + +*(object)* Options related to MatrixRTC. Defaults to `{}`. + +This setting has the following sub-options: + +* `transports` (array): A list of transport types and arguments to use for MatrixRTC connections. Defaults to `[]`. + + Options for each entry include: + + * `type` (string): The type of transport to use to connect to the selective forwarding unit (SFU). + + * `livekit_service_url` (string): The base URL of the LiveKit service. Should only be used with LiveKit-based transports. + +Example configuration: +```yaml +matrix_rtc: + transports: + - type: livekit + livekit_service_url: https://matrix-rtc.example.com/livekit/jwt +``` +--- ## Registration Registration can be rate-limited using the parameters in the [Ratelimiting](#ratelimiting) section of this manual. @@ -3792,7 +3846,7 @@ This setting has the following sub-options: * `localdb_enabled` (boolean): Set to false to disable authentication against the local password database. This is ignored if `enabled` is false, and is only useful if you have other `password_providers`. Defaults to `true`. -* `pepper` (string|null): Set the value here to a secret random string for extra security. DO NOT CHANGE THIS AFTER INITIAL SETUP! Defaults to `null`. +* `pepper` (string|null): A secret random string that will be appended to user's passwords before they are hashed. This improves the security of short passwords. DO NOT CHANGE THIS AFTER INITIAL SETUP! Defaults to `null`. * `policy` (object): Define and enforce a password policy, such as minimum lengths for passwords, etc. This is an implementation of MSC2000. @@ -4432,7 +4486,7 @@ stream_writers: --- ### `outbound_federation_restricted_to` -*(array)* When using workers, you can restrict outbound federation traffic to only go through a specific subset of workers. Any worker specified here must also be in the [`instance_map`](#instance_map). [`worker_replication_secret`](#worker_replication_secret) must also be configured to authorize inter-worker communication. +*(array)* You can restrict outbound federation traffic to only go through a specific subset of workers including the [Secure Border Gateway (SBG)](https://element.io/en/server-suite/secure-border-gateways). Any worker specified here (including the SBG) must also be in the [`instance_map`](#instance_map). [`worker_replication_secret`](#worker_replication_secret) must also be configured to authorize inter-worker communication. Also see the [worker documentation](../../workers.md#restrict-outbound-federation-traffic-to-a-specific-set-of-workers) for more info. diff --git a/docs/usage/configuration/logging_sample_config.md b/docs/usage/configuration/logging_sample_config.md index 23a55abdcc..9cc96df73c 100644 --- a/docs/usage/configuration/logging_sample_config.md +++ b/docs/usage/configuration/logging_sample_config.md @@ -14,6 +14,9 @@ It should be named `.log.config` by default. Hint: If you're looking for a guide on what each of the fields in the "Processed request" log lines mean, see [Request log format](../administration/request_log.md). +If you use `systemd.journal.JournalHandler` in your own logging config, ensure +`systemd-python` is installed in Synapse's runtime environment. + ```yaml {{#include ../../sample_log_config.yaml}} ``` diff --git a/docs/website_files/README.md b/docs/website_files/README.md index bc51c4865e..b5521997d5 100644 --- a/docs/website_files/README.md +++ b/docs/website_files/README.md @@ -9,27 +9,18 @@ point to additional JS/CSS in this directory that are added on each page load. I addition, the `theme` directory contains files that overwrite their counterparts in each of the default themes included with mdbook. -Currently we use these files to generate a floating Table of Contents panel. The code for -which was partially taken from -[JorelAli/mdBook-pagetoc](https://github.com/JorelAli/mdBook-pagetoc/) -before being modified such that it scrolls with the content of the page. This is handled -by the `table-of-contents.js/css` files. The table of contents panel only appears on pages -that have more than one header, as well as only appearing on desktop-sized monitors. +Currently we use these files to make a few modifications: -We remove the navigation arrows which typically appear on the left and right side of the -screen on desktop as they interfere with the table of contents. This is handled by -the `remove-nav-buttons.css` file. +* We stylise the chapter titles in the left sidebar by indenting them + slightly so that they are more visually distinguishable from the section headers + (the bold titles). This is done through the `indent-section-headers.css` file. -Finally, we also stylise the chapter titles in the left sidebar by indenting them -slightly so that they are more visually distinguishable from the section headers -(the bold titles). This is done through the `indent-section-headers.css` file. - -In addition to these modifications, we have added a version picker to the documentation. -Users can switch between documentations for different versions of Synapse. -This functionality was implemented through the `version-picker.js` and -`version-picker.css` files. +* We add a version picker pertaining to the different documentation versions + shipped with each version of Synapse. This functionality was implemented through + the `version-picker.js` and `version-picker.css` files, and is currently the only + requirement for the custom `theme/`. More information can be found in mdbook's official documentation for [injecting page JS/CSS](https://rust-lang.github.io/mdBook/format/config.html) and -[customising the default themes](https://rust-lang.github.io/mdBook/format/theme/index.html). \ No newline at end of file +[customising the default themes](https://rust-lang.github.io/mdBook/format/theme/index.html). diff --git a/docs/website_files/remove-nav-buttons.css b/docs/website_files/remove-nav-buttons.css deleted file mode 100644 index 4b280794ea..0000000000 --- a/docs/website_files/remove-nav-buttons.css +++ /dev/null @@ -1,8 +0,0 @@ -/* Remove the prev, next chapter buttons as they interfere with the - * table of contents. - * Note that the table of contents only appears on desktop, thus we - * only remove the desktop (wide) chapter buttons. - */ -.nav-wide-wrapper { - display: none -} \ No newline at end of file diff --git a/docs/website_files/table-of-contents.css b/docs/website_files/table-of-contents.css deleted file mode 100644 index 1b6f44b66a..0000000000 --- a/docs/website_files/table-of-contents.css +++ /dev/null @@ -1,47 +0,0 @@ -:root { - --pagetoc-width: 250px; -} - -@media only screen and (max-width:1439px) { - .sidetoc { - display: none; - } -} - -@media only screen and (min-width:1440px) { - main { - position: relative; - margin-left: 100px !important; - margin-right: var(--pagetoc-width) !important; - } - .sidetoc { - margin-left: auto; - margin-right: auto; - left: calc(100% + (var(--content-max-width))/4 - 140px); - position: absolute; - text-align: right; - } - .pagetoc { - position: fixed; - width: var(--pagetoc-width); - overflow: auto; - right: 20px; - height: calc(100% - var(--menu-bar-height)); - } - .pagetoc a { - color: var(--fg) !important; - display: block; - padding: 5px 15px 5px 10px; - text-align: left; - text-decoration: none; - } - .pagetoc a:hover, - .pagetoc a.active { - background: var(--sidebar-bg) !important; - color: var(--sidebar-fg) !important; - } - .pagetoc .active { - background: var(--sidebar-bg); - color: var(--sidebar-fg); - } -} diff --git a/docs/website_files/table-of-contents.js b/docs/website_files/table-of-contents.js deleted file mode 100644 index 772da97fb9..0000000000 --- a/docs/website_files/table-of-contents.js +++ /dev/null @@ -1,148 +0,0 @@ -const getPageToc = () => document.getElementsByClassName('pagetoc')[0]; - -const pageToc = getPageToc(); -const pageTocChildren = [...pageToc.children]; -const headers = [...document.getElementsByClassName('header')]; - - -// Select highlighted item in ToC when clicking an item -pageTocChildren.forEach(child => { - child.addEventHandler('click', () => { - pageTocChildren.forEach(child => { - child.classList.remove('active'); - }); - child.classList.add('active'); - }); -}); - - -/** - * Test whether a node is in the viewport - */ -function isInViewport(node) { - const rect = node.getBoundingClientRect(); - return rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth); -} - - -/** - * Set a new ToC entry. - * Clear any previously highlighted ToC items, set the new one, - * and adjust the ToC scroll position. - */ -function setTocEntry() { - let activeEntry; - const pageTocChildren = [...getPageToc().children]; - - // Calculate which header is the current one at the top of screen - headers.forEach(header => { - if (window.pageYOffset >= header.offsetTop) { - activeEntry = header; - } - }); - - // Update selected item in ToC when scrolling - pageTocChildren.forEach(child => { - if (activeEntry.href.localeCompare(child.href) === 0) { - child.classList.add('active'); - } else { - child.classList.remove('active'); - } - }); - - let tocEntryForLocation = document.querySelector(`nav a[href="${activeEntry.href}"]`); - if (tocEntryForLocation) { - const headingForLocation = document.querySelector(activeEntry.hash); - if (headingForLocation && isInViewport(headingForLocation)) { - // Update ToC scroll - const nav = getPageToc(); - const content = document.querySelector('html'); - if (content.scrollTop !== 0) { - nav.scrollTo({ - top: tocEntryForLocation.offsetTop - 100, - left: 0, - behavior: 'smooth', - }); - } else { - nav.scrollTop = 0; - } - } - } -} - - -/** - * Populate sidebar on load - */ -window.addEventListener('load', () => { - // Prevent rendering the table of contents of the "print book" page, as it - // will end up being rendered into the output (in a broken-looking way) - - // Get the name of the current page (i.e. 'print.html') - const pageNameExtension = window.location.pathname.split('/').pop(); - - // Split off the extension (as '.../print' is also a valid page name), which - // should result in 'print' - const pageName = pageNameExtension.split('.')[0]; - if (pageName === "print") { - // Don't render the table of contents on this page - return; - } - - // Only create table of contents if there is more than one header on the page - if (headers.length <= 1) { - return; - } - - // Create an entry in the page table of contents for each header in the document - headers.forEach((header, index) => { - const link = document.createElement('a'); - - // Indent shows hierarchy - let indent = '0px'; - switch (header.parentElement.tagName) { - case 'H1': - indent = '5px'; - break; - case 'H2': - indent = '20px'; - break; - case 'H3': - indent = '30px'; - break; - case 'H4': - indent = '40px'; - break; - case 'H5': - indent = '50px'; - break; - case 'H6': - indent = '60px'; - break; - default: - break; - } - - let tocEntry; - if (index == 0) { - // Create a bolded title for the first element - tocEntry = document.createElement("strong"); - tocEntry.innerHTML = header.text; - } else { - // All other elements are non-bold - tocEntry = document.createTextNode(header.text); - } - link.appendChild(tocEntry); - - link.style.paddingLeft = indent; - link.href = header.href; - pageToc.appendChild(link); - }); - setTocEntry.call(); -}); - - -// Handle active headers on scroll, if there is more than one header on the page -if (headers.length > 1) { - window.addEventListener('scroll', setTocEntry); -} diff --git a/docs/website_files/theme/index.hbs b/docs/website_files/theme/index.hbs index 9cf7521e80..3126184c9b 100644 --- a/docs/website_files/theme/index.hbs +++ b/docs/website_files/theme/index.hbs @@ -1,11 +1,11 @@ - + {{ title }} {{#if is_print }} - + {{/if}} {{#if base_url}} @@ -15,60 +15,78 @@ {{> head}} - - + {{#if favicon_svg}} - + {{/if}} {{#if favicon_png}} - + {{/if}} - - - + + + {{#if print_enable}} - + {{/if}} - - {{#if copy_fonts}} - - {{/if}} + - - - + + + {{#each additional_css}} - + {{/each}} {{#if mathjax_support}} - + {{/if}} + + + + + - - - +
+
+

Keyboard shortcuts

+
+

Press or to navigate between chapters

+ {{#if search_enabled}} +

Press S or / to search in the book

+ {{/if}} +

Press ? to show this help

+

Press Esc to hide this help

+
+
+
+
- - + + - -