9. modulObservability, biztonság, költségmodell
Cloudflare for Devs · 9. modul

Observability, biztonság, költségmodell

Mit látsz élesben a CloudWatch helyett, mit kapsz a platformtól biztonságban „ingyen", ami AWS-en külön termék volt — és hogyan becsülöd meg előre a havi számlát, konkrét példaszámítással.

9.1A megfigyelhetőség rétegei — a CloudWatch-térkép

AWS-en a megfigyelhetőség egy központba folyt (CloudWatch Logs + Metrics + Alarms + X-Ray), amit te dróztoztál össze. A Workers-nél rétegek vannak, mindegyik a maga feladatára — így fordul a fejedben lévő térkép:

RétegEszközCloudWatch-megfelelő
lokális fejlesztéswrangler dev konzol + Chrome DevTools (breakpoint, CPU-profil!)lokális Node debug
élő stream élesbőlwrangler tailaws logs tail --follow
tárolt, kereshető logokWorkers Logs (7 nap retention) + Query BuilderCloudWatch Logs Insights
elosztott trace-ekWorkers Traces (OpenTelemetry-szabvány)X-Ray
metrikák, percentilisekdashboard: kérések, hibák, CPU/wall time p50–p99.9, versionönkéntCloudWatch Metrics
hosszú távú tárolás / saját stackLogpush, OTel-export (Grafana, Honeycomb, Axiom…)Kinesis/Firehose export
termék-metrikák (nagy kardinalitás)Analytics Engine — lásd 9.4custom metrics (drágán)

9.2Workers Logs a gyakorlatban

A bekapcsolás egy konfig-blokk — és mivel a 8. modul env-fegyelmét már ismered, rögtön környezetenként eltérő mintavétellel mutatom, ahogy élesben érdemes:

wrangler.jsonc
{
  "env": {
    "staging": {
      "observability": { "enabled": true, "head_sampling_rate": 1 }
    },
    "production": {
      "observability": {
        "enabled": true,
        "head_sampling_rate": 0.1,          // minden 10. kérés logja tárolódik
        "traces": { "enabled": true, "head_sampling_rate": 0.05 }
      }
    }
  }
}

A mintavétel head-based: kérés-szinten dől el, és ha egy kérés kiválasztódik, annak minden logsora megmarad — tehát összefüggő invocation-képet kapsz, nem véletlen sortöredékeket. A hibák tipikusan így is fennakadnak, mert a limit- és hiba-események (1102, kivételek) az invocation-státuszban mindig látszanak.

Strukturált logolás: a legjobb befektetésed

A Workers Logs a console.log-ba írt objektumokat mezőnként indexeli — vagyis ha JSON-t logolsz, a dashboard Query Builderében mezőkre szűrhetsz. A te multitenant SaaS-odban ez így néz ki:

// ne: console.log(`hiba a ${tenantId} tenantnál: ${err.message}`)
// hanem:
console.log({
  event: "invoice.create.failed",
  tenantId,
  orderId,
  error: err.message,
  durationMs: Date.now() - start,
});

Ezután a Query Builderben (vagy az API-n át) válaszolhatók a support-kérdések: „az acme tenant összes hibája tegnap óta", „melyik tenant generálja a legtöbb invoice.create.failed-et", „a p99 durationMs eseménytípusonként". Élő hibakereséshez pedig a tail:

npx wrangler tail --env production --status error          # csak a hibák, élőben
npx wrangler tail --env production --format json | jq '.logs'  # szkriptelhetően
Az AsyncLocalStorage-trükk (2. modul kapcsa): a nodejs_compat alatt működő AsyncLocalStorage-dzsal egy request-kontextusba teszed a tenantId-t + egy request ID-t, és a logger-wrappered minden logsorhoz automatikusan hozzáfűzi — pontosan úgy, ahogy a Node-appodban a pino/winston child loggerrel csináltad. A megszokásod itt egy az egyben átvihető.

Verzió-korreláció: a kanári műszerfala

A 8. modul kanári-folyamatának ez adja a szemét: a metrikák és logok versionönként bonthatók (a version metadata bindinggel a saját logjaidba is beírhatod a version ID-t). A kanári-emelés előtti kérdés tehát nem „nőtt-e a hibaarány?", hanem pontosan: „a v42 hibaaránya rosszabb-e, mint a v41-é?" — miközben mindkettő él. Az invocation-státuszok (pl. exceededCpu, exception) ugyanitt, versionre szűrve mutatják meg, ha az új kód CPU-limitet döntöget (2. modul).

