{"skill":{"slug":"cf-workers-logs","displayName":"Cf Workers Logs","summary":"Query Cloudflare Workers Observability logs via API. Use when the user asks to check logs, debug Workers, look up errors, or investigate Worker/Durable Objec...","description":"---\nname: cf-workers-logs\ndescription: |\n  Query Cloudflare Workers Observability logs via API. Use when the user asks to check logs,\n  debug Workers, look up errors, or investigate Worker/Durable Object/Workflow behavior.\n  Triggers on keywords like \"check logs\", \"worker logs\", \"look up error\", \"debug worker\".\nmetadata: '{\"openclaw\":{\"requires\":{\"env\":[\"CF_OBSERVABILITY_ACCOUNT_ID\",\"CF_OBSERVABILITY_API_TOKEN\"],\"bins\":[\"curl\"]}}}'\nuser-invocable: true\nhomepage: https://github.com/adaHubble/cf-workers-logs\n---\n\n# Query Cloudflare Workers Observability Logs\n\nQuery the CF Workers Observability API to retrieve structured logs from any Workers, Durable Objects, Workflows, Queues, and Cron Triggers in your Cloudflare account.\n\n## Prerequisites\n\nSet these environment variables (e.g. in your project's `.env` or shell profile):\n\n- `CF_OBSERVABILITY_ACCOUNT_ID` — your Cloudflare account ID\n- `CF_OBSERVABILITY_API_TOKEN` — API token with Workers Observability read permission\n\n## API Endpoint\n\n```\nPOST https://api.cloudflare.com/client/v4/accounts/{accountId}/workers/observability/telemetry/query\nAuthorization: Bearer {apiToken}\nContent-Type: application/json\n```\n\n## Request Body Format\n\n```json\n{\n  \"queryId\": \"cc-{timestamp}\",\n  \"timeframe\": {\n    \"from\": \"<unix_ms_start>\",\n    \"to\": \"<unix_ms_end>\"\n  },\n  \"view\": \"events\",\n  \"limit\": 50,\n  \"parameters\": {\n    \"filters\": [\n      {\"key\": \"<field>\", \"operation\": \"<op>\", \"type\": \"<type>\", \"value\": \"<value>\"}\n    ],\n    \"filterCombination\": \"and\",\n    \"calculations\": [],\n    \"groupBys\": [],\n    \"needle\": {\"value\": \"<search_text>\", \"isRegex\": false, \"matchCase\": false},\n    \"limit\": 50\n  }\n}\n```\n\n### Filter Operations\n\n- String: `eq`, `neq`, `includes`, `doesNotInclude`, `startsWith`, `regex`, `exists`, `doesNotExist`\n- Number: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `exists`, `doesNotExist`\n\n### Standard Fields\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `$workers.scriptName` | string | Worker script name |\n| `$workers.outcome` | string | `ok` / `exception` |\n| `$workers.entrypoint` | string | Entrypoint class (Worker, DO, Workflow) |\n| `$workers.eventType` | string | `fetch`, `rpc`, `queue`, `scheduled`, `alarm` |\n| `msg` | string | Log message |\n| `level` | string | Log level (`log`, `info`, `warn`, `error`) |\n| `error` | string | Error message |\n| `status` | number | HTTP status code |\n\nAny custom fields logged via `console.log({ key: value })` are also queryable as top-level fields.\n\n### Full-text Search\n\nUse `needle.value` for free-text search across all fields. Useful when you don't know which field contains the value.\n\n## How to Execute\n\nUse Bash with `curl` to call the API. **Do NOT use WebFetch** (it processes through an AI model and loses structure).\n\n### Step 1: Read credentials\n\nRead `CF_OBSERVABILITY_ACCOUNT_ID` and `CF_OBSERVABILITY_API_TOKEN` from environment variables. If not set in the shell, search for them in project `.env` files:\n\n```bash\ngrep -r 'CF_OBSERVABILITY_' --include='.env' --include='.env.*' . 2>/dev/null\n```\n\n### Step 2: Build and execute query\n\nConstruct the curl command based on the user's request. Default time range: last 1 hour. Default limit: 30.\n\n### Step 3: Format output\n\nParse the JSON response and format as a timeline:\n\n```\n{timestamp} [{level}] [{scriptName}/{entrypoint}] {msg}\n         {extra fields if present: error=, status=, eventType=}\n```\n\nEvents are in `result.events.events[]`. Each event has:\n- `source`: structured log fields (msg, level, plus any custom fields)\n- `$workers`: Worker metadata (scriptName, outcome, eventType, entrypoint)\n- `$metadata`: system metadata (timestamp, requestId)\n- `timestamp`: event timestamp in unix ms\n\nSort events by timestamp ascending for chronological view.\n\n## Common Query Patterns\n\n### By Worker name\n```json\n{\"filters\": [{\"key\": \"$workers.scriptName\", \"operation\": \"eq\", \"type\": \"string\", \"value\": \"my-worker\"}]}\n```\n\n### Errors only\n```json\n{\"filters\": [{\"key\": \"level\", \"operation\": \"eq\", \"type\": \"string\", \"value\": \"error\"}]}\n```\n\n### By entrypoint (Durable Object / Workflow class)\n```json\n{\"filters\": [{\"key\": \"$workers.entrypoint\", \"operation\": \"eq\", \"type\": \"string\", \"value\": \"MyDurableObject\"}]}\n```\n\n### By event type (alarm, queue, scheduled, etc.)\n```json\n{\"filters\": [{\"key\": \"$workers.eventType\", \"operation\": \"eq\", \"type\": \"string\", \"value\": \"alarm\"}]}\n```\n\n### Exceptions (Worker crashed)\n```json\n{\"filters\": [{\"key\": \"$workers.outcome\", \"operation\": \"eq\", \"type\": \"string\", \"value\": \"exception\"}]}\n```\n\n### Custom field filter\n```json\n{\"filters\": [{\"key\": \"userId\", \"operation\": \"eq\", \"type\": \"string\", \"value\": \"user_123\"}]}\n```\n\n### Free-text search\n```json\n{\"needle\": {\"value\": \"search text here\", \"isRegex\": false, \"matchCase\": false}}\n```\n\n### Combine filters\n```json\n{\n  \"filters\": [\n    {\"key\": \"$workers.scriptName\", \"operation\": \"eq\", \"type\": \"string\", \"value\": \"my-worker\"},\n    {\"key\": \"level\", \"operation\": \"eq\", \"type\": \"string\", \"value\": \"error\"}\n  ],\n  \"filterCombination\": \"and\"\n}\n```\n\n## Argument Parsing\n\nWhen invoked as `/cf-workers-logs`, parse `$ARGUMENTS` for:\n\n- `worker=my-worker` → filter by `$workers.scriptName`\n- `level=error` → filter by level\n- `entrypoint=MyDO` → filter by `$workers.entrypoint`\n- `event=alarm` → filter by `$workers.eventType`\n- `search=xxx` → needle search\n- `<key>=<value>` → filter by custom field\n- `last=1h` / `last=30m` / `last=24h` → time range (default: 1h)\n- `limit=N` → result limit (default: 30)\n- No arguments → show recent errors across all Workers (last 1h, level=error)\n\nMultiple arguments can be combined: `/cf-workers-logs worker=my-api level=error last=24h`\n","tags":{"latest":"1.0.1"},"stats":{"comments":0,"downloads":543,"installsAllTime":0,"installsCurrent":0,"stars":0,"versions":2},"createdAt":1773653733559,"updatedAt":1778491943830},"latestVersion":{"version":"1.0.1","createdAt":1773654100092,"changelog":"Improve README: add CF token setup guide and detailed usage docs","license":"MIT-0"},"metadata":{"setup":[{"key":"CF_OBSERVABILITY_ACCOUNT_ID","required":true},{"key":"CF_OBSERVABILITY_API_TOKEN","required":true}],"os":null,"systems":null},"owner":{"handle":"adahubble","userId":"s17d0gxb6wbprsqjjm6s9e5nah885bwb","displayName":"adaHubble","image":"https://avatars.githubusercontent.com/u/200054160?v=4"},"moderation":null}