Version 2 is coming up

Cloudflare (Worker)

Overview

This integration runs a Cloudflare Worker as middleware. On each request, the Worker extracts metadata and sends it to Agent Monitoring — without interfering with normal request flow.

For additional details about Logpush, refer to Cloudflare’s official documentation. Cloudflare Worker is free up to 100K requests per day, for additional details, refer to Cloudflare’s official documentation.

1

Open Terminal and install the following using npm

npm create [email protected] -- log-shipping

Follow the instructions below

Running the CLI creates the log-shipping project and handles dependency installation automatically.

VERY IMPORTANT - DO NOT DEPLOY YET

2

Configure your worker

Edit your wrangler.jsonc file to configure LIMY_URL environment variable to our endpoint and replace the domain.com/* placeholder should match your organization's domain. If your site is https://www.domain.com, use domain.com/* as the pattern and domain.com for zone_name

{
  "$schema": "node_modules/wrangler/config-schema.json",
  "name": "log-collector",
  "main": "src/index.ts",
  "compatibility_date": "2025-12-09",
  "observability": {
    "enabled": true
  },
  "route": {
    "pattern": "domain.com/*",
    "zone_name": "domain.com"
  },
  "vars": { "LIMY_URL": "https://stream.getlimy.ai" }
}

Then replace src/index.ts code within the code below :

/**
 * Cloudflare Worker for Log Collection
 *
 * This worker captures HTTP request/response data and forwards it to Limy's log collection API.
 * It runs as a middleware, meaning it doesn't interfere with the actual request handling.
 */

export interface Env {
     LIMY_KEY: string;
    LIMY_URL: string;
}

export default {
    async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {

    // Get the original response
    const response = await fetch(request);

    // Clone the response so we can read it multiple times
        const responseClone = response.clone();
    
        ctx.waitUntil(handleRequest(request, responseClone, env));
        return response;
    }
} satisfies ExportedHandler<Env>;

async function handleRequest(request: Request, response: Response, env: Env) {
	const requestUrl = new URL(request.url);
	const cf = request.cf;
  
	const headerSize = Array.from(response.headers.entries())
	  .reduce((total, [key, value]) => total + key.length + value.length + 4, 0);
	
	const responseBody = await response.blob();
	const bodySize = responseBody.size;

    // Total bytes sent includes headers and body
    const totalBytesSent = headerSize + bodySize;

    const logData = {
		// Timing
		timestamp: Date.now(),
		
		// Request basics
		host: requestUrl.hostname,
		method: request.method,
		pathname: requestUrl.pathname,
		query_params: Object.fromEntries(requestUrl.searchParams),
		
		// Client info
		ip: request.headers.get('cf-connecting-ip'),
		userAgent: request.headers.get('user-agent'),
		referer: request.headers.get('referer'),
		acceptLanguage: request.headers.get('accept-language'),
		
		// Response info
		bytes: headerSize + bodySize,
		status: response.status,
		contentType: response.headers.get('content-type'),
		
		// Cloudflare request ID
		rayId: request.headers.get('cf-ray'),
		
		// Geographic (from cf object)
		country: cf?.country,
		city: cf?.city,
		region: cf?.region,
		regionCode: cf?.regionCode,
		continent: cf?.continent,
		postalCode: cf?.postalCode,
		latitude: cf?.latitude,
		longitude: cf?.longitude,
		timezone: cf?.timezone,
		
		// Network
		asn: cf?.asn,
		asOrganization: cf?.asOrganization,
		colo: cf?.colo,  // Cloudflare datacenter
		
		// Connection
		httpProtocol: cf?.httpProtocol,
		tlsVersion: cf?.tlsVersion,
		tlsCipher: cf?.tlsCipher,
    }

    await fetch(env.LIMY_URL, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-API-Key': env.LIMY_KEY,
			'User-Agent': 'Cloudflare-Worker-Logs'
        },
        body: JSON.stringify([logData])
    }).catch(error => console.error('Failed to send logs:', error))
}
3

Login to Cloudflare

Deploy the worker using Wrangler CLI:

//Login to Cloudflare
npx wrangler login

Configure Limy API key

Cloudflare Workers Secrets let you store sensitive values like API keys securely, outside of your code.

npx wrangler secret put LIMY_KEY
4

Deploy your worker

npx wrangler deploy

Need More Help?

Last updated