9.3Traces: az X-Ray helyett, szabványosan

A Workers Traces OpenTelemetry-szabványú: bekapcsolod (fenti konfig), és a kérés útja — Worker → Hyperdrive-query → R2-hívás → subrequest — span-ekként áll össze a dashboardon. Ami a te szempontodból a lényeg: mivel OTel, zéró extra munkával exportálható a meglévő vagy leendő observability-stackedbe (Grafana Cloud, Honeycomb, Axiom), akár úgy is, hogy a Cloudflare-nél nem is tárolod (persist: false) — tehát nem záródsz be a platform sajáteszközeibe. Magas forgalomnál a trace-mintavételt lőd alacsonyra (1–5%), a logokét magasabbra.

9.4Analytics Engine: tenantonkénti metering — a rejtett gyöngyszem

Van egy kategória, amire se a log, se a platform-metrika nem való: a nagy kardinalitású termék-metrikák — nálad tipikusan a tenantonkénti fogyasztásmérés (usage-based billinghez, limitekhez, admin-dashboardhoz). CloudWatch custom metricsszel ez tenantonként×metrikánként fizetős és fájdalmas volt. Az Analytics Engine pontosan erre van: a Workerből egy sorral írsz egy adatpontot, és utána SQL-lel kérdezed le:

// írás a Workerből — nem blokkol, nem kell await
env.USAGE.writeDataPoint({
  blobs:   [tenantId, "api_call", endpoint],   // dimenziók (szöveg)
  doubles: [1, responseBytes],                 // mértékek (szám)
  indexes: [tenantId],                          // ezen lehet gyorsan szűrni
});
-- lekérdezés a SQL API-n át (pl. a havi számlázási cron-ból):
SELECT blob1 AS tenant, SUM(double1) AS calls, SUM(double2) AS bytes
FROM usage_dataset
WHERE timestamp > NOW() - INTERVAL '30' DAY
GROUP BY tenant

Az adatpontok mintavételezéssel skálázódnak (tehát óriási forgalomnál is olcsó marad), cserébe ez becslés-pontosságú aggregátum — számlázási alapnak bevált gyakorlat, fillérre pontos főkönyvnek nem való (azt D1-ben könyveled). A hármas felosztás tehát: Workers Logs = hibakeresés (7 nap), Analytics Engine = termék/üzleti metrikák (hónapok), D1 = tranzakcionális igazság.

9.5Biztonság: ami a platformból jön

Itt fordul a legnagyobbat a világ az AWS-hez képest: ami ott külön termék, külön számla és külön konfiguráció volt (Shield, WAF, API Gateway throttling, Cognito egy része), az itt a platform rétegei — a kérés már átesett rajtuk, mire a Workered meghívódik:

👤 DDoS-védelem automatikus WAF managed + custom Rate limiting zóna-szabályok Bot / Turnstile ember-e? a te Workered app-szintű logika
9. ábra — A kérés útja: mire a kódod fut, a zaj nagy része már kiszűrődött — és a kiszűrt kérésekért nem is fizetsz Worker-díjat.

9.6A költségmodell — és egy végigszámolt példa

A Workers Paid $5/hó alapdíjból plusz fogyasztásból áll. A mentális modell minden komponensnél ugyanaz: bőséges included keret + lineáris túlfogyasztási ár, üresjárati díj nélkül. A fő tételek (nagyságrendek — az aktuális árlista a developers.cloudflare.com/workers/platform/pricing oldalon):

TételIncluded (Paid)FölötteAWS-párhuzam
Kérések10 M/hó~$0.30 / MALB + Lambda request díjak
CPU-idő30 M ms/hó~$0.02 / M msEC2 instance-órák — de itt csak a tényleges munka
Statikus asset kérésekingyen, korlátlanulCloudFront-forgalom
R2tárolás ~$0.015/GB-hó + műveletek; egress: $0S3 + a teljes egress-számla
D1olvasott/írt sorok + tárolás — üresjáratban ~0Aurora instance-órák
KV / Queuesműveletenkénti mikroárakElastiCache node-óra / SQS

Példaszámítás: egy közepes SaaS hónapja

Tegyük fel: 20 M dinamikus kérés/hó (API + SSR), átlag 5 CPU-ms/kérés (emlékezz a 2. modul idővonalára: a DB-várakozás nem számít!), plusz a statikus forgalom (ingyen):

