# Logs are searchable and queryable

- **Pattern:** `ab-002324` (`saas-logging.observability.logs-searchable`)
- **Severity:** medium
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-002324
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-002324)

## Why it matters

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.

## Severity rationale

Medium because logs that are not persisted to a searchable store are effectively unavailable for incident investigation, making structured logging moot.

## Remediation

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:
```bash
npm install @logtail/node @logtail/pino
```
```ts
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.

## Detection

- **ID:** `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:
  - Better Stack: Install the Better Stack Vercel integration, then logs automatically stream.
  - Axiom: Install the Axiom Vercel integration, set `AXIOM_DATASET` and `AXIOM_TOKEN`, and use `next-axiom` for in-process shipping.

  For Pino, add a transport:
  ```bash
  npm install @logtail/node @logtail/pino
  ```
  ```ts
  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) }
  ]))
  ```

## External references

- owasp A09
- nist AU-7
- iso-25010 maintainability

Taxons: observability

HTML version: https://auditbuffet.com/patterns/ab-002324
