INTEGRITY Dokumentace

Observabilita

Dynamic Workers podporují logy s console.log() volání, výjimky a metadata požadavků zachycená během provádění. Pro přístup k těmto logům připojte Tail Worker, callback, který se spustí po dokončení Dynamic Workeru a předá všechny logy, výjimky a metadata, které shromáždil.

Tento průvodce vám ukáže, jak:

Zachytávání protokolů pomocí Tail Workerů

Chcete-li uložit logy generované Dynamic Workerem, musíte je zachytit a zapsat je někam, kde je bude možné uchovávat. Nastavení vyžaduje tři kroky:

  1. Povolení Workers Logs na loader Workeru, aby se výstup logů ukládal.
  2. Definování Tail Workeru, který přijímá protokoly z Dynamic Workeru a zapisuje je do Workers Logs.
  3. Připojení Tail Workeru k Dynamic Workeru při jeho vytváření.

Povolte Workers Logs na načítacím Workeru

Povolit Workers Logs přidáním observability nastavení do konfigurace Wrangler pro loader Worker. Workers Logs ovšem zachytávají výstup logů pouze ze samotného loader Workeru. Dynamic Workery jsou samostatné, takže jejich console.log() volání se do nich automaticky nezahrnují. Aby se logy Dynamic Workeru dostaly do Workers Logs, musíte definovat Tail Worker, který přijímá logy z Dynamic Workeru a zapisuje je do Workers Logs loader Workeru.

{
  "$schema": "./node_modules/wrangler/config-schema.json",
  "observability": {
    "enabled": true,
    "head_sampling_rate": 1
  }
}
[observability]
enabled = true
head_sampling_rate = 1

Definování Tail Workeru

Když Dynamic Worker běží, runtime shromažďuje veškeré jeho console.log() volání, výjimky a metadata požadavků. Ve výchozím nastavení se tyto logy po dokončení Dynamic Workeru zahodí.

Chcete-li je uchovat, definujte na loader Workeru Tail Worker. Tail Worker je třída s tail() metodu. Sem patří kód, který rozhoduje, co se s logy stane. Runtime tuto metodu zavolá po dokončení Dynamic Workeru a předá mu vše, co bylo během vykonávání shromážděno.

Uvnitř tail(), každý záznam logu zapíšete do Workers Logs zavoláním console.log() s objektem JSON. Zahrňte do něj workerId pole v každém záznamu, abyste poznali, který Dynamic Worker daný log vytvořil, a mohli podle Dynamic Workeru logy později filtrovat a vyhledávat.

import { WorkerEntrypoint } from "cloudflare:workers";

export class DynamicWorkerTail extends WorkerEntrypoint {
	async tail(events) {
		for (const event of events) {
			for (const log of event.logs) {
				console.log({
					source: "dynamic-worker-tail",
					workerId: this.ctx.props.workerId,
					level: log.level,
					message: log.message,
				});
			}
		}
	}
}

Tail Worker přečte workerId z this.ctx.props.workerId. Tuto hodnotu nastavíte v dalším kroku, když k Dynamic Workeru připojíte Tail Worker.

Protože je Tail Worker definován uvnitř loader Workeru, jeho console.log() výstup se ukládá do Workers Logs spolu s vlastními logy loader Workeru.

Připojení Tail Workeru k Dynamic Workeru

Při vytváření Dynamic Workeru předejte Tail Worker v tails pole. Tím runtime sdělíte, že jakmile tento Dynamic Worker skončí, má odeslat shromážděné logy do Tail Workeru, který jste definovali.

Chcete-li odkázat na DynamicWorkerTail třídu, kterou jste definovali v předchozím kroku, použijte ctx.exports. ctx je třetí parametr loader Workeru v fetch(request, env, ctx) handler. ctx.exports vám dává přístup ke třídám exportovaným z loader Workeru. Protože Dynamic Worker běží v samostatném kontextu a nemůže třídu přímo použít, použijete ctx.exports.DynamicWorkerTail() k vytvoření reference, kterou runtime dokáže propojit s Dynamic Workerem.

Dále musíte Tail Workeru sdělit, pro který Dynamic Worker vede logy. Protože Tail Worker běží odděleně od fetch() handleru, nemá přístup k vašim lokálním proměnným. Chcete-li mu předat informace, použijte props při vytváření instance. props je obyčejný objekt dvojic klíč-hodnota, který nastavíte při připojování Tail Workeru a který Tail Worker může číst na this.ctx.props při spuštění. V takovém případě předáte workerId aby Tail Worker věděl, který Dynamic Worker logy vytvořil.

const worker = env.LOADER.get(workerId, () => ({
	mainModule: WORKER_MAIN,
	modules: {
		[WORKER_MAIN]: WORKER_SOURCE,
	},
	tails: [
		ctx.exports.DynamicWorkerTail({
			props: { workerId },
		}),
	],
}));

return worker.getEntrypoint().fetch(request);

Vracení logů v reálném čase

Výše uvedené nastavení ukládá logy pro pozdější použití, ale někdy potřebujete logy okamžitě pro vývoj v reálném čase. Problém je v tom, že Tail Worker a loader Worker mají každý vlastní fetch() handler se spouští odděleně. Tail Worker má logy, ale fetch() handler je ten, kdo sestavuje odpověď. Potřebujete sdílené místo, kam může Tail Worker zapisovat logy a odkud je fetch() handler je může číst.

A Durable Object se pro tento účel hodí dobře. Jak Tail Worker, tak fetch() handler může podle názvu vyhledat stejnou instanci Durable Object. Tail Worker do ní po dokončení Dynamic Workeru zapíše logy a fetch() handler je vyčte a zahrne do odpovědi.

Vzor funguje takto:

  1. fetch() handler před spuštěním Dynamic Workeru vytvoří relaci pro logy v Durable Object.
  2. Dynamic Worker se spustí a vytváří logy.
  3. Po dokončení Dynamic Workeru zapíše Tail Worker shromážděné protokoly do stejného Durable Object.
  4. fetch() handler čte logy z Durable Object a vrací je v odpovědi.
import { exports } from "cloudflare:workers";

// 1. Create a log session before running the Dynamic Worker.
const logSession = exports.LogSession.getByName(workerName);
const logWaiter = await logSession.waitForLogs();

// 2. Run the Dynamic Worker.
const response = await worker.getEntrypoint().fetch(request);

// 3. Wait up to 1 second for the Tail Worker to deliver logs.
const logs = await logWaiter.getLogs(1000);

Kompletní funkční implementaci najdete v Příklad Dynamic Workers Playground ↗.