Alapdíj:                                          $5.00
Kérések:  20M − 10M included = 10M × $0.30/M  =   $3.00
CPU:      20M × 5ms = 100M ms − 30M included
          = 70M ms × $0.02/M ms               =   $1.40
                                              ─────────
Workers compute összesen:                        ~$9.40/hó

Ehhez jön a tárolás (R2/D1/KV — jellemzően dollárok, nem tízdollárok ebben a méretben), és ennyi. Amit érdemes a mostani számláddal szembeállítani: a Beanstalk EC2-instance-ok (éjjel is), az ALB, a NAT gateway, a CloudFront-forgalom és az S3-egress — ezek a tételek itt vagy nem léteznek, vagy nullák. A tipikus tapasztalat ebben a méretosztályban: nagyságrendi csökkenés a compute+CDN+egress vonalon; ami marad érdemi tételnek, az az Aurora (amíg meg nem válaszolod az 5. modul kérdését).

Mitől tud mégis elszaladni a számla? Három tipikus ok: ① CPU-falánk kód (nagy JSON-ok szinkron feldolgozása, nehéz kriptó) — ezt a versionönkénti CPU-percentiliseken (9.2) kiszúrod, és a limits.cpu_ms-sel (2. modul) plafonozod; ② forgalmi anomália/scraping — erre a zóna-szintű rate limiting a védelem, ami a Worker előtt szűr, tehát a kiszűrt kérés nem is számláz; ③ önmagát hívó Worker vagy queue-retry-vihar — ezért volt a 7. modulban a NonRetryableError és a DLQ. A biztonsági háló: billing notifications a dashboardon — állíts be értesítést a várható havi költség küszöbére, az első hónapban mindenképp.

9.7Error tracking: kell-e külön eszköz a Nuxt server-kód mellé?

Jogos kérdés, hogy az eddigiek mellett kell-e még Sentry/Honeybadger-féle eszköz. A válasz két részre bomlik, mert két különböző munkáról van szó:

Mi illik a Workers-runtime-hoz?

A Sentry-protokoll de facto szabvány lett: a legtöbb alternatíva Sentry-SDK-kompatibilis, tehát a kódba a @sentry/cloudflare SDK megy (ez kifejezetten a Workers-runtime-ra készült, és a Nitro server-oldalon is működik), és csak a DSN-t irányítod máshova. A kódod így nem köteleződik el egyetlen szolgáltató mellett sem. A source map feltöltést kapcsold be, különben minifikált kódot látsz a trace-ekben:

wrangler.jsonc
{ "upload_source_maps": true }

A Node-alapú SDK-k (pl. a Honeybadger klasszikus kliense) Node API-kra támaszkodhatnak — ezek vagy nem, vagy csak vékony saját wrapperrel mennek Workersből (fetch-hívás a reporting API-ra, ctx.waitUntil()-lel, hogy ne késleltesse a választ).

Ajánlott recept, ha self-hosted és olcsó kell: Bugsink Renderen. A Bugsink kifejezetten könnyűsúlyú, Sentry-DSN-kompatibilis hibakövető. Renderen két értelmes felállás van: (a) Starter web service + persistent disk + SQLite (~$8/hó) — a legolcsóbb, de diszkes service-nél a deploy nem zero-downtime; (b) Starter web service + managed Postgres (~$13–14/hó) — diszk nélkül, zero-downtime deploy, szabványos backup/restore, később skálázható. Éles használatra a (b) a platform-natív út. Fontos pontosítás: a „nem alszik" csak a fizetős szintre igaz, a free tier leáll inaktivitásnál — egy error trackernél ez kizáró ok, mert pont akkor kell ébren lennie, amikor minden más ég. Ugyanezért ne tedd Cloudflare Containersbe sem: az efemer diszkű, elalvó konténer nem hibakövetőnek való (és az observabilityt amúgy sem szerencsés arra a platformra tenni, amit figyel).

A végállapot tehát: Workers Logs (debug) + Analytics Engine (termék-metrikák) a platformról, plusz egy error tracker a hibák életciklusára. Ez lefedi, amit ma CloudWatch + Honeybadger párossal kapsz — a verzió-korrelált metrikákkal (9.2) még többet is.

9.8Riasztások — az őszinte kép

