Cloudflare Workers
Cloudflare Workers
Tail Workers for real-time logs, or Logpush for zone-wide HTTP data.
Two options. A Tail Worker gets you a Worker's own console output within a second; Logpush gets you every HTTP request across a zone in batches.
Tail Worker
export default {
async tail(events: TraceItem[], env: Env) {
const rows = events.flatMap((e) =>
e.logs.map((log) => ({
_time: log.timestamp,
level: log.level,
script: e.scriptName,
outcome: e.outcome,
message: log.message.join(" "),
...(e.event && "request" in e.event
? { url: e.event.request.url, method: e.event.request.method }
: {}),
})),
);
if (!rows.length) return;
await fetch("https://api.logstreem.com/v1/ingest/cloudflare-workers", {
method: "POST",
headers: {
Authorization: `Bearer ${env.LOGSTREEM_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify(rows),
});
},
};Logpush
cURL
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/logpush/jobs" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "logstreem-http",
"dataset": "http_requests",
"destination_conf": "https://api.logstreem.com/v1/ingest/cloudflare-http?header_Authorization=Bearer%20'"$LOGSTREEM_TOKEN"'",
"output_options": {
"field_names": ["EdgeStartTimestamp","ClientIP","ClientRequestHost","ClientRequestMethod","ClientRequestURI","EdgeResponseStatus","EdgeTimeToFirstByteMs","RayID"],
"timestamp_format": "rfc3339"
},
"enabled": true
}'Different latency, different job
Tail Workers are near-real-time and Worker-scoped — right for debugging. Logpush batches every few minutes and is zone-wide — right for traffic analysis. Most teams run both, into different datasets.