Prometheus and Alertmanager
Alerts in, PromQL as evidence for every pack, approved silences, and fixes when your monitoring itself breaks.
Firing alerts from Alertmanager become 3AM incidents (silenced and inhibited ones don't). 3AM's packs run their checks as PromQL against your Prometheus: MySQL, Kubernetes, JVM, nginx and the rest. 3AM also watches Prometheus and Alertmanager themselves. When monitoring is broken, its own evidence is unreliable, so it treats that as an incident too.
Before you start
- Read access to Prometheus' HTTP API, and to Alertmanager's.
- Write access to Alertmanager silences, only if 3AM may create silences. Every silence is approved.
- Outbound access from 3AM to both. Nothing connects to 3AM.
1. Create credentials
| Your setup | Give 3AM |
|---|---|
| No authentication | The URLs |
web.yml basic auth | A user and password (add a user for 3AM) |
| A reverse proxy or SSO in front | A bearer token |
| Alertmanager behind a different proxy | Its own credentials (the alertmanager_* settings) |
| HTTPS with an internal CA | The CA certificate, as a PEM file |
web.yml stores bcrypt hashes. Make one for 3AM's password:
htpasswd -nbBC 10 3am 'a-long-random-password' | cut -d: -f2basic_auth_users:
3am: $2y$10$… # the hash from above2. Check your exporters
The packs' checks read standard exporter metrics. A stock exporter covers the core checks; a few need a flag:
| Technology | Exporter | Works out of the box | Turn on for more |
|---|---|---|---|
| MySQL / MariaDB | mysqld_exporter | up, read-only, connection usage, row-lock waits | --collect.info_schema.processlist for per-user connections. Replication lag is reported on replicas |
| Alertmanager | its own /metrics (scrape it) | notification failures | |
| Kubernetes | kube-state-metrics | restarts, OOM kills |
A check whose metric is missing is reported as inconclusive. It never counts as passed.
3. Add the connector
In the console: Connections → Add a connection → Prometheus / Alertmanager. Or in connectors.json:
{ "name": "prometheus", "kind": "prometheus",
"settings": { "url": "https://prometheus.bank.internal:9090",
"username": "3am", "password": { "file": "/etc/3am/secrets/prometheus-password" },
"alertmanager_url": "https://alertmanager.bank.internal:9093",
"alertmanager_bearer_token": { "env": "AM_TOKEN" },
"ca_file": "/etc/3am/secrets/bank-ca.pem" } }kind: prometheusalerts inmetrics and queriesactions| Setting | What to enter | Required | Default |
|---|---|---|---|
url | Prometheus base URL | yes | — |
alertmanager_url | Alertmanager base URL | no | — |
bearer_tokensecret | Bearer token, if required | no | — |
username | Basic-auth user, if required | no | — |
passwordsecret | Basic-auth password | no | — |
alertmanager_bearer_tokensecret | Alertmanager bearer token (if different) | no | — |
alertmanager_username | Alertmanager basic-auth user (if different) | no | — |
alertmanager_passwordsecret | Alertmanager basic-auth password (if different) | no | — |
ca_file | CA certificate for a private CA (PEM file) | no | — |
verify_tls | Verify TLS | yes | true |
4. Verify
Test connection runs a real query (not just a ping) and checks Alertmanager with its own credentials:
Connected. Prometheus 3.15.0 + Alertmanager 0.34.1
jobs: 6 (mysql, prometheus, …) alert rules: 95 targets: 32To check the whole path, add a rule that always fires and reload Prometheus:
groups:
- name: 3am-test
rules:
- alert: ThreeAMPipelineTest
expr: vector(1)
labels: { severity: critical, service: monitoring }Within a minute the console shows an incident for ThreeAMPipelineTest. 3AM finds nothing to prove and says so.
Remove the rule afterwards.
What it proves and fixes
3AM raises these from Prometheus' and Alertmanager's own status, even with no alert rule for them. If your own rule for the same thing fires, 3AM uses yours.
| Cause | How 3AM knows | Fix |
|---|---|---|
| Prometheus or Alertmanager down or hung | It doesn't answer. Raised as PrometheusComponentDown, even when Prometheus is the one down | Restart its pod or workload (Kubernetes connector) |
| Prometheus' storage full | The TSDB fails to write its WAL or to compact | Grow its volume by half (Kubernetes connector). Two approvers |
| Target unreachable | The scrape error: connection refused, DNS, timeout | Restart the target's workload, if it runs in a namespace 3AM watches |
| Target refuses credentials | The scrape error is a 401 or 403 | Advice: update the scrape job's credentials |
| Target answers garbage | A parse or content-type error | Advice: check the exporter |
| Config reload failed | Prometheus' runtime status | Advice: promtool check config, fix, reload |
| Rules failing | Rule health, with each failing rule's error | Advice: fix the named rules |
| No Alertmanager | Prometheus' Alertmanager discovery | Advice: alerts reach nobody until it's fixed |
| Notifications failing | alertmanager_notifications_failed_total rising, per integration | Advice: fix the receiver |
Restarts and volume growth go through the Kubernetes connector, which finds the workload behind Prometheus', Alertmanager's or the target's address. Without it these causes go to a person with the evidence.
Actions
| Action | Parameters | Notes |
|---|---|---|
silence | alertname, minutes, comment, matchers | 1–1440 minutes, createdBy: 3AM. The rehearsal lists the alerts it would silence |
unsilence | silence_id | Expires a silence |
targets, prometheus_status, alertmanager_status, components_status, volume_usage | Read-only evidence for the packs |
Troubleshooting
Prometheus: authentication failed
Check the user and password, or the bearer token.
Alertmanager: authentication failed
Alertmanager has its own credentials. Fill in the alertmanager_* settings.
the certificate is not trusted: set ca_file
Set CA certificate to your internal CA, in PEM format.
Prometheus refused the query (bad_data)
A check's PromQL didn't parse on your Prometheus. The message includes Prometheus' own explanation; send it to support@3am.si.
Silenced alerts still appear
Without alertmanager_url, 3AM reads Prometheus' alerts, which know nothing about silences. Add the Alertmanager URL.
Certification
Live, on Prometheus 3.15 behind HTTPS with an internal CA and basic auth, Alertmanager 0.34 behind a bearer-token
proxy, and the real mysqld_exporter 0.20 (2026-10-04):
- 46 checks. End to end, the database was set read-only. This Prometheus fired
MySQLReadOnlythrough Alertmanager, 3AM proved it from this Prometheus' metric and fixed it with approval, and the alert resolved. - Fixes, on Kubernetes. A hung Prometheus, a hung Alertmanager and a hung scrape target were each restarted and verified (details).