A beépített notifications rendszer értesít a fontos eseményekről (Workers-hibaküszöbök, usage/billing küszöbök, SSL-lejárat stb. — email/webhook/PagerDuty). Ez a mindennapi „szólj, ha baj van" szintet lefedi. Amit őszintén ki kell mondani: a CloudWatch Alarms-féle, tetszőleges metrikára írt, összetett riasztási logika beépítve nincs ilyen mélységben. A bevált minta emiatt: az OTel-exporton (9.3) a logok/trace-ek a meglévő stackedbe (Grafana, Honeycomb…) folynak, és a riasztási agy ott él — a Cloudflare a jel, a te eszközöd a sziréna. Kis csapatnak addig is sokat ad egy 5 perces cron-Worker, ami a Query Builder API-n lekérdezi az elmúlt 5 perc hibaszámát, és küszöb fölött Slackre ír (7. modul mintáival ez fél óra munka).

9.9Ellenőrizd magad

  1. Miért JSON-objektumot logolj string helyett, és mit kapsz érte a Workers Logsban?
    Válasz

    A Workers Logs az objektum mezőit indexeli: a Query Builderben mezőkre (tenantId, event, durationMs…) szűrhetsz és aggregálhatsz — a string-log csak full-text keresést adna. A support-kérdések („az acme összes hibája tegnap óta") így kattintásokká válnak.

  2. Prodban 10%-os log-mintavételt állítasz. Elveszted-e a hibák láthatóságát?
    Válasz

    A mintavétel head-based és kérés-szintű: a kiválasztott kérések teljes log-kontextusa megmarad. A hiba-arányokat az invocation-metrikák mintavétel nélkül mutatják, tehát a trend mindig pontos; a részletes hibalogok 10%-a jellemzően bőven elég a diagnózishoz — ha nem, a rate emelhető, vagy a hibás útvonalra célzott logolást teszel.

  3. Mi a szereposztás a Workers Logs, az Analytics Engine és a D1 között az adataidra nézve?
    Válasz

    Workers Logs: hibakeresés, 7 napos ablak. Analytics Engine: nagy kardinalitású termék/üzleti metrikák (tenant-usage, metering) — mintavételezett, becslés-pontosságú, SQL-lel kérdezhető. D1: a tranzakcionális igazság (fillérre pontos számlázási tételek). Ami számla lesz, az D1-be is könyvelődik; az AE a trend és a dashboard.

  4. Mikor véd a zóna-szintű rate limiting és mikor a DO-alapú limiter — miért kell mindkettő?
    Válasz

    A zóna-szabály a Worker előtt fut, infra-szintű, durva védelem (brute force, scraping) — a kiszűrt kérés nem is számláz. A DO-limiter app-szintű üzleti kvóta (tenant-plan-függő, pontos). Más fenyegetés, más szemcse: a zóna-szabály a zajt fogja, a DO a szerződéses limitet érvényesíti.

  5. Számold ki: 40 M kérés/hó, átlag 8 CPU-ms. Mennyi kb. a Workers compute-költség?
    Válasz

    Alapdíj $5. Kérések: 40M−10M = 30M × $0.30/M = $9. CPU: 320M ms − 30M = 290M × $0.02/M = $5.80. Összesen ≈ $19.80/hó — egy t3.medium páros + ALB árának a törtrésze, nulla üresjárati díjjal.

  6. Mi a kanári-emelés előtti ellenőrzés helyes formája a metrikákban?
    Válasz

    Versionönkénti bontás: a v42 hibaaránya, invocation-státuszai (exception, exceededCpu) és CPU-percentilisei a v41-ével egyidejűleg összevetve — nem az összforgalom átlagát nézed, mert abban a 10%-os kanári hatása elmosódik.

  7. A Workers Logs mellé miért kell mégis error tracker, és mi az, amit a kódodban nem kell lecserélned a váltáskor?
    Válasz

    A Logs log-rendszer: nincs benne hiba-csoportosítás issue-vá, dedup, resolved/regression életciklus, értesítés új hibatípusra, release-korreláció. Ezt egy error tracker adja. A kódban a @sentry/cloudflare SDK marad akkor is, ha nem a Sentryt használod — a legtöbb alternatíva (pl. Bugsink) Sentry-DSN-kompatibilis, tehát csak a DSN változik.

Előző8. modul — CI/CD, környezetek, migrációk, release-stratégia Következő 10. modul — Migrációs stratégia: a te stacked átállítása