---
url: https://simpledatalogs.com/docs/integrations/cloudflare.md
description: >-
  Send Cloudflare HTTP request logs and Workers trace events to simpledatalogs
  with a Logpush job to an HTTP destination.
---

# Cloudflare

Cloudflare Logpush posts batches of logs to an HTTP destination. Point a job at `/v1/ingest`, and each record becomes an event.

Logpush needs an Enterprise zone for HTTP requests, or a Workers Paid plan for Workers trace events.

## The destination

```text
https://edge.simpledatalogs.com/v1/ingest?header_Authorization=Bearer%20sdl_sec_…&header_Content-Type=application%2Fx-ndjson&header_Content-Encoding=gzip
```

* `header_…` parameters become request headers. Logpush always gzips, and the last one says so.
* Logpush tests the destination with one small upload. It shows up once in Unparsed as `missing_event`.

## HTTP requests

Create the job with a `record_template`, so each request gets an id and a time:

```sh
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/logpush/jobs" \
  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  --json '{
    "name": "simpledatalogs",
    "dataset": "http_requests",
    "destination_conf": "https://edge.simpledatalogs.com/v1/ingest?header_Authorization=Bearer%20sdl_sec_…&header_Content-Type=application%2Fx-ndjson&header_Content-Encoding=gzip",
    "max_upload_records": 1000,
    "output_options": {
      "field_names": ["RayID", "EdgeStartTimestamp", "ClientRequestHost", "ClientRequestMethod", "ClientRequestPath", "EdgeResponseStatus", "CacheCacheStatus", "EdgeColoCode"],
      "timestamp_format": "rfc3339ms",
      "record_template": "\"event\":\"http_request\",\"event_id\":{{.RayID}},\"ts\":{{.EdgeStartTimestamp}},\"host\":{{.ClientRequestHost}},\"method\":{{.ClientRequestMethod}},\"path\":{{.ClientRequestPath}},\"status\":{{.EdgeResponseStatus}},\"cache\":{{.CacheCacheStatus}},\"colo\":{{.EdgeColoCode}}"
    },
    "enabled": true
  }'
```

* Each request is an `http_request` event, deduped on its Ray ID.
* Leave `ClientIP` out of `field_names`; it would be stored as sent.

## Workers trace events

Use the account endpoint (`/accounts/$ACCOUNT_ID/logpush/jobs`) with `"dataset": "workers_trace_events"` and:

```json
"output_options": {
  "field_names": ["EventTimestampMs", "ScriptName", "Outcome", "Logs", "Exceptions"],
  "record_template": "\"event\":\"worker_invocation\",\"ts\":{{.EventTimestampMs}},\"script\":{{.ScriptName}},\"outcome\":{{.Outcome}},\"logs\":{{.Logs}},\"exceptions\":{{.Exceptions}}"
}
```

Each invocation is a `worker_invocation` event, with its `console.log` lines under `logs`. These records carry no id, so a retried batch can count twice.

## Keep the volume down

::: warning Every request is an event
An HTTP requests job sends one record per request to the zone. Use `"sample_rate": 0.1` in `output_options`, or a `filter` on the job, to send fewer.
:::

* Keep `max_upload_records` at 1000, so each gzipped batch stays well under the 512 KB limit.

Tested by posting Logpush-shaped batches (gzip NDJSON, sent twice) to the local stack, not against a live Logpush job.

## Next steps

* [Payload shapes](/integrations/payload-shapes): other tools' events on `/v1/ingest`.
