Skip to content

Log Schema

Every HTTP log produced by CipherLogger conforms to the RequestLog type: a fixed set of required fields, plus whichever optional fields you've enabled via fields.

Required fields

Always included in every HTTP log, regardless of configuration:

Field Type Description
id string Unique identifier (UUID)
type "http" Log type discriminator
timestamp string ISO 8601 timestamp
method string HTTP method
path string Request path (including query string as received)
status number HTTP status code
duration number Duration in milliseconds

Optional fields

Enabled individually via the fields config:

Field Type Description
ip string Client IP address
userAgent string User-Agent header
referer string Referer header
protocol string Protocol (http / https)
host string Host header
query Record<string, string> Query string parameters
requestId string Value of the x-request-id header
metadata Record<string, unknown> Custom metadata you supply

Full example

With every optional field enabled:

{
  "id": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
  "type": "http",
  "timestamp": "2026-09-01T20:00:00.000Z",
  "method": "GET",
  "path": "/users?page=1",
  "status": 200,
  "duration": 12,
  "ip": "::1",
  "userAgent": "Mozilla/5.0 ...",
  "referer": "https://example.com/",
  "protocol": "https",
  "host": "api.example.com",
  "query": { "page": "1" },
  "requestId": "req_9f8e7d6c",
  "metadata": { "userId": "usr_123" }
}

Working with the schema in TypeScript

import type { RequestLog } from "cipher-logger";

function shipToSink(log: RequestLog) {
  // log is fully typed — required fields always present,
  // optional fields present only if you enabled them
}

Because optional fields are only ever added when explicitly enabled, downstream consumers (log shippers, dashboards, alert rules) can rely on a stable, minimal shape by default and opt into richer payloads only where needed.