🤕 clumsy.dev 🚀

Send Cloudflare Logs to Grafana Loki

cloudflare workerslokigrafanaanalytics

Logpush to Grafana Loki Endpoint

Cloudflare Logpush can send logs to any HTTP Endpoint, with this project I want to configure Grafana Loki as a logging destination

To transform the incoming data from Logpush to a format Grafana Loki understands, I'm going to use a Worker to do the following:

This solution still requires transforming the data, but it can be done from Workers directly and does not require an intermediary storage location.

Create the Worker

name = "cf-logpush-loki"
type = "webpack"

account_id = "abc1234"
workers_dev = true
route = ""
zone_id = ""
usage_model = "unbound"
npm install
wrangler secret put lokiHost

example Loki host: https://logs-prod-us-central1.grafana.net/loki/api/v1/push

wrangler publish

Note down the returned URL to create the actual Logpush job.

Create Logpush Job

Here's a cURL request to create a Logpush Job with most available fields already included:

curl --location --request POST 'https://api.cloudflare.com/client/v4/zones/<zone id>/logpush/jobs' \
--header 'X-Auth-Email: you@example.com' \
--header 'X-Auth-Key: abcSecretAPIKey' \
--header 'Content-Type: application/json' \
--data-raw '{
    "name": "http",
    "logpull_options": "fields=BotScore,BotScoreSrc,CacheCacheStatus,CacheResponseBytes,CacheResponseStatus,CacheTieredFill,ClientASN,ClientCountry,ClientDeviceType,ClientIP,ClientIPClass,ClientRequestBytes,ClientRequestHost,ClientRequestMethod,ClientRequestPath,ClientRequestProtocol,ClientRequestReferer,ClientRequestURI,ClientRequestUserAgent,ClientSSLCipher,ClientSSLProtocol,ClientSrcPort,ClientXRequestedWith,EdgeColoCode,EdgeColoID,EdgeEndTimestamp,EdgePathingOp,EdgePathingSrc,EdgePathingStatus,EdgeRateLimitAction,EdgeRateLimitID,EdgeRequestHost,EdgeResponseBytes,EdgeResponseCompressionRatio,EdgeResponseContentType,EdgeResponseStatus,EdgeServerIP,EdgeStartTimestamp,FirewallMatchesActions,FirewallMatchesRuleIDs,FirewallMatchesSources,OriginIP,OriginResponseBytes,OriginResponseHTTPExpires,OriginResponseHTTPLastModified,OriginResponseStatus,OriginResponseTime,OriginSSLProtocol,ParentRayID,RayID,SecurityLevel,WAFAction,WAFFlags,WAFMatchedVar,WAFProfile,WAFRuleID,WAFRuleMessage,WorkerCPUTime,WorkerStatus,WorkerSubrequest,WorkerSubrequestCount,ZoneID&timestamps=unixnano",
    "destination_conf": "https://your.example.workers.dev?header_Authorization=Basic%20dXNlcm5hbWU6cGFzc3dvcmQK&job=lokiJobName",
    "max_upload_bytes": 5000000,
    "max_upload_records": 1000,
    "dataset": "http_requests",
    "frequency": "high",
    "enabled": true
}'

If everything went according to plan, you should see your new Logpush Job in the Analytics => Log tab as well as in Grafana Loki.

logpush job

logpush data

logpush logfields

Debugging

The initial creation of the Logpush job will push one JSON line to Loki, you should see something along the lines:

{"content": "test", "filename": "test.txt"}

In your Loki logs.