Skip to main content

Ingestion & Formats

See also the endpoint-level reference: reference/endpoint-ingestion-maintenance.md.

How ingestion works

  1. Files are discovered in the application's logs/ directory (recursively). The first-level subdirectory is a module slug.
  2. Each file is streamed and parsed into events; events on the workspace's severity allowlist become occurrences, grouped into issues by fingerprint.
  3. Successfully processed files are moved to processed/ (the archive). The database keeps byte ranges, not full bodies.
  4. After each incoming import, retention optionally prunes the archive.

Trigger it from the dashboard (Process logs), the API (POST /?api=import-incoming), or the CLI (php bin/import.php).

Supported formats

log_typeDetectionNotes
laravelMultiline Laravel/Monolog headers ([time] env.LEVEL: message)Multiline bodies and stack traces captured.
horizonhorizon*.log with Laravel framingSame pipeline as Laravel.
horizonhorizon*.log in the framing horizon/queue:work prints to the consoleNo log level in the format, so the verb is the level: Failed/FAIL to ERROR, everything else to INFO.
nginx_accessCommon/combined access lines in access*/nginx* filesStatus mapped: <400 to INFO, 4xx to WARNING, 5xx to ERROR.
consoleBracketed or ISO timestamps with optional severityFallback for any other .log file.

Which filenames count as logs is controlled by ingestion.log_file_pattern (default matches .log and rotated .log.N). See Configuration.

Known parsing limitation: parsing is line-based - an event runs from one header line to the next. A multiline event whose body contains a line that itself looks like a header (e.g. a quoted log line embedded in a message) is split at that line.

Severity allowlist

New workspaces ingest ERROR and WARNING. Change the selection under Settings to Ingestion or via PUT /?api=ingestion-settings. The selection is part of each source's import signature, so changing it and reindexing reparses sources under the new allowlist. Saving does not delete existing issues.

Incremental behavior

  • source_files.last_offset records the scanned byte position; only appended bytes are parsed on the next run.
  • Unchanged size/mtime/parser-version files are skipped.
  • Truncation or a parser/fingerprint version change triggers a full reparse.
  • (source_file_id, byte_start) prevents duplicate occurrences.

Reindex

POST /?api=reindex

Reparses paths already recorded in source_files (does not rescan logs/ or move files). Use it after changing the severity allowlist or after a Log Lens upgrade that bumps the parser version.