Skip to main content

Database schema

Log Lens stores everything in SQLite by default, one database per application — the first application uses storage/log-analyzer.sqlite; each additional application uses applications/<id>/log-lens.sqlite. Databases open in WAL mode with foreign keys on, synchronous=NORMAL, an in-memory temp store, and a 5000 ms busy timeout. The schema and idempotent migrations are applied automatically on first connection.

Postgres and MySQL are supported as opt-in alternatives (schema-per-application and database-per-application, respectively, in place of SQLite's file-per-application) — the tables, columns, and indexes below are identical on every engine. See Database drivers for how to switch and what differs under the hood.

The application registry lives separately at storage/applications.json and holds only names and storage paths - never issue data.

Core tables

TableHolds
error_groupsOne row per issue, keyed by a unique fingerprint. Carries severity, log_type, channel, status, origin (ingested/manual), kind (error/issue/bug/feature_request/task), aggregated count/first_seen/last_seen, sample data, and optional module_id.
occurrencesIndividual events linked to a group and source_files row via cascading keys. Stores occurred_at, byte_start/byte_end, exact_fingerprint, event_hash, and a generated occurred_day column.
source_filesIndexed log files: unique path, size, modified_at, last_offset cursor, parser_version, log_type, channel, and optional module_id/source_stream_id.
modulesApplication-local groupings with unique name/slug and a hex color.
app_settingsKey/value workspace configuration; value is JSON.

Manual issues get a unique fingerprint, origin=manual, count=0, and intentionally have no occurrences or source_files rows, so reindexing preserves them.

Connector tables

connectors, source_streams, and connector_sync_runs track ingestion sources, per-file streams (with fetched_offset, generation, prefix_hash), and immutable sync history. Deleting a connector cascades its streams and runs but sets source_files.source_stream_id to null, preserving indexed data.

Workflow and tags

issue_status_history records status transitions; tags, error_group_tags (with manual/rule source), and tag_rules drive tagging.

Key constraints and indexes

  • error_groups.fingerprint, source_files.path, and modules.name/slug are unique.
  • occurrences(source_file_id, byte_start) is unique for idempotent re-imports.

Notable indexes cover the common query paths:

idx_groups_last_seen recent sorting
idx_groups_severity severity filters
idx_groups_status workflow filters
idx_groups_module module filters
idx_occurrences_group_time one issue's occurrences
idx_occurrences_day date filters and daily trends
idx_streams_connector_path latest remote generation