Semantic linter for Prometheus Alertmanager configs
Project description
amlint
Semantic linter for Prometheus Alertmanager configs.
amtool check-config validates syntax. amlint validates semantics:
will alerts actually reach a receiver, does the inhibition rule do anything,
are there unreachable routing branches? These are the bugs that burn teams —
config is valid, alerts silently vanish.
Why
Alertmanager configs are YAML routing trees with inhibition rules and receivers. The most painful mistakes are syntactically valid:
- route references a receiver that doesn't exist → alerts are dropped
- inhibition without
equal→ silences unrelated alerts, you think it's quiet, there's actually a fire - catch-all branch before specific ones → specific branches are unreachable
match_rethat doesn't compilegroup_bythat doesn't behave the way you think
amtool won't catch any of this. amlint will.
Install
pip install amlint
Or with Docker (no Python required):
docker run --rm -v $(pwd):/cfg ghcr.io/danikdanik2013/amlint check /cfg/alertmanager.yml
Usage
amlint check alertmanager.yml
amlint check prod.yml staging.yml # multiple files
cat alertmanager.yml | amlint check - # stdin
amlint check alertmanager.yml --strict # WARN also exits non-zero
amlint check alertmanager.yml --format json
amlint diff old.yml new.yml # show what changed
amlint init > alertmanager.yml # generate minimal valid config
Shell completions (bash/zsh):
pip install "amlint[completions]"
eval "$(register-python-argcomplete amlint)" # add to ~/.zshrc or ~/.bashrc
Example output:
ERROR Route references receiver 'pager-team' which is not defined in receivers. Alerts matched here will be dropped.
↳ route.routes[1] [undefined-receiver]
WARN Catch-all route (no matchers) with continue:false will intercept all alerts — 2 subsequent sibling(s) are unreachable.
↳ route.routes[0] [unreachable-route]
2 error · 3 warn · 1 info
Exit code 1 on ERROR — ready for CI. --strict makes WARN block too.
CI example
# .github/workflows/lint.yml
- name: Lint Alertmanager config
run: amlint check alertmanager.yml --strict
Checks
| code | level | what it catches |
|---|---|---|
undefined-receiver |
error | route references a receiver that doesn't exist |
bad-regex |
error | match_re pattern fails to compile |
no-root-route |
error | no root route defined |
inhibit-no-equal |
warn | inhibition without equal silences too broadly |
unreachable-route |
warn | catch-all hides subsequent sibling routes |
groupby-ellipsis |
warn | ... mixed with explicit labels in group_by |
inhibit-same-match |
info | source and target match the same label value |
unused-receiver |
info | receiver defined but not used in any route |
duplicate-receiver |
error | receiver name defined more than once |
empty-receiver |
warn/info | receiver has no integration configured — alerts will be dropped |
undefined-time-interval |
error | mute_time_intervals / active_time_intervals references unknown interval |
repeat-before-group |
warn | repeat_interval shorter than group_interval |
circular-inhibition |
warn | two inhibition rules that silence each other |
wait-exceeds-interval |
warn | group_wait longer than group_interval |
useless-continue |
info | continue:true on the last sibling route has no effect |
Tests
python3 -m pytest test_linter.py -v
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file amlint-0.1.4.tar.gz.
File metadata
- Download URL: amlint-0.1.4.tar.gz
- Upload date:
- Size: 12.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7e4a52e6183abc45dd3553950735d3ec8bf8ab4444941937c1b983c68331257a
|
|
| MD5 |
5d6c3662fbb7a11a87485f5125e33f01
|
|
| BLAKE2b-256 |
9865855ec412713260cdeca71f171828b9aecc71bb078fc083e047d400c3f449
|
Provenance
The following attestation bundles were made for amlint-0.1.4.tar.gz:
Publisher:
publish.yml on danikdanik2013/amlint
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
amlint-0.1.4.tar.gz -
Subject digest:
7e4a52e6183abc45dd3553950735d3ec8bf8ab4444941937c1b983c68331257a - Sigstore transparency entry: 1923672388
- Sigstore integration time:
-
Permalink:
danikdanik2013/amlint@bea814316417a3d8bae98839f60f478db3bc3060 -
Branch / Tag:
refs/tags/v0.1.4 - Owner: https://github.com/danikdanik2013
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@bea814316417a3d8bae98839f60f478db3bc3060 -
Trigger Event:
push
-
Statement type:
File details
Details for the file amlint-0.1.4-py3-none-any.whl.
File metadata
- Download URL: amlint-0.1.4-py3-none-any.whl
- Upload date:
- Size: 11.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7176dee50fa842fb388a9af0ff280df79ec9f91b570fd6a63bcc0502d6e12555
|
|
| MD5 |
42c7417584c1b198deb95b5fc47e9c59
|
|
| BLAKE2b-256 |
85b4ced0f739a9858c28324ba1818c599e0223b171c2bda910a25857689472ac
|
Provenance
The following attestation bundles were made for amlint-0.1.4-py3-none-any.whl:
Publisher:
publish.yml on danikdanik2013/amlint
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
amlint-0.1.4-py3-none-any.whl -
Subject digest:
7176dee50fa842fb388a9af0ff280df79ec9f91b570fd6a63bcc0502d6e12555 - Sigstore transparency entry: 1923672468
- Sigstore integration time:
-
Permalink:
danikdanik2013/amlint@bea814316417a3d8bae98839f60f478db3bc3060 -
Branch / Tag:
refs/tags/v0.1.4 - Owner: https://github.com/danikdanik2013
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@bea814316417a3d8bae98839f60f478db3bc3060 -
Trigger Event:
push
-
Statement type: