OWASP A09 and NIST AU-7 (Audit Record Reduction and Report Generation) both require that logs be accessible for analysis — which means persisted, indexed, and queryable, not just emitted to stdout. On serverless platforms like Vercel, function logs visible in the dashboard are ephemeral and retained for only a short window (typically 1–24 hours) without a log drain configured. A structured JSON logger producing perfect output is useless if the output disappears before you need it. When an incident happens, you need to query log history across a time range, filter by user ID, or trace a specific error across multiple function invocations — none of which is possible with transient platform logs.
Medium because logs that are not persisted to a searchable store are effectively unavailable for incident investigation, making structured logging moot.
Ship logs to a persistent, queryable log platform. For Vercel-deployed apps, the fastest path is a native Vercel integration.
Better Stack: Install the Better Stack Vercel integration — logs stream automatically from all Vercel functions with no code changes.
Axiom: Install the Axiom Vercel integration, set AXIOM_DATASET and AXIOM_TOKEN env vars, and optionally add next-axiom for in-process shipping.
For Pino-based loggers, add a transport directly:
npm install @logtail/node @logtail/pino
import { Logtail } from '@logtail/node'
import { LogtailTransport } from '@logtail/pino'
const logtail = new Logtail(process.env.LOGTAIL_SOURCE_TOKEN!)
const logger = pino({ level: 'info' }, pino.multistream([
{ stream: process.stdout },
{ stream: new LogtailTransport(logtail) }
]))
Add the log service token to .env.example so it is documented as a required configuration.
ID: saas-logging.observability.logs-searchable
Severity: medium
What to look for: Enumerate all relevant files and Check whether application logs flow to a searchable log management service. Look for: Better Stack Logs (logtail), Axiom, Datadog Logs, Grafana Loki, AWS CloudWatch Logs Insights, Papertrail, Logflare, or Supabase logs dashboard. Check package.json for log shipping libraries (@logtail/node, axiom-node, pino-datadog-transport, winston-cloudwatch, etc.), .env.example for log service credentials, and documentation for log platform references. Platform-specific log retention (Vercel function logs visible in dashboard for 24h without a log drain) does not count — those are ephemeral and not searchable over time.
Pass criteria: No more than 0 violations are acceptable. Application logs are shipped to a persistent, searchable log platform with a query interface. Evidence is in dependencies, environment variable references, or documentation.
Fail criteria: No log shipping configured — logs only appear in the hosting platform's transient function log view (Vercel dashboard, Netlify function logs) and are not persisted to a searchable store.
Skip (N/A) when: No server-side logging of any kind (static site).
Detail on fail: "No log shipping configured — logs are emitted to stdout and visible only in Vercel's 1-hour transient function log view, with no persistent queryable store"
Remediation: Searching through function log tails when an incident is happening is painful and slow. A proper log platform lets you search across time ranges, filter by user ID or error type, and set up alerts on log patterns.
For a Vercel-deployed Next.js app, add a Vercel Log Drain to Better Stack or Axiom in minutes:
AXIOM_DATASET and AXIOM_TOKEN, and use next-axiom for in-process shipping.For Pino, add a transport:
npm install @logtail/node @logtail/pino
import { Logtail } from '@logtail/node'
import { LogtailTransport } from '@logtail/pino'
const logtail = new Logtail(process.env.LOGTAIL_SOURCE_TOKEN!)
const logger = pino({ level: 'info' }, pino.multistream([
{ stream: process.stdout },
{ stream: new LogtailTransport(logtail) }
]))