CLI for querying Cloudflare Workers Observability logs
Project description
cf-logs
CLI for querying Cloudflare Workers Observability logs.
Install
pip install cf-logs
Or run directly without installing:
uvx cf-logs events -s 1h
Setup
Set your Cloudflare credentials (or create a .env file):
export CF_ACCOUNT_ID="your-account-id"
export CF_API_TOKEN="your-api-token"
The API token needs the Workers Observability Read permission (and Write for managing destinations).
Usage
cf-logs COMMAND [OPTIONS]
Run cf-logs COMMAND --help for detailed usage and examples.
Commands
| Command | Description |
|---|---|
events |
Fetch individual log events |
query |
Run aggregate queries (counts, percentiles, etc.) |
invocations |
Fetch logs grouped by request |
tail |
Live-tail logs (like tail -f) |
keys |
List available field keys |
values |
List unique values for a field |
destinations |
Manage OpenTelemetry export destinations |
Preset filters
The events command has built-in presets for common debugging scenarios via -p:
| Preset | What it filters |
|---|---|
errors |
Log level = error |
exceptions |
Unhandled exceptions (outcome = exception) |
5xx |
HTTP 5xx responses |
4xx |
HTTP 4xx responses |
slow |
Slow requests (wall time >= 1s) |
cold |
Cold start requests |
cpu |
Exceeded CPU or memory limits |
cf-logs events -p errors # all errors in last hour
cf-logs events -p 5xx -w my-api -s 24h # 5xx for a worker, last 24h
cf-logs events -p slow -j # slow requests as JSON
cf-logs events -p exceptions -n "db" # exceptions mentioning "db"
Presets combine with other filters, so -p 5xx -w my-api -n "timeout" all work together.
Common scenarios
Something is broken — what's happening?
# Quick look at errors
cf-logs events -p errors -w my-api
# Are there unhandled exceptions?
cf-logs events -p exceptions -w my-api -s 30m
# What's the error rate?
cf-logs query -c COUNT -g '$workers.outcome' -w my-api -s 1h
Investigating slow responses
# Find slow requests
cf-logs events -p slow -w my-api
# P99 and P50 latency
cf-logs query -c P99:'$workers.wallTimeMs' -c P50:'$workers.wallTimeMs' -w my-api -s 6h
# Latency by endpoint
cf-logs query -c P99:'$workers.wallTimeMs' -g '$workers.event.request.url' -w my-api
Monitoring a deploy
# Tail logs in real time
cf-logs tail -w my-api
# Tail only errors
cf-logs tail -w my-api -f '$metadata.level=error'
# Watch for 5xx
cf-logs tail -w my-api -f '$workers.event.response.status>=500' -i 2
Understanding traffic patterns
# Requests per worker
cf-logs query -c COUNT -g '$workers.scriptName' -s 24h
# Status code distribution
cf-logs query -c COUNT -g '$workers.event.response.status' -w my-api
# Traffic over time (5-min buckets)
cf-logs query -c COUNT --granularity 300 -w my-api -s 6h -j
Tracing a specific request
# View all logs for recent invocations
cf-logs invocations -w my-api -s 15m
# Find failed invocations
cf-logs invocations -f '$workers.outcome=exception' -s 1h
Examples
Fetch recent events
# Last hour of events (default)
cf-logs events
# Last 24 hours for a specific worker
cf-logs events -s 24h -w my-api
# Events with 5xx status codes
cf-logs events -f '$workers.event.response.status>=500'
# Search for "timeout" in log messages
cf-logs events -n "timeout"
# Exceptions or errors (OR filter)
cf-logs events -f '$workers.outcome=exception' -f '$metadata.level=error' --or
# Raw JSON output for piping to jq
cf-logs events -w my-api -j | jq '.events.events[].["$metadata"].message'
Aggregate queries
# Total event count (default)
cf-logs query
# Count events per worker
cf-logs query -c COUNT -g '$workers.scriptName'
# P99 latency over the last 24 hours
cf-logs query -c P99:'$workers.wallTimeMs' -s 24h
# Average CPU time per worker, sorted descending
cf-logs query -c AVG:'$workers.cpuTimeMs' -g '$workers.scriptName' -o AVG:desc
# Error rate by status code
cf-logs query -c COUNT -g '$workers.event.response.status' -w my-api
# Multiple calculations at once
cf-logs query -c COUNT -c P50:'$workers.wallTimeMs' -c P99:'$workers.wallTimeMs'
# Time-series with 5-minute buckets
cf-logs query -c COUNT -g '$workers.outcome' --granularity 300 -j
# Only show groups with more than 100 events
cf-logs query -c COUNT -g '$workers.scriptName' -H 'COUNT>100'
Live tail
# Tail all logs
cf-logs tail
# Tail a specific worker
cf-logs tail -w my-api
# Tail errors only, poll every 2 seconds
cf-logs tail -f '$metadata.level=error' -i 2
# Tail as JSON for piping
cf-logs tail -w my-api -j | jq '.["$metadata"].message'
Discover fields and values
# List all available field keys
cf-logs keys
# Search for keys related to "status"
cf-logs keys -S status
# List all worker names
cf-logs values '$workers.scriptName'
# List all outcomes for a worker
cf-logs values '$workers.outcome' -w my-api
# List HTTP status codes (numeric field)
cf-logs values '$workers.event.response.status' -t number
Manage export destinations
# List configured destinations
cf-logs destinations list
# Create an OTLP destination
cf-logs destinations create \
--name my-collector \
--type otlp \
--endpoint https://otel.example.com/v1/traces \
-H 'Authorization=Bearer token123'
# Disable a destination
cf-logs destinations update my-collector-slug --disabled
# Delete a destination
cf-logs destinations delete my-collector-slug -y
Filter syntax
Filters are passed with -f and support these operators:
| Syntax | Operator |
|---|---|
key=value |
equals |
key!=value |
not equals |
key>value |
greater than |
key>=value |
greater than or equal |
key<value |
less than |
key<=value |
less than or equal |
key~=pattern |
regex match |
key::value |
contains substring |
key!:value |
does not contain |
key^=value |
starts with |
key@=a,b,c |
value in list |
key@!=a,b,c |
value not in list |
key? |
field exists |
key!? |
field is null |
Multiple -f flags are combined with AND by default. Use --or to combine with OR.
Common fields
| Field | Description |
|---|---|
$workers.scriptName |
Worker script name |
$workers.outcome |
ok, exception, exceededCpu, exceededMemory, canceled |
$workers.wallTimeMs |
Wall clock time in ms |
$workers.cpuTimeMs |
CPU time in ms |
$workers.eventType |
fetch, scheduled, cron, queue, alarm, email, rpc |
$workers.executionModel |
stateless or durableObject |
$workers.event.response.status |
HTTP response status code |
$metadata.level |
log, debug, info, warn, error |
$metadata.message |
Log message text |
$metadata.requestId |
Request ID |
$metadata.traceId |
Trace ID |
Calculation operators
Used with -c in the query command:
COUNT, UNIQ, AVG, SUM, MIN, MAX, MEDIAN, STDDEV, VARIANCE, P01, P05, P10, P25, P75, P90, P95, P99, P999
Format: OPERATOR (for count) or OPERATOR:field (for field aggregations).
Time formats
The --since and --until options accept:
- Durations:
30s,5m,1h,7d,2w,1h30m - ISO datetimes:
2024-01-15T10:00:00
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cf_logs-0.2.1.tar.gz.
File metadata
- Download URL: cf_logs-0.2.1.tar.gz
- Upload date:
- Size: 22.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e34462f209ce456f45888047e438b9607ea41b0a751f699889838741a7fc6f94
|
|
| MD5 |
ccc4ac2a132d85a82fc0505514426659
|
|
| BLAKE2b-256 |
af863d874845d9cfcd3bbc8174be8f620f5f6d73c7b5c360a48e546266946cb0
|
File details
Details for the file cf_logs-0.2.1-py3-none-any.whl.
File metadata
- Download URL: cf_logs-0.2.1-py3-none-any.whl
- Upload date:
- Size: 13.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5be5d30ca726e97c726c0a9e95dd58eae321959d7aecb648b0517aa9dd2d3b88
|
|
| MD5 |
a36ace5b202344e5828b117f4dfe289b
|
|
| BLAKE2b-256 |
969d3b711ffa0db8b1b4acb2d2f4ddc16c8c1c7909530debbfb301a880499aa1
|