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.
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éteg | Eszköz | CloudWatch-megfelelő |
|---|---|---|
| lokális fejlesztés | wrangler dev konzol + Chrome DevTools (breakpoint, CPU-profil!) | lokális Node debug |
| élő stream élesből | wrangler tail | aws logs tail --follow |
| tárolt, kereshető logok | Workers Logs (7 nap retention) + Query Builder | CloudWatch Logs Insights |
| elosztott trace-ek | Workers Traces (OpenTelemetry-szabvány) | X-Ray |
| metrikák, percentilisek | dashboard: kérések, hibák, CPU/wall time p50–p99.9, versionönként | CloudWatch Metrics |
| hosszú távú tárolás / saját stack | Logpush, OTel-export (Grafana, Honeycomb, Axiom…) | Kinesis/Firehose export |
| termék-metrikák (nagy kardinalitás) | Analytics Engine — lásd 9.4 | custom metrics (drágán) |
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.
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
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ő.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).
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.
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.
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:
/api/auth/login-ra IP-nként max 10 kérés/perc, fölötte block". Mikor ez, és mikor a 7. modul DO-rate-limitere? A zóna-szabály durva szemcséjű, infra-szintű védelem (brute force, scraping) — ingyen szűri a zajt a Worker előtt. A DO-limiter üzleti logika: tenant-plan-függő, pontos kvóták. Éles SaaS-ban mindkettő kell, más ellen védenek.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étel | Included (Paid) | Fölötte | AWS-párhuzam |
|---|---|---|---|
| Kérések | 10 M/hó | ~$0.30 / M | ALB + Lambda request díjak |
| CPU-idő | 30 M ms/hó | ~$0.02 / M ms | EC2 instance-órák — de itt csak a tényleges munka |
| Statikus asset kérések | ingyen, korlátlanul | CloudFront-forgalom | |
| R2 | tárolás ~$0.015/GB-hó + műveletek; egress: $0 | S3 + a teljes egress-számla | |
| D1 | olvasott/írt sorok + tárolás — üresjáratban ~0 | Aurora instance-órák | |
| KV / Queues | műveletenkénti mikroárak | ElastiCache node-óra / SQS | |
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).
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.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ó:
console.log automatikusan begyűjtődik és indexelődik — nincs mit „kiszállítani", és nincs is hosszú életű processz, amiben egy log-buffer élhetne. A pinót megtarthatod formázónak, de transport nem kell alá.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:
{ "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).
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.
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).
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.
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.
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.
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.
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.
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.
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.