export interface Env {
AIROPS_API_URL: string;
AIROPS_API_KEY: string;
AIROPS_LOG_COLLECTOR_QUEUE: Queue;
}
export default {
// The queue producer is invoked on each page visit and saves request metadata to the queue
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
// Save the time the request started
const startTime = Date.now();
// Make the request
const response = await fetch(request);
// Clone the response so it can be reused
const responseClone = response.clone();
ctx.waitUntil(handleRequest(startTime, request, responseClone, env));
return response;
},
// The queue consumer reads messages from the queue and sends periodic batches to AirOps
async queue(batch: MessageBatch<string>, env: Env): Promise<void> {
const body = batch.messages.map(m => m.body).join('\n');
await fetch(env.AIROPS_API_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': env.AIROPS_API_KEY,
},
body,
}).catch(error => console.error('Failed to send logs:', error))
}
} satisfies ExportedHandler<Env, string>;
async function handleRequest(startTime: number, request: Request, response: Response, env: Env) {
const logData = {
request_start_time: startTime,
request_end_time: Date.now(),
status_code: response.status,
response_bytes: response.bytes.length,
method: request.method,
url: request.url,
client_ip: request.headers.get('cf-connecting-ip'),
user_agent: request.headers.get('user-agent'),
referer: request.headers.get('referer'),
};
await env.AIROPS_LOG_COLLECTOR_QUEUE.send(JSON.stringify(logData));
}