From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [IPv6:2a0f:8001:1:32::40]) by lore.proxmox.com (Postfix) with ESMTPS id 4D8A61FF09C for ; Mon, 02 Nov 2026 16:07:05 +0100 (CET) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id BEB17220B1; Mon, 02 Nov 2026 15:59:03 +0100 (CET) From: Lukas Wagner To: pbs-devel@lists.proxmox.com, pve-devel@lists.proxmox.com Subject: [PATCH proxmox-backup v6 27/43] docs: notifications: rework matcher sections, describe expression option Date: Mon, 2 Nov 2026 15:57:24 +0100 Message-ID: <20261102145748.411817-28-l.wagner@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20261102145748.411817-1-l.wagner@proxmox.com> References: <20261102145748.411817-1-l.wagner@proxmox.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1793631473766 X-SPAM-LEVEL: Spam detection results: 0 AWL -0.166 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_ASCII_DIVIDERS 0.8 Email that uses ascii formatting dividers and possible spam tricks KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: PB4SJUTH7YDZLFCYK7YEDR5CJMZHOQ5T X-Message-ID-Hash: PB4SJUTH7YDZLFCYK7YEDR5CJMZHOQ5T X-MailFrom: l.wagner@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: In the matcher section, focus on the higher-level concepts first, as this resembles what the user actually has to understand to use the UI. Move configuration options that are used in the configuration file and API to a separate subsection. Furthermore, add a brief section demonstrating the JSON format used by match expressions. Signed-off-by: Lukas Wagner --- Notes: New in v6. docs/notifications.rst | 226 +++++++++++++++++++++++++++++++++-------- 1 file changed, 183 insertions(+), 43 deletions(-) diff --git a/docs/notifications.rst b/docs/notifications.rst index 440c700a4..5c1b66541 100644 --- a/docs/notifications.rst +++ b/docs/notifications.rst @@ -195,63 +195,203 @@ Notification Matchers Notification matchers route notifications to notification targets based on their matching rules. These rules can match certain properties of a -notification, such as the timestamp (``match-calendar``), the severity of the -notification (``match-severity``) or metadata fields (``match-field``). If a -notification is matched by a matcher, all targets configured for the matcher -will receive the notification. +notification, such as the timestamp, the severity of the notification or +metadata fields, as well as arbitrary combinations of these. If a notification +is matched by a matcher, all targets configured for the matcher will receive +the notification. -An arbitrary number of matchers can be created, each with with their own -matching rules and targets to notify. Every target is notified at most once for -every notification, even if the target is used in multiple matchers. +An arbitrary number of matchers can be created, each with their own match rules +and targets to notify. Every target is notified at most once for every +notification, even if the target is used in multiple matchers. -A matcher without rules matches any notification; the configured targets will -always be notified. +Match Rules +^^^^^^^^^^^ + +Notification matchers can be configured in the GUI under *Configuration → +Notifications*. Matchers can be created, modified and deleted from this view. + +When editing a matcher, match rules can be edited under the *Match Rule* tab. +Rules are represented as a tree. Each tree node can either match on properties +of a notification (fields, severity or timestamp) or combine the results of +child nodes (e.g. *All sub-rules match*). Combinator nodes can be nested, which +makes it possible to compose arbitrarily complex matching behavior. + +The following node types are available: + +* **Always match**: Match any notification. + +* **All sub-rules match**: All direct children of this node must match. + +* **Any sub-rule matches**: At least one direct child of this node must match. + +* **Exactly one sub-rule matches**: Exactly one direct child of this node must + match. + +* **Match Field**: Match a metadata field of a notification. This node can + either match if the field value matches one of the values provided, or, + alternatively, if it matches a regular expression. Available fields are + listed in :ref:`notification_events`. + +* **Match Calendar**: Check if the timestamp of a notification is within a + configured time range, based on a selection of weekdays and one contiguous + time range within each day (e.g. Monday to Friday, 09:00 to 17:00). If + multiple time ranges within a day must be matched, use an **Any sub-rule + matches** node with one **Match Calendar** child per time range. + +* **Match Severity**: Match the severity of a notification. The following + severity levels are available: ``info``, ``notice``, ``warning``, ``error`` + and ``unknown``. Each **Match Severity** node can specify multiple severity + levels it matches on, for instance ``info`` and ``notice``. + +Each node in the tree can be inverted by checking **Invert Rule**. For instance, +for a **Match Severity** node matching on ``info``, checking **Invert Rule** +lets the node match on ``notice``, ``warning``, ``error`` and ``unknown``. + +Under the *Targets to Notify* tab, one or more notification targets can be +selected. All selected targets are notified if a notification is matched. + +Matcher Configuration Options +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This section gives an overview of the options used by matchers in the +configuration file and in the API. + +The following options are used in configuration entries for matchers: + +* ``target``: Determine which target should be notified if the matcher + matches. Can be used multiple times to notify multiple targets. +* ``disable``: Don't evaluate this matcher. +* ``comment``: Comment for this matcher. +* The matching behavior is defined either by the ``expression`` option or by + the deprecated options below; the two cannot be combined. + + * Expression-based matchers (preferred): + + * ``expression``: Ruleset for this matcher as a single JSON-serialized + object (:ref:`notification_match_expression_reference`). + + * Deprecated matcher options: + + * ``invert-match``: Inverts the result of the whole matcher. + * ``mode``: Determines how the individual match rules are evaluated to + compute the result for the whole matcher. If set to ``all``, all + matching rules must match. If set to ``any``, at least one rule must + match. Defaults to ``all``. + + * ``match-calendar``: Match the notification's timestamp against a + schedule. Days can be specified as an inclusive range (e.g. + ``mon..wed``) or enumerated (e.g. ``mon,wed,sat``). If no days are + specified, the time range applies to every day of the week (e.g. + ``08:00-12:00``). Examples: + + * ``match-calendar mon..wed 9-12`` + * ``match-calendar mon,wed,sat 08:15-12:35`` + * ``match-calendar 04:15-16:35`` + + * ``match-field``: Match a notification's metadata field, either against + a list of matched values, or as a regular expression. If the field does + not exist, the notification will not be matched. Examples: + + * ``match-field exact:type=gc`` + * ``match-field exact:type=prune,verify`` + * ``match-field regex:datastore=^backup-.*$`` + + * ``match-severity``: Match the notification's severity. Examples: + + * ``match-severity error`` + * ``match-severity warning,error,unknown`` + +A matcher without any matching rules always matches; the configured targets +will always be notified. + +Starting with Proxmox Backup Server 4.3, match rules created and edited via the +GUI are stored as a single option ``expression`` in the respective matcher +configuration entry. The previously used options (``match-field``, +``match-calendar``, ``match-severity``, ``mode`` and ``invert-match``) will +continue to be supported at least until the next major release. + +.. NOTE:: Any existing matcher will be migrated to use the newer ``expression`` + option when edited through the GUI. See :ref:`notifications.cfg` for all configuration options. -Calendar Matching Rules -^^^^^^^^^^^^^^^^^^^^^^^ -A calendar matcher matches a notification's timestamp. +.. _notification_match_expression_reference: -Examples: +Match Expression Reference +^^^^^^^^^^^^^^^^^^^^^^^^^^ -* ``match-calendar 8-12`` -* ``match-calendar 8:00-15:30`` -* ``match-calendar mon-fri 9:00-17:00`` -* ``match-calendar sun,tue-wed,fri 9-17`` +This section describes the representation used to encode rules in the +``expression`` parameter. -Field Matching Rules -^^^^^^^^^^^^^^^^^^^^ -Notifications have a selection of metadata fields that can be matched. When -using ``exact`` as a matching mode, a ``,`` can be used as a separator. The -matching rule then matches if the metadata field has **any** of the specified -values. +The ``expression`` option contains a JSON-formatted tree structure of rules, +with leaf nodes matching on the properties of a notification (``field``, +``severity``, ``calendar``) or representing constants (``constant``). +Intermediate nodes and the root node encode the relationship between them +(``all-of``, ``any-of``, ``one-of``, ``not``). -Examples: +============ ======================================================== ========= =============================== +Node Type Description Leaf Node Example +============ ======================================================== ========= =============================== +``all-of`` Match if all child nodes match No ``{"all-of": []}`` +``any-of`` Match if any child node matches No ``{"any-of": []}`` +``one-of`` Match if exactly one child node matches No ``{"one-of": []}`` +``not`` Invert the result of a single child node No ``{"not": }`` +``constant`` Always or never matches, depending on the boolean value Yes ``{"constant": true|false}`` +``match`` Match on a property of a notification Yes ``{"match": }`` +============ ======================================================== ========= =============================== -* ``match-field exact:type=gc`` Only match notifications for garbage collection - jobs -* ``match-field exact:type=prune,verify`` Match prune job and verification job - notifications. -* ``match-field regex:datastore=^backup-.*$`` Match any datastore starting with - ``backup``. +``match`` leaf nodes can have the following variants (````): -If a notification does not have the matched field, the rule will **not** match. -For instance, a ``match-field regex:datastore=.*`` directive will match any -notification that has a ``datastore`` metadata field, but will not match if the -field does not exist. +============ =========================================================================== =================================================================== +Match Type Description Example +============ =========================================================================== =================================================================== +``calendar`` Check if the notification's timestamp is within a configured time range ``{"type": "calendar", "schedule": "mon..fri 9-17"}`` +``field`` Check a notification's fields against a regex or a list of permitted values ``{"type": "field", "field": "job-id", "values": ["a", "b"]}`` or + ``{"type": "field", "field": "datastore", "regex": "^backup-.*$"}`` +``severity`` Check a notification's severity against a list of permitted values ``{"type": "severity", "severities": ["info", "notice"]}`` +============ =========================================================================== =================================================================== -Severity Matching Rules -^^^^^^^^^^^^^^^^^^^^^^^ -A notification has a associated severity that can be matched. +A pretty-printed, full example of a non-trivial expression is shown below. It +encodes an expression matching on garbage collection jobs (``gc``), but only +within a given time range (``mon..fri 09:00-17:00``) or if it has a severity of +``warning`` or ``error``. In the API and configuration file, the JSON is +expected to be stored as a single line, as the value of the ``expression`` +option; the line breaks and indentation are only for demonstration purposes. -Examples: +.. code-block:: json -* ``match-severity error``: Only match errors -* ``match-severity warning,error``: Match warnings and error - -The following severities are in use: -``info``, ``notice``, ``warning``, ``error``, ``unknown``. + { + "all-of": [ + { + "any-of": [ + { + "match": { + "type": "calendar", + "schedule": "mon..fri 09:00-17:00" + } + }, + { + "match": { + "type": "severity", + "severities": [ + "warning", + "error" + ] + } + } + ] + }, + { + "match": { + "type": "field", + "field": "type", + "values": [ + "gc" + ] + } + } + ] + } .. _notification_events: -- 2.47.3