Skip to main content

Semantic linter for Prometheus Alertmanager configs

Project description

amlint

CI Docs Coverage PyPI Python Docker

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_re that doesn't compile
  • group_by that 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 check alertmanager.yml --ignore empty-receiver,unused-receiver
amlint diff old.yml new.yml                 # show what changed
amlint init > alertmanager.yml              # generate minimal valid config
amlint explain undefined-receiver           # detailed explanation + examples

Project config.amlint.yml or pyproject.toml [tool.amlint]:

# .amlint.yml
ignore:
  - empty-receiver
strict: true
severity:
  unused-receiver: error   # upgrade info → error
# pyproject.toml
[tool.amlint]
ignore = ["empty-receiver"]
strict = true

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
duplicate-receiver error receiver name defined more than once
undefined-time-interval error mute_time_intervals / active_time_intervals references unknown interval
email-no-smarthost error email_configs without smarthost and no global SMTP
webhook-no-url error webhook_configs without url or url_file
pagerduty-no-routing-key error pagerduty_configs without routing_key
slack-no-api-url error slack_configs without api_url and no global
opsgenie-no-api-key error opsgenie_configs without api_key and no global
msteams-no-webhook-url error msteams_configs without webhook_url
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
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
empty-receiver warn/info receiver has no integration configured — alerts will be dropped
unused-receiver info receiver defined but not used in any route
inhibit-same-match info source and target match the same label value
useless-continue info continue:true on the last sibling route has no effect
deep-nesting info route tree deeper than 5 levels

Run amlint explain <code> for detailed description and examples of any check.

Tests

python3 -m pytest test_linter.py -v

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

amlint-0.1.7.tar.gz (17.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

amlint-0.1.7-py3-none-any.whl (17.2 kB view details)

Uploaded Python 3

File details

Details for the file amlint-0.1.7.tar.gz.

File metadata

  • Download URL: amlint-0.1.7.tar.gz
  • Upload date:
  • Size: 17.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for amlint-0.1.7.tar.gz
Algorithm Hash digest
SHA256 1c39e0ee492de20afa14ee3dbe4ccbb88407836fabd14dbfdeb72c37d87534fc
MD5 adfe0d1bfed94fd7d81729266e5eed43
BLAKE2b-256 9b98c55e8b01ad83c10429951aff712f07f7c1a17b60574dee90d67e45a865e1

See more details on using hashes here.

Provenance

The following attestation bundles were made for amlint-0.1.7.tar.gz:

Publisher: publish.yml on danikdanik2013/amlint

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file amlint-0.1.7-py3-none-any.whl.

File metadata

  • Download URL: amlint-0.1.7-py3-none-any.whl
  • Upload date:
  • Size: 17.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for amlint-0.1.7-py3-none-any.whl
Algorithm Hash digest
SHA256 30ef15a32d2eaf79901af8e2da0a117a8b95a8af037a58eb8f5e1b4edbeb4903
MD5 789282b71fb93119d7a139323e2036e9
BLAKE2b-256 ed7d0dd5000d07cb60faddd84ba65a6fe7e1a779a0490286202362c31d1f9a74

See more details on using hashes here.

Provenance

The following attestation bundles were made for amlint-0.1.7-py3-none-any.whl:

Publisher: publish.yml on danikdanik2013/amlint

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page