Routage par Tags & Tentatives
Les tags Apprise ne font pas que regrouper des services — ils peuvent piloter l’ordre de livraison, les chaînes de secours et le comportement en cas d’échec sans modifier une seule ligne de code applicatif.
Cette page explique comment configurer ces fonctionnalités dans vos fichiers de configuration et comment les contrôler depuis la bibliothèque Python ou la CLI.
Tags de Priorité
Section intitulée « Tags de Priorité »Chaque tag dans un fichier de configuration peut porter un préfixe numérique de priorité séparé par deux-points : N:nomdetag.
Les numéros inférieurs signifient une urgence plus haute — ils sont traités en premier.
# Priorité 1 -- canaux d'alerte principaux (urgence maximale)1:alerts=slack://tokenA/tokenB/tokenC1:alerts=discord://webhook_id/webhook_token
# Priorité 2 -- canaux secondaires (utilisés uniquement si la priorité 1 échoue entièrement)2:alerts=telegram://bottoken/chatid
# Priorité 5 -- dernier recours5:alerts=mailto://user:pass@example.comLes tags sans préfixe de priorité ont par défaut la priorité 0 (urgence maximale).
version: 1urls: # Priorité 1 -- canaux d'alerte principaux (urgence maximale) - slack://tokenA/tokenB/tokenC: tag: 1:alerts
- discord://webhook_id/webhook_token: tag: 1:alerts
# Priorité 2 -- canaux secondaires (utilisés uniquement si la priorité 1 échoue entièrement) - telegram://bottoken/chatid: tag: 2:alerts
# Priorité 5 -- dernier recours - mailto://user:pass@example.com: tag: 5:alertsLes tags sans préfixe de priorité ont par défaut la priorité 0 (urgence maximale).
Fonctionnement de l’Envoi
Section intitulée « Fonctionnement de l’Envoi »Mode Escalade (par défaut)
Section intitulée « Mode Escalade (par défaut) »Lorsque vous déclenchez un tag sans préfixe de priorité, Apprise utilise la chaîne d’escalade :
- Les services sont regroupés par priorité de tag configurée.
- Le groupe au numéro le plus bas (urgence la plus haute) s’exécute en premier.
- Si chaque service de ce groupe réussit, le résultat est considéré comme vrai immédiatement — les groupes de numéros supérieurs ne sont jamais déclenchés.
- Si un service du groupe échoue, Apprise escalade vers le niveau de priorité suivant.
# Déclencher tous les services 'alerts' avec la chaîne d'escalade.# Les entrées de priorité 1 s'exécutent en premier. Si elles réussissent toutes,# les entrées de priorité 5 ne sont jamais déclenchées.apobj.notify(body="Utilisation disque à 90%", tag="alerts")# Équivalent CLIapprise --config=config.yml --tag="alerts" --body="Utilisation disque à 90%"Formation des Groupes
Section intitulée « Formation des Groupes »Tous les services partageant le même nom de tag et le même numéro de priorité sont traités comme un seul groupe. Le groupe est considéré comme réussi uniquement si chaque service qu’il contient réussit. Si un seul service échoue, Apprise escalade immédiatement vers le groupe au numéro supérieur suivant.
Les tags sans préfixe numérique ont par défaut la priorité 0 — le niveau d’urgence le plus élevé. Cela signifie qu’il est possible de mélanger des versions simples et préfixées d’un même tag pour créer une chaîne d’escalade sans modifier les entrées d’URL existantes :
# Priorité 0 (par défaut, urgence maximale) -- ces deux entrées forment le premier groupeabc=slack://tokenA/tokenB/tokenCabc=discord://webhook_id/webhook_token
# Priorité 1 -- secours si le groupe de priorité 0 échoue1:abc=telegram://bottoken/chatidversion: 1urls: # Priorité 0 (par défaut, urgence maximale) -- ces deux entrées forment le premier groupe - slack://tokenA/tokenB/tokenC: tag: abc
- discord://webhook_id/webhook_token: tag: abc
# Priorité 1 -- secours si le groupe de priorité 0 échoue - telegram://bottoken/chatid: tag: 1:abcLorsque notify(tag="abc") est appelé avec la configuration ci-dessus :
- Le groupe de priorité 0 (Slack + Discord) s’exécute en premier.
- Si les deux réussissent,
Trueest retourné — Telegram n’est jamais contacté. - Si l’un ou l’autre échoue, Apprise escalade vers le groupe de priorité 1 (Telegram).
Les tags sans préfixe ayant par défaut la priorité 0, les définitions abc et 0:abc sont
entièrement équivalentes dans une configuration de service. Toutes deux placent le service dans le
groupe de priorité 0, et un filtre "abc" comme un filtre "0:abc" correspondent aux services
définis avec l’une ou l’autre forme. Si les deux formes figurent dans le même fichier de
configuration, ces services seront toujours distribués ensemble comme un groupe unique.
Mode Exclusif
Section intitulée « Mode Exclusif »Lorsque vous spécifiez un préfixe de priorité dans le filtre, Apprise ignore la chaîne d’escalade et ne notifie que les services dont le tag correspondant porte exactement cette priorité.
# Déclencher UNIQUEMENT les entrées 'alerts' configurées avec la priorité 2.# Les entrées de priorité 1 et 5 ne sont pas affectées.apobj.notify(body="Fenêtre de maintenance planifiée", tag="2:alerts")# Équivalent CLIapprise --config=config.yml --tag="2:alerts" --body="Fenêtre de maintenance planifiée"| Valeur du filtre | Comportement |
|---|---|
"alerts" | Chaîne d’escalade — priorité la plus haute (numéro le plus bas) d’abord |
"2:alerts" | Exclusif — uniquement les entrées alerts de priorité 2 |
"0:alerts" | Exclusif — uniquement les entrées de priorité 0 (alerts et 0:alerts sont identiques) |
Comportement en cas d’échec de chaîne
Section intitulée « Comportement en cas d’échec de chaîne »Quand notify() exécute plusieurs chaînes OR indépendantes en parallèle, le comportement par défaut est de laisser chaque chaîne se terminer avant de retourner — même si une chaîne a déjà échoué. Cela garantit que chaque service configuré obtient au moins une tentative.
Pour arrêter immédiatement tous les rounds d’escalade restants dès qu’une chaîne épuise ses groupes de priorité sans succès, définissez abort_on_chain_failure=True sur votre AppriseAsset :
from apprise import Apprise, AppriseAsset
asset = AppriseAsset(abort_on_chain_failure=True)apobj = Apprise(asset=asset)
# ...ajout des services...
# Si la chaîne 'ops' échoue complètement, Apprise s'arrête immédiatement# et ne lance pas de nouveaux rounds d'escalade pour la chaîne 'securite'.apobj.notify(body="Alerte critique", tag=["ops", "securite"])abort_on_chain_failure | Comportement en cas d’échec d’une chaîne |
|---|---|
False (défaut) | Toutes les chaînes se terminent ; chaque service a une chance d’être tenté |
True | Les rounds restants sont ignorés ; le résultat est considéré comme faux aussitôt |
Tentatives et Délai par Service
Section intitulée « Tentatives et Délai par Service »Chaque service peut être configuré avec son propre nombre de tentatives et délai inter-tentative. Ces paramètres sont indépendants de la chaîne d’escalade et s’appliquent à chaque échec de livraison.
retry— nombre de tentatives supplémentaires après le premier échec (0 = pas de nouvelle tentative).wait— secondes de pause entre les tentatives (décimales acceptées ; 0.0 = pas de pause).
Ajoutez ?retry=N et/ou ?wait=S directement à l’URL sous forme de paramètres de requête.
# jusqu'à 3 nouvelles tentatives, avec 5 secondes d'attente entre chacune1:alerts=slack://tokenA/tokenB/tokenC?retry=3&wait=5
# jusqu'à 2 nouvelles tentatives avec 1,5 seconde d'attente1:alerts=discord://webhook_id/webhook_token?retry=2&wait=1.5
# Canal de secours -- pas besoin de nouvelles tentatives (comportement par défaut)5:alerts=mailto://user:pass@example.comUtilisez les clés retry: et wait: sous chaque entrée d’URL.
version: 1urls: # jusqu'à 3 nouvelles tentatives, avec 5 secondes d'attente entre chacune - slack://tokenA/tokenB/tokenC: tag: 1:alerts retry: 3 wait: 5
# jusqu'à 2 nouvelles tentatives avec 1,5 seconde d'attente - discord://webhook_id/webhook_token: tag: 1:alerts retry: 2 wait: 1.5
# Canal de secours -- pas besoin de nouvelles tentatives - mailto://user:pass@example.com: tag: 5:alertsValeurs acceptées
Section intitulée « Valeurs acceptées »| Paramètre | Type | Contraintes | Par défaut |
|---|---|---|---|
retry | int | 0 à 10 | 0 |
wait | float | 0.0 à 20.0 ; les entiers sont promus en flottant | 0.5 |
Les valeurs invalides (nombres négatifs, chaînes non numériques, inf, nan) sont rejetées et reviennent à la valeur par défaut de l’asset (voir Valeurs par Défaut Globales ci-dessous).
Délais par Service
Section intitulée « Délais par Service »Chaque service dispose d’un budget de temps — s’il (avec toutes ses tentatives et pauses)
n’a pas terminé dans ce délai, Apprise cesse d’attendre plutôt que de rester bloqué
indéfiniment. Ceci est indépendant de retry/wait ci-dessus : un service peut avoir
droit à de nombreuses tentatives tout en étant coupé si l’ensemble prend trop de temps.
Par défaut, chaque service dispose de 60 secondes. Définissez votre propre valeur avec
service_timeout sur AppriseAsset, ou désactivez complètement la limite avec 0 :
from apprise import Apprise, AppriseAsset
# Donne 10 secondes à chaque service au lieu des 60 secondes par défautasset = AppriseAsset(service_timeout=10)apobj = Apprise(asset=asset)apobj.add("slack://tokenA/tokenB/tokenC")
apobj.notify(body="Vérification rapide")# Équivalent CLI -- --service-limit (-SL) applique la même limite à chaque serviceapprise --service-limit 10 --body "Vérification rapide" \ "slack://tokenA/tokenB/tokenC"Un service qui dépasse son délai est signalé avec un statut TIMEOUT plutôt qu’un
simple échec — voir Résultats de notification pour savoir comment
vérifier cela depuis Python.
| Paramètre | Type | Contraintes | Par défaut |
|---|---|---|---|
service_timeout | int / float | 0 ou plus ; 0 désactive la limite | 60 |
Services Optionnels
Section intitulée « Services Optionnels »Le paramètre optional indique qu’un service peut échouer sans faire échouer toute
la notification. Lorsque optional=yes est activé sur un service, un échec de
livraison pour ce service n’affecte pas le résultat global. Le résultat global est
quand même considéré comme vrai si tous les services requis ont réussi.
Utilisez ce paramètre pour les points de terminaison qui doivent recevoir la notification quand ils sont disponibles, sans faire échouer l’application appelante quand ils ne le sont pas.
Exemple : écrans d’affichage domestiques
Section intitulée « Exemple : écrans d’affichage domestiques »Imaginons que votre système domotique possède quatre écrans Kodi avec le tag media. Vous souhaitez afficher une notification sur les écrans actuellement allumés, mais vous ne voulez pas qu’un écran éteint déclenche une alerte d’astreinte à trois heures du matin.
# Les quatre écrans sont optionnels -- leur indisponibilité n'est jamais une erreur.media=kodi://192.168.1.10media=kodi://192.168.1.11media=kodi://192.168.1.12media=kodi://192.168.1.13Pour les rendre optionnels, ajoutez ?optional=yes à chaque URL :
media=kodi://192.168.1.10?optional=yesmedia=kodi://192.168.1.11?optional=yesmedia=kodi://192.168.1.12?optional=yesmedia=kodi://192.168.1.13?optional=yesversion: 1urls: - kodi://192.168.1.10: tag: media optional: yes
- kodi://192.168.1.11: tag: media optional: yes
- kodi://192.168.1.12: tag: media optional: yes
- kodi://192.168.1.13: tag: media optional: yes# Le résultat reste vrai même si tous les écrans sont éteints ou inaccessibles.apobj.notify(body="Le dîner est prêt", tag="media")apprise --config=config.yml --tag="media" --body="Le dîner est prêt"Interaction entre optional et les services requis
Section intitulée « Interaction entre optional et les services requis »Le paramètre est par service. Vous pouvez librement mélanger des services optionnels et requis au sein du même groupe de tags. Le résultat global suit ces règles :
| Services dans le lot | Résultat |
|---|---|
| Tous requis, tous réussissent | Vrai (SUCCESS) |
| Tous requis, un ou plusieurs échouent | Faux (FAILURE) |
| Tous requis, délai dépassé sans échec confirmé | Faux (TIMEOUT) |
| Tous optionnels, tous échouent | Vrai (SUCCESS) |
| Tous optionnels, tous dépassent le délai | Vrai (SUCCESS) |
| Tous optionnels, tous réussissent | Vrai (SUCCESS) |
| Mélange requis/optionnels ; tous les requis réussissent | Vrai (SUCCESS) |
| Mélange requis/optionnels ; au moins un requis échoue | Faux (FAILURE) |
| Mélange requis/optionnels ; délai dépassé sur les requis seulement | Faux (TIMEOUT) |
En résumé : les échecs et dépassements de délai des services optionnels ne font pas échouer le résultat global. Seul l’échec ou le dépassement de délai d’un service requis peut rendre le résultat faux.
Interaction entre optional et les tentatives
Section intitulée « Interaction entre optional et les tentatives »Activer optional=yes ne saute pas le service et ne contourne pas la logique de tentatives. La livraison est toujours tentée, et si retry est supérieur à zéro, Apprise retentera le nombre de fois configuré avant d’abandonner. Ce n’est qu’après l’épuisement de toutes les tentatives qu’Apprise vérifie le paramètre optional pour décider d’absorber ou non l’échec.
# Ce service est tenté jusqu'à 4 fois (tentative initiale + 3 nouvelles tentatives)# avec une pause de 2 secondes entre chacune. Si les quatre tentatives échouent,# l'échec est silencieusement absorbé grâce à optional=yes.media=kodi://192.168.1.10?optional=yes&retry=3&wait=2- kodi://192.168.1.10: tag: media optional: yes retry: 3 wait: 2Utilisation de optional depuis Python
Section intitulée « Utilisation de optional depuis Python »Vous pouvez définir ce paramètre directement sur n’importe quel objet service chargé, ou le passer en argument lors de la construction manuelle d’objets service :
import apprise
apobj = apprise.Apprise()
# Option 1 -- paramètre de requête URL (fonctionne avec tous les chargeurs de config)apobj.add("kodi://192.168.1.10?optional=yes")
# Option 2 -- définir l'attribut directement après chargementobj = apprise.Apprise.instantiate("kodi://192.168.1.10")obj.optional = Trueapobj.add(obj)
# Option 3 -- argument mot-clé du constructeurfrom apprise.plugins.NotifyJSON import NotifyJSONsvc = NotifyJSON(host="192.168.1.10", optional=True)apobj.add(svc)
# Les trois options produisent le même comportement : les échecs sont silencieusement absorbés.result = apobj.notify(body="Le dîner est prêt")print(result) # True même si chaque point de terminaison était inaccessibleExemples supplémentaires
Section intitulée « Exemples supplémentaires »Journal de débogage non critique associé à un canal d’alerte requis :
# Requis : l'ingénieur d'astreinte doit toujours être averti.alerts=slack://tokenA/tokenB/tokenC
# Optionnel : enregistrer dans le canal de diagnostic interne s'il est disponible,# mais ne jamais considérer son absence comme un échec.alerts=json://diagnostics.internal/api/events?optional=yesversion: 1urls: # Requis : l'ingénieur d'astreinte doit toujours être averti. - slack://tokenA/tokenB/tokenC: tag: alerts
# Optionnel : enregistrer dans le canal de diagnostic interne si disponible. - json://diagnostics.internal/api/events: tag: alerts optional: yes# Retourne True si Slack a réussi, quel que soit l'état du journal JSON.apobj.notify(body="Base de données inaccessible", tag="alerts")Groupe de tags entièrement optionnel — diffusion au mieux :
# Notifier les trois écrans s'ils sont accessibles ; ne jamais échouer s'ils ne le sont pas.affichages=kodi://192.168.1.10?optional=yesaffichages=kodi://192.168.1.11?optional=yesaffichages=kodi://192.168.1.12?optional=yesversion: 1urls: - kodi://192.168.1.10: tag: affichages optional: yes
- kodi://192.168.1.11: tag: affichages optional: yes
- kodi://192.168.1.12: tag: affichages optional: yes# Le résultat reste considéré comme vrai, quel que soit le nombre d'écrans ayant répondu.apobj.notify(body="Mouvement détecté", tag="affichages")Valeurs par Défaut Globales via AppriseAsset
Section intitulée « Valeurs par Défaut Globales via AppriseAsset »Si vous souhaitez que chaque service d’une session Apprise partage les mêmes valeurs par défaut de tentatives, d’attente et de délai sans modifier chaque URL, définissez-les sur AppriseAsset :
from apprise import Apprise, AppriseAsset
asset = AppriseAsset( default_service_retry=2, # jusqu'à 2 nouvelles tentatives en cas d'échec avant d'abandonner default_service_wait=3.0, # attendre 3 secondes entre les tentatives service_timeout=10, # abandonner un service bloqué après 10 secondes)
apobj = Apprise(asset=asset)apobj.add("slack://tokenA/tokenB/tokenC")apobj.add("discord://webhook_id/webhook_token")
apobj.notify(body="Valeurs par défaut appliquées à chaque service")Les valeurs par URL (?retry= / ?wait= ou clés YAML) remplacent les valeurs par défaut de l’asset pour ce service spécifique uniquement. Tous les autres services utilisent toujours les valeurs par défaut de l’asset.
Remplacement du Nombre de Tentatives par Appel
Section intitulée « Remplacement du Nombre de Tentatives par Appel »Un :N en fin de valeur de filtre de tag remplace le nombre de tentatives pour chaque service correspondant, pour cet appel uniquement. La configuration permanente du service n’est pas modifiée.
# Réessayer chaque service correspondant jusqu'à 5 fois pour cet appel uniquementapobj.notify(body="Alerte critique", tag="alerts:5")
# Correspondance exclusive priorité 2 ET jusqu'à 3 tentatives par serviceapobj.notify(body="Priorité 2 uniquement", tag="2:alerts:3")# Équivalents CLIapprise --config=config.yml --tag="alerts:5" --body="Alerte critique"apprise --config=config.yml --tag="2:alerts:3" --body="Priorité 2 uniquement"Le suffixe :N suit les mêmes règles de validation que le paramètre URL retry. Sa spécification n’affecte pas wait — chaque service utilise toujours sa valeur d’attente configurée entre les tentatives.
Remplacement du Délai par Appel
Section intitulée « Remplacement du Délai par Appel »Passez timeout= à notify() pour limiter la durée de cet appel précis, du début à
la fin — pour tous les services qu’il notifie. Contrairement à service_timeout (un
budget par service défini sur AppriseAsset), timeout est un plafond pour l’appel
entier.
# Limite cet appel entier à 30 secondes, quel que soit le service_timeout# propre à l'assetapobj.notify(body="Alerte urgente", timeout=30)# Équivalent CLI -- --limit (-L) s'applique à l'ensemble de l'exécutionapprise --limit 30 --body "Alerte urgente" \ "slack://tokenA/tokenB/tokenC"Lorsque les deux sont définis, le délai le plus court l’emporte pour chaque service —
timeout= ne prolonge jamais un service_timeout plus strict, et un service_timeout
généreux ne remplace jamais un timeout= plus serré.
from apprise import Apprise, AppriseAsset
# Chaque service dispose normalement de 60 secondes (valeur par défaut# d'AppriseAsset)...apobj = Apprise(asset=AppriseAsset())apobj.add("slack://tokenA/tokenB/tokenC")
# ...mais cet appel coupe chaque service à 5 secondes à la place.apobj.notify(body="Abandonner rapidement cette fois", timeout=5)timeout vaut 0 par défaut, ce qui signifie “aucun plafond au niveau de l’appel” —
seul le service_timeout de AppriseAsset s’applique. Les valeurs négatives déclenchent
une erreur, tout comme un service_timeout invalide.
Filtres OR et AND multi-tags
Section intitulée « Filtres OR et AND multi-tags »Apprise supporte deux façons de combiner des noms de tags dans un seul appel à notify.
| Motif | Signification | Exemple |
|---|---|---|
| OR — plusieurs valeurs de tag séparées | Correspond aux services portant l’un ou l’autre des tags listés | Plusieurs indicateurs --tag dans la CLI ; une liste de chaînes de tags en Python |
| AND — plusieurs noms de tags dans une seule entrée de filtre | Correspond uniquement aux services portant tous les tags listés | Un seul --tag "a, b" dans la CLI ; une liste imbriquée en Python |
Avec OR, chaque nom de tag forme une chaîne d’escalade indépendante.
Toutes les chaînes doivent trouver un groupe de priorité entièrement réussi
avant que le résultat soit considéré comme vrai. Un suffixe :N sur un token ne
s’applique qu’aux services correspondant à ce token ; les autres ne sont pas
affectés.
# OR -- les services devops obtiennent retry=3 ; management obtient retry=2.# Chaque chaîne d'escalade de tag s'exécute indépendamment.apobj.notify(body="Alerte équipe", tag=["devops:3", "management:2"])# OR -- plusieurs indicateurs --tag ; chacun est une chaîne indépendante.apprise --config=config.yml \ --tag="devops:3" \ --tag="management:2" \ --body="Alerte équipe"Si tous les services devops réussissent dans leur groupe de priorité le plus
bas, Apprise envoie quand même la chaîne management — les deux chaînes sont
indépendantes l’une de l’autre.
Avec AND, les services doivent porter tous les tags du groupe pour être sélectionnés. Les services correspondant à un filtre AND partagent une seule chaîne d’escalade.
# AND -- le service doit porter "devops" ET "management" pour correspondre.apobj.notify(body="Alerte combinée", tag=[["devops", "management"]])# AND -- valeurs séparées par des virgules dans un seul indicateur --tag.apprise --config=config.yml --tag="devops, management" --body="Alerte combinée"Exemple Complet
Section intitulée « Exemple Complet »L’exemple suivant combine les trois fonctionnalités : escalade par priorité, tentatives/attente par service, et remplacement du nombre de tentatives par appel.
# --- Canaux principaux (priorité 1) ---# jusqu'à 2 nouvelles tentatives, 2 secondes d'attente entre chacune1:alerts=slack://tokenA/tokenB/tokenC?retry=2&wait=21:alerts=discord://webhook_id/webhook_token?retry=2&wait=2
# --- Canal secondaire (priorité 5 -- secours) ---# Une seule tentative suffit ; les canaux principaux ont déjà réessayé5:alerts=mailto://user:pass@pagerduty.example.comversion: 1urls: # Canaux principaux (priorité 1) - slack://tokenA/tokenB/tokenC: tag: 1:alerts retry: 2 wait: 2
- discord://webhook_id/webhook_token: tag: 1:alerts retry: 2 wait: 2
# Canal secondaire (priorité 5 -- secours) # Une seule tentative ; les canaux principaux ont déjà réessayé - mailto://user:pass@pagerduty.example.com: tag: 5:alertsfrom apprise import Apprise, AppriseConfig
config = AppriseConfig()config.add("config.yml")
apobj = Apprise()apobj.add(config)
# Alerte normale -- chaîne d'escalade# Slack et Discord (priorité 1) s'exécutent en premier ; chacun réessaie jusqu'à 2 fois# avec une pause de 2 secondes. Si les deux réussissent, PagerDuty (priorité 5) est ignoré.apobj.notify(body="Utilisation disque à 90%", tag="alerts")
# Incident critique -- jusqu'à 5 nouvelles tentatives pour cet appel uniquementapobj.notify(body="Base de données inaccessible", tag="alerts:5")
# Fenêtre de maintenance -- cibler uniquement le canal email de secours (priorité 5)apobj.notify(body="Coupure planifiée dans 30 min", tag="5:alerts")# Alerte normale -- chaîne d'escaladeapprise --config=config.yml --tag="alerts" \ --body="Utilisation disque à 90%"
# Incident critique -- jusqu'à 5 nouvelles tentatives pour cet appel uniquementapprise --config=config.yml --tag="alerts:5" \ --body="Base de données inaccessible"
# Fenêtre de maintenance -- cibler uniquement le canal email de secours (priorité 5)apprise --config=config.yml --tag="5:alerts" \ --body="Coupure planifiée dans 30 min"Variantes
Section intitulée « Variantes »Les exemples ci-dessous illustrent des schémas de notification courants.
Tag unique avec deux niveaux d’escalade — les valeurs 2 et 50 montrent que les
numéros sont arbitraires ; seul l’ordre importe.
# Premier essai (numéro inférieur = urgence supérieure)2:alertes=slack://tokenA/tokenB/tokenC
# Secours ; s'exécute uniquement si la priorité 2 échoue50:alertes=mailto://user:pass@example.comversion: 1urls: - slack://tokenA/tokenB/tokenC: tag: 2:alertes
- mailto://user:pass@example.com: tag: 50:alertes# Chaîne d'escalade : Slack d'abord, e-mail seulement en cas d'échecapobj.notify(body="Alerte", tag="alertes")apprise --config=config.yml --tag="alertes" --body="Alerte"Trois chaînes OR avec plusieurs niveaux de priorité — alpha, beta et gamma
sont des chaînes indépendantes dispatchées simultanément. Au sein de chaque chaîne,
les groupes de priorité inférieure s’exécutent en premier ; les échecs escaladent au
niveau suivant. Par défaut, chaque chaîne s’exécute jusqu’à son terme même après qu’une
autre chaîne a déjà épuisé tous ses niveaux sans succès — voir « Comportement en cas
d’échec de chaîne » plus haut pour changer cela.
# alpha : trois niveaux avec des valeurs de priorité arbitraires1:alpha=slack://tokenA/tokenB/tokenC1:alpha=mailto://user:pass@gmail.com5:alpha=telegram://bottoken/chatid700:alpha=discord://webhook_id/webhook_token
# beta : un seul niveau à la priorité 500500:beta=discord://webhook_id2/webhook_token2
# gamma : deux niveaux ; sans préfixe = priorité 0 (la plus haute)gamma=telegram://bottoken2/chatid2200:gamma=telegram://bottoken3/chatid3version: 1urls: # alpha -- trois niveaux d'escalade - slack://tokenA/tokenB/tokenC: tag: 1:alpha - mailto://user:pass@gmail.com: tag: 1:alpha - telegram://bottoken/chatid: tag: 5:alpha - discord://webhook_id/webhook_token: tag: 700:alpha
# beta -- niveau unique - discord://webhook_id2/webhook_token2: tag: 500:beta
# gamma -- deux niveaux (sans préfixe = priorité 0) - telegram://bottoken2/chatid2: tag: gamma - telegram://bottoken3/chatid3: tag: 200:gammaOrdre de dispatch quand les trois chaînes sont combinées en OR :
| Round | alpha | beta | gamma |
|---|---|---|---|
| 1 | Slack + Gmail (priorité 1) | Discord (priorité 500) | Telegram 2 (priorité 0) |
| 2 (si échec au round 1) | Telegram (priorité 5) | — épuisé — | Telegram 3 (priorité 200) |
| 3 (si échec au round 2 pour alpha) | Discord (priorité 700) |
apobj.notify(body="Diffusion", tag=["alpha", "beta", "gamma"])apprise --config=config.yml \ --tag="alpha" \ --tag="beta" \ --tag="gamma" \ --body="Diffusion"Deux chaînes OR indépendantes avec surcharge de tentatives par appel — chaque
token porte son propre suffixe :N : les services devops obtiennent trois tentatives
et les services direction en obtiennent deux.
10:devops=slack://tokenA/tokenB/tokenC10:direction=discord://webhook_id/webhook_tokenversion: 1urls: - slack://tokenA/tokenB/tokenC: tag: 10:devops
- discord://webhook_id/webhook_token: tag: 10:direction# devops : retry=3 ; direction : retry=2apobj.notify(body="Alerte équipe", tag=["devops:3", "direction:2"])apprise --config=config.yml \ --tag="devops:3" \ --tag="direction:2" \ --body="Alerte équipe"Filtre AND — seuls les services portant tous les tags listés sont dispatchés.
# Les deux tags sur la même URL ; seul ce service correspond au filtre ANDdevops direction=slack://tokenA/tokenB/tokenC
# Un seul tag "devops" -- ne correspond PAS au filtre ANDdevops=discord://webhook_id/webhook_tokenversion: 1urls: # Les deux tags sur la même URL - slack://tokenA/tokenB/tokenC: tag: - devops - direction
# Un seul tag -- ne correspond pas au filtre AND - discord://webhook_id/webhook_token: tag: devops# AND -- le service doit porter "devops" ET "direction"apobj.notify(body="Alerte combinée", tag=[["devops", "direction"]])# AND -- valeurs séparées par une virgule dans un seul flag --tagapprise --config=config.yml --tag="devops, direction" --body="Alerte combinée"Dispatch exclusif — un préfixe de priorité dans le filtre cible uniquement ce niveau exact. Aucune chaîne d’escalade n’est construite ; les services correspon- dants sont dispatchés en un seul lot plat.
2:alertes=slack://tokenA/tokenB/tokenC50:alertes=mailto://user:pass@example.comversion: 1urls: - slack://tokenA/tokenB/tokenC: tag: 2:alertes
- mailto://user:pass@example.com: tag: 50:alertes# Exclusif : seules les entrées de priorité 50 s'exécutent ; Slack est ignoréapobj.notify(body="Maintenance", tag="50:alertes")apprise --config=config.yml --tag="50:alertes" --body="Maintenance"Récapitulatif
Section intitulée « Récapitulatif »| Fonctionnalité | Où le configurer | Portée |
|---|---|---|
| Priorité de tag | N:nomdetag dans le fichier de configuration (TEXT ou YAML) | Par définition de service |
| Nombre de tentatives par service | Paramètre URL ?retry=N ou clé YAML retry: | Par définition de service |
| Délai inter-tentative par service | Paramètre URL ?wait=S ou clé YAML wait: | Par définition de service |
| Service optionnel | Paramètre URL ?optional=yes ou clé YAML optional: yes | Par définition de service |
| Délai par service | AppriseAsset(service_timeout=N) ou --service-limit N | Par définition de service |
| Valeurs par défaut globales | AppriseAsset(default_service_retry=N, default_service_wait=S) | Tous les services de la session |
| Envoi en escalade | notify(tag="nomdetag") ou --tag nomdetag (sans préfixe de priorité) | Un appel notify() / CLI |
| Envoi exclusif | notify(tag="N:nomdetag") ou --tag N:nomdetag | Un appel notify() / CLI |
| Remplacement des tentatives | notify(tag="nomdetag:N") ou --tag nomdetag:N | Un appel notify() / CLI |
| Remplacement du délai | notify(timeout=N) ou --limit N | Un appel notify() / CLI |
| Envoi OR multi-tags | notify(tag=["tagA", "tagB"]) ou --tag tagA --tag tagB | Un appel notify() / CLI |
| Envoi AND multi-tags | notify(tag=[["tagA", "tagB"]]) ou --tag "tagA, tagB" | Un appel notify() / CLI |
| Envoi OR multi-tags avec tentatives par tag | notify(tag=["tagA:N", "tagB:M"]) ou --tag tagA:N --tag tagB:M | Un appel notify() / CLI |
| Arrêt anticipé sur échec de chaîne | AppriseAsset(abort_on_chain_failure=True) | Tous les services de la session |
Questions ou commentaires ?
Documentation
Vous avez repéré une faute de frappe ou une erreur ?
Problèmes Techniques
Vous rencontrez un problème avec le code ? Ouvrez un ticket sur GitHub :