_private/qwestly-docs/Engineering/Monitoring/vercel-log-drain.md

Vercel Log Drain Engineering Documentation

Overview

This document describes the engineering details, setup, and operational considerations for the Vercel log drain integration with the Qwestly Monitoring API. The log drain enables ingestion of Vercel platform logs into our AWS S3 bucket for monitoring, compliance, and analysis.


Architecture

  • Vercel sends logs via HTTP POST to our API endpoint (/api/vercel-log-drain).
  • The API authenticates requests using the X-Vercel-Signature header (shared secret).
  • The API supports both NDJSON and JSON payloads.
  • The API extracts the projectId from the first log object and stores the raw log data in S3 under vercel-logs/{projectId}/{YYYY-MM-DD}/{HHMMSS}.ndjson.
  • Vercel verifies endpoint ownership by sending a GET request and expecting a specific value in the response header.

Endpoint Details

URL

POST /api/vercel-log-drain
GET  /api/vercel-log-drain

Authentication

  • Header: X-Vercel-Signature: <secret>
  • The secret is set in the API as the VERCEL_LOG_DRAIN_SECRET environment variable and in the Vercel dashboard as the log drain secret.

Verification

  • Header: x-vercel-verify: <verify-value>
  • The value is set in the API as the VERCEL_LOG_DRAIN_VERIFY environment variable and in the Vercel dashboard during log drain setup.
  • Vercel sends a GET request to verify the endpoint; the API responds with a 200 and the x-vercel-verify header.

Payload

  • Content-Type: application/x-ndjson (preferred) or application/json
  • Body: NDJSON (newline-delimited JSON objects), a JSON array, or a single JSON object.
  • The API will parse and accept all three formats.

Example NDJSON

{"projectId":"prj_abc123xyz","message":"log1"}
{"projectId":"prj_abc123xyz","message":"log2"}

Example JSON Array

[
  {"projectId":"prj_abc123xyz","message":"log1"},
  {"projectId":"prj_abc123xyz","message":"log2"}
]

Example JSON Object

{"projectId":"prj_abc123xyz","message":"log1"}

S3 Storage Structure

  • Logs are stored in the S3 bucket defined by AWS_S3_LOGS_BUCKET (default: qwestly-logs).
  • Path: vercel-logs/{projectId}/{YYYY-MM-DD}/{HHMMSS}.ndjson
  • The raw request body is stored as the S3 object content.

Setup Instructions

1. API Environment Variables

  • VERCEL_LOG_DRAIN_SECRET: Shared secret for authenticating log drain POSTs.
  • VERCEL_LOG_DRAIN_VERIFY: Value to return in the x-vercel-verify header for GET requests (provided by Vercel during setup).
  • AWS_S3_LOGS_BUCKET, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION: S3 configuration.

2. Vercel Log Drain Setup

  • Go to your Vercel project dashboard.
  • Navigate to Settings > Log Drains.
  • Add a new log drain:
    • Type: HTTP
    • Endpoint: https://<your-api-domain>/api/vercel-log-drain
    • Secret: (same as VERCEL_LOG_DRAIN_SECRET)
    • Verification: (same as VERCEL_LOG_DRAIN_VERIFY)
  • Vercel will verify the endpoint by sending a GET request and checking the x-vercel-verify header.
  • Once verified, Vercel will POST logs to the endpoint.

Error Handling & Edge Cases

  • If the signature is missing or incorrect, the API returns 401 Unauthorized.
  • If the body is empty or cannot be parsed as NDJSON/JSON, the API returns 200 with the verification header (to avoid Vercel retries/disablement).
  • If projectId is missing, the API returns 200 with the verification header.
  • If S3 upload fails, the API returns 200 with the verification header.
  • All POST responses include the x-vercel-verify header for Vercel compatibility.

Operational Notes

  • The endpoint is designed to be idempotent and always return 200 for POSTs (except for signature errors), to prevent Vercel from disabling the drain.
  • Logs are stored as raw NDJSON/JSON for maximum fidelity and future flexibility.
  • The endpoint is compatible with both Vercelโ€™s log drain requirements and internal monitoring needs.

Internal: Fetching Vercel Logs from S3

Endpoint

GET /api/internal/vercel-logs

Authentication

  • HTTP Basic Auth (username/password from environment variables INTERNAL_DASHBOARD_USER and INTERNAL_DASHBOARD_PASS)

Query Parameters

  • project_id (required): The Vercel projectId (S3 folder)
  • date (optional, default: today, format: YYYY-MM-DD)
  • time (optional, format: HHMMSS)

Usage

  • If time is omitted, the endpoint lists all log files for the given project and date.
  • If time is provided, the endpoint returns the contents of the specific log file.

Example: List all log files for a project and date

GET /api/internal/vercel-logs?project_id=prj_abc123xyz&date=2024-07-08

Example: Fetch a specific log file

GET /api/internal/vercel-logs?project_id=prj_abc123xyz&date=2024-07-08&time=153012

Response

  • If listing files:
    {
      "project_id": "prj_abc123xyz",
      "date": "2024-07-08",
      "files": ["153012.ndjson", "153045.ndjson"]
    }
    
  • If fetching a file:
    {
      "project_id": "prj_abc123xyz",
      "date": "2024-07-08",
      "time": "153012",
      "log": "{\"projectId\":\"prj_abc123xyz\",...}"
    }
    

References