# Prometheus

## Vad det är

Prometheus är ett system för övervakning med öppen källkod, byggt kring en egen tidsseriedatabas.
Med några sekunders mellanrum ber det programmen som det bevakar om deras senaste värden över HTTP,
lagrar varje värde med en tidsstämpel och låter dig ställa databasfrågor mot det, rita grafer och
skicka larm utifrån det som har sparats. Namnet betecknar servern för sig och, lika ofta, den lilla
familj av komponenter som har vuxit upp kring den.

Det byggdes på SoundCloud, där arbetet började 2012, och tillhör i dag Cloud Native Computing
Foundation (CNCF). Projektet gick med 2016 som stiftelsens andra projekt, efter Kubernetes, och
nådde 2018 den högsta mognadsnivån, graduated. Prometheus 3.0, som presenterades i november 2024,
var den första större versionen på sju år. Koden är till största delen skriven i Go och publiceras
under licensen Apache 2.0.

Allt som lagras är en tidsserie, namngiven av ett mätvärdesnamn och en uppsättning etiketter
(labels): par av nyckel och värde som säger vilken instans av något som mättes, som i
`api_http_requests_total{method="POST", handler="/messages"}`. Varje mätpunkt i serien är ett
64-bitars flyttal, eller ett inbyggt histogram (native histogram), med en tidsstämpel i
millisekunder. Ett annat värde på vilken etikett som helst ger en annan serie. Det gör datan lätt
att dela upp per värddator, sökväg eller statuskod, och det gör den också lätt att överbelasta.

Program exponerar sina systemmätvärden på en HTTP-ändpunkt, oftast `/metrics`, genom ett
klientbibliotek som kompileras in i koden eller genom en exporterare (exporter): en liten adapter
som översätter ett system som Prometheus inte kan instrumentera direkt, t.ex. en värddator med
Linux eller en databas. Servern hittar sina mål genom tjänsteupptäckt (service discovery) eller en
statisk lista och hämtar data från dem med fasta intervall, det som kallas scraping. Ett batchjobb
som avslutas före nästa hämtning kan i stället skicka sina värden till en separat push-gateway.
Larmregler körs på servern, och utlösta larm går till Alertmanager, som tar bort dubbletter,
grupperar dem, tillämpar tystningar och skickar dem vidare till e-post, PagerDuty, OpsGenie och
liknande mottagare.

Prometheus vägs oftast mot push-baserade insamlare i traditionen från Graphite och StatsD, mot
allmänna tidsseriedatabaser som InfluxDB och mot hanterade tjänster för mätvärden. Grafana är det
vanliga ansiktet framför det. Prometheus lagrar tal snarare än händelser, så en loggrad hör hemma i
loggningen och en spårning (trace) i ett system för spårning. Projektet säger också rakt ut att det
prioriterar tillförlitlighet framför fullständighet: debitering per anrop, där varje räkning måste
vara exakt, är ett jobb för ett annat system.

## Varför det spelar roll

Beslutet som Prometheus står mitt i är om du ska driva en egen databas för mätvärden eller hyra en,
och om du driver den själv, hur stor den måste vara.

Att driva den själv kostar ingen licensavgift. Kostnaden är en maskin och timmarna hos den som
håller den frisk. En hanterad tjänst tar bort det arbetet och ersätter det med en avgift som växer
med mängden data som skickas dit, vilket gör varje ny etikett till en rad på en faktura. För några
dussin maskiner är den egna servern oftast den billigare och enklare vägen. Kalkylen ändras när
antalet serier når miljontals och teamet hellre betalar än bemannar.

Storleksräkningen är snällare än de flesta tror. Projektets dokumentation om lagring anger i
genomsnitt en till två byte per mätpunkt. Tusen serier som hämtas var 15:e sekund och sparas under
standardlagringstiden på 15 dagar blir 86,4 miljoner mätpunkter, ungefär 86–173 MB på disk. Det är
sällan disken som tar slut. Det är minnet: blocket som fylls just nu ligger i minnet, skyddat mot
krascher av en write-ahead-logg, och varje aktiv serie kostar något där, oavsett om någon någonsin
frågar efter den.

Varje server är medvetet självständig. Den lutar sig mot ingen nätverkslagring, så den fortsätter
att svara medan infrastrukturen den bevakar faller ihop, och det är just då den behövs som mest.
Priset är att den lokala lagringen varken är klustrad eller replikerad. Hög tillgänglighet betyder
två identiska servrar som hämtar från samma mål, och historik längre än några veckor betyder att en
kopia skickas med `remote_write` till ett lager som är byggt för att behålla den.

Att hämta i stället för att ta emot ger också en praktisk vinst. Eftersom servern är den som frågar
märker den när ett mål slutar svara och registrerar det som att `up` sjunker till noll. Och en
ingenjör kan öppna samma `/metrics`-sida i en webbläsare och se exakt det som servern ser, vilket
gör att en oenighet mellan grafen och applikationen snabbt går att reda ut.

## Så ser det ut i praktiken

I företagets arbete dyker Prometheus upp som insamlaren bakom en dashboard: en gång för en flotta
av databasservrar och en gång som andra versionen av en vy som hela kontoret tittade på.

I databasfallet hämtade Prometheus mätvärden från
[tio databasservrar med två motorer, PostgreSQL 14 och MS SQL Server 2019](/sv/portfolio/designed-deployed-and-maintained-10-postgresql-and-ms-13/),
alla på virtuella servrar med Ubuntu 20.04 LTS. Tillsammans med Grafana följde den CPU, minne,
disk-I/O och prestanda för databasfrågor i realtid, vid sidan av automatiserade säkerhetskopior,
regler för brandväggen och egna skript för logganalys. På alla tio servrarna höll sig upptiden på
99,9 %. Databasvärdar passar bra för den här sortens hämtning, eftersom de värden som förutsäger
problem där, en disk som fylls eller en databasfråga som blir långsammare, rör sig över timmar. En
mätpunkt med några sekunders mellanrum ser dem långt innan en användare gör det.

Kontorsvyn visar steget från en hemmabyggd insamlare till Prometheus.
[Företagets första dashboard för observerbarhet](/sv/portfolio/developed-and-launched-the-company-s-first-observability-9/)
började med att läsa CPU, RAM, disk, temperatur med mera från Linux-servrar på distans via SSH, och
bevakade Docker-containrar på samma sätt. En andra version byggdes om på Prometheus och Grafana,
kring de mått som valdes tillsammans med DevOps- och utvecklingsteamen: CPU-användning,
minnesanvändning, tjänsternas upptid och API-latens, med larm vid överskridna tröskelvärden. Med
dashboarden på plats upptäckte och löste teamen incidenter 40 % snabbare. Att polla över SSH är en
bra start för en handfull maskiner. En insamlare med etiketter och ett frågespråk är det som låter
samma vy fortsätta växa.

## Var det går fel

**Minnet klättrar efter en release som inte ändrade något viktigt.** Någon lade till en etikett
vars värden saknar gräns: ett användar-ID, en e-postadress, en fullständig URL-sökväg, ett
anrops-ID. Varje nytt värde blev en ny serie, och servern håller nu miljontals serier där den förut
höll tusentals. Namngivningsguiden varnar för exakt det här. Håll etikettvärdena till små, kända
mängder, skicka detaljer per anrop till loggar eller spårningar och hitta de värsta bovarna med en
PromQL-fråga som den här:

```promql
topk(10, count by (__name__) ({__name__=~".+"}))
```

**En graf visar ett stup eller en topp som aldrig inträffade.** En räknare (counter) går bara uppåt
och faller till noll när processen startar om. Att rita upp det råa värdet, eller subtrahera för
hand, gör varje omstart till en krasch eller en rusning. `rate()` förstår nollställningar, så
beräkna `rate()` först och summera efteråt, över ett fönster som är flera hämtintervall brett:

```promql
sum by (job) (rate(http_requests_total{status=~"5.."}[5m]))
```

En inspelningsregel (recording rule) som summerar en räknare innan `rate()` tas gömmer
nollställningarna inne i summan och tar tillbaka de falska stupen.

**En tjänst går ned och dess larm för felfrekvens förblir grönt.** En regel som felfrekvens över ett
tröskelvärde utvärderas över de serier som finns. När målet försvinner försvinner även dess serier,
uttrycket ger ett tomt resultat och larmet löser upp sig självt i värsta tänkbara ögonblick. Larma
på `up == 0` för varje mål som hämtas, använd `absent()` för varje serie som alltid måste finnas och
låt något utanför servern kontrollera att servern själv är igång.

**Förra kvartalets siffror är borta när någon frågar efter dem.** Den lokala lagringen sparar 15
dagar som standard och är en enda kopia på en enda disk. Den fungerar som ett fönster mot det
senaste beteendet, och som arkiv sviker den. Höj lagringstiden med försiktighet, skicka det som
måste bestå till långtidslagring via `remote_write` och håll siffror som pengar hänger på i en
databas som är den auktoritativa källan för dem.

## Läs mer

- [Prometheus overview](https://prometheus.io/docs/introduction/overview/)
  — projektets egen beskrivning av vad det är, vilka komponenter det har och var det passar dåligt.
- [Data model](https://prometheus.io/docs/concepts/data_model/) — mätvärdesnamn, etiketter och
  mätpunkter, och varför varje nytt etikettvärde startar en ny serie.
- [Metric types](https://prometheus.io/docs/concepts/metric_types/) — counter, gauge, histogram
  och summary, och vilka frågor var och en kan besvara.
- [Querying basics](https://prometheus.io/docs/prometheus/latest/querying/basics/)
  — selektorer i PromQL, intervallvektorer och de typer ett uttryck kan returnera.
- [Storage](https://prometheus.io/docs/prometheus/latest/storage/) — block på två timmar,
  write-ahead-loggen, lagringstiden och gränssnittet för remote write.
- [Metric and label naming](https://prometheus.io/docs/practices/naming/) — basenheter, suffixet
  `_total` och varningen för etiketter med hög kardinalitet.

<https://engineer.company/sv/glossary/prometheus/>
