3. Writing your first rules #
The syntax, a full example and group options.
A rules file #
Declare the file in prometheus.yml, then write the rules. These examples use Prometheus's own metrics, so you can try them straight away:
global:
scrape_interval: 5s
evaluation_interval: 15s
rule_files:
- /etc/prometheus/rules.yml
scrape_configs:
- job_name: prometheus
static_configs:
- targets: ["localhost:9090"]groups:
- name: http_prometheus
rules:
- record: job_handler:prometheus_http_requests:rate5m
expr: sum by (job, handler) (rate(prometheus_http_requests_total[5m]))
- record: job:prometheus_http_requests:rate5m
expr: sum by (job) (job_handler:prometheus_http_requests:rate5m)
- record: job:prometheus_http_requests_errors:rate5m
expr: sum by (job) (rate(prometheus_http_requests_total{code=~"5.."}[5m]))
- record: job:prometheus_http_requests_errors:ratio_rate5m
expr: |
(job:prometheus_http_requests_errors:rate5m or job:prometheus_http_requests:rate5m * 0)
/ job:prometheus_http_requests:rate5m
- record: job:prometheus_http_request_duration_seconds:p95_rate5m
expr: |
histogram_quantile(0.95,
sum by (job, le) (rate(prometheus_http_request_duration_seconds_bucket[5m])))In Grafana, the query becomes very simple:
# Before: recomputed on every refresh of every panel
sum by (job) (rate(http_requests_total[5m]))
# After: simple read of the recorded series
job:http_requests:rate5mGroup options #
groups:
- name: http_aggregates
interval: 30s # otherwise: the global evaluation_interval
query_offset: 30s # evaluates slightly in the past if data arrives late
limit: 1000 # the rule fails if it produces more than 1000 series
labels:
team: platform # added to all rules of the group
rules:
- record: job:http_requests:rate5m
expr: sum by (job) (rate(http_requests_total[5m]))4. Naming your rules well #
The level:metric:operations convention.
The official convention #
The Prometheus documentation recommends the level:metric:operations format. The name then says what the series contains, without opening the rules file. Colons are reserved for this purpose: exporters must not use them.
| Part | Meaning | Example |
|---|---|---|
| level | Labels kept by the aggregation | job, instance_path |
| metric | Original name, without the _total suffix after a rate | http_requests |
| operations | Applied operations, newest first | rate5m, ratio_rate5m, p95_rate5m |
5. Pitfalls to avoid #
Ratios, missing series, order of operations.
Never average ratios #
A service at 10 requests per second with 50% errors and another at 1000 requests per second with 0% do not average 25% errors, but about 0.5%. So record the numerator and denominator, then divide their sums:
# Wrong: average of ratios, a small service weighs as much as a big one
avg by (job) (instance:http_requests_errors:ratio_rate5m)
# Right: aggregate the numerator and denominator separately
sum by (job) (instance:http_requests_errors:rate5m)
/ sum by (job) (instance:http_requests:rate5m)The ratio that disappears when all is well #
This is the sneakiest pitfall, observed while preparing this chapter. If no 5xx series exists, the filter returns nothing, and dividing by an empty result gives an empty result, not 0. The dashboard shows “No data”: you can then no longer tell “no errors” from a collection outage.
# Empty as long as no 5xx error has been seen
job:requests_errors:rate5m / job:requests:rate5m
# Equals 0 when there is no error
(job:requests_errors:rate5m or job:requests:rate5m * 0) / job:requests:rate5mOther frequent mistakes #
ratefirst,sumsecond:sum(rate(x[5m])). Adding counters beforeratebreaks the detection of their resets.- Histograms: keep the
lelabel insum by, orhistogram_quantilecannot compute anything. - Too many labels: a rule keeping
instanceorpodkeeps almost all the cardinality. - Changing a rule: if the expression changes meaning, change the name too, or the old and new logic mix in the same series.
My progress
Sign in to track your progress and take notes. Sign in
Course Glossary
Alerting
The process of notifying teams (via email, Slack, Teams) when a specific event, threshold breach, or anomaly is detected.
Architecture
The overall structural design of an IT system, defining its various components, their relationships, and the principles guiding its evolution.
OpenTelemetry
An open source framework providing standards, APIs, and SDKs to collect and export observability data (traces, metrics, logs) in an agnostic way.
Recommended Articles
Bonnes pratiques Prometheus : métriques, cardinalité, règles et exploitation
Bonnes pratiques Prometheus : nommage des métriques, labels et cardinalité, intervalles de scrape...
Thanos Ruler : règles et alertes sur la vue globale
Évaluer des règles d'enregistrement et d'alerte sur l'ensemble des clusters avec Thanos Ruler : c...
Mesurer des SLI avec Prometheus
Implémenter des SLI de disponibilité et de latence avec Prometheus : métriques nécessaires, requê...
Mimir : ruler, Alertmanager et mimirtool
Évaluer des règles d'enregistrement et d'alerte dans Mimir, configurer l'Alertmanager multi-tenan...
Écrire de bonnes règles d'alerte Prometheus (et les tester)
Concevoir des alertes utiles : alerter sur les symptômes, choisir for et les seuils, labels de sé...
Prometheus : visualiser ses métriques (UI, Grafana et dashboards)
Visualiser les données Prometheus : interface web, graphes PromQL, connexion à Grafana, dashboard...
Générer ses SLO Prometheus avec Sloth
Décrire un SLO en quelques lignes avec Sloth et générer automatiquement règles d'enregistrement m...
Alerter sur les logs avec le Ruler de Loki
Mettre en place des alertes et des recording rules LogQL avec le Ruler Loki : configuration, fich...
PromQL : introduction au langage de requête de Prometheus
Apprendre PromQL, le langage de requête de Prometheus : sélecteurs, rate, sum by, histogrammes et...