Core Concepts
Applications (workspaces)
An application is a fully isolated workspace: its own SQLite database,
logs/ incoming directory, processed/ archive, sources/ connector mirrors,
modules, tags, connectors, and settings. The interface always shows exactly
one application - there is no aggregated "all applications" view, and numeric
IDs are only meaningful within one application's database.
The first application (default) uses the root layout of the install itself.
Additional workspaces are created from the sidebar selector and live under
applications/<id>/.
Modules
A module is a label for a subsystem (Billing, Auth, ...). The first-level
subdirectory under an application's logs/ is treated as a module slug:
logs/billing/laravel.log to the Billing module, archived to
processed/billing/. Modules are created on demand and can also be managed via
the API. Root-level log files are unassigned.
Issues (error groups) and occurrences
- An occurrence is a single parsed log event: a byte range in a source file, a timestamp, severity, and a capped context preview.
- An issue (internally an error group) is a cluster of occurrences that
share a fingerprint. The issue carries the aggregate
count, first/last seen, a representative message/stack/context, workflow status, and tags.
Fingerprinting
The group fingerprint is a SHA-256 of the module, log type, severity, exception
class, and a normalized title and source frame. Normalization replaces
volatile tokens - UUIDs, timestamps, IPs, emails, numbers, release paths - with
placeholders so that "Order 123 failed" and "Order 456 failed" collapse into one
issue. A second exact fingerprint (adds the normalized stack) plus a
(source_file_id, byte_start) uniqueness constraint prevent duplicate
occurrences.
Severities
EMERGENCY, ALERT, CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG. Aliases
WARN to WARNING, ERR/FATAL to ERROR, TRACE to DEBUG are normalized before
the allowlist is applied. Each workspace ingests only the severities on its
allowlist (default ERROR + WARNING).
Workflow statuses
Each issue moves through: open to in_progress to fixed (or wont_fix), with
reoccurred applied automatically when a new occurrence lands on an issue that
was already fixed. Every status change writes an immutable history entry
(with an optional note) - the audit trail shown as a timeline in the dashboard.
Manual issues
Beyond ingested errors, you can create first-class manual issues - bugs,
feature requests, tasks, or general issues - with a title, description, severity,
module, and tags. They start with zero occurrences, participate fully in
workflow and tagging, and are returned with origin=manual, log_type=manual.
Aggregate refreshes never delete occurrence-free manual work.
Tags and rules
Tags are colored, icon-bearing labels. A tag may carry a rule - a match word that auto-assigns the tag to any issue whose title, message, or exception class contains it. Manual assignments are preserved when a rule changes; rule-based assignments are recalculated.
Connectors and sources
A connector pulls logs from a local directory or a remote SSH host
into the application. Fetched bytes are appended to a canonical mirror under
sources/, then run through the same parser/severity/fingerprint/workflow/tag
pipeline as dropped files. See Connectors.
Storage model
Full event bodies stay in the archived files; SQLite stores byte ranges
(byte_start/byte_end) plus capped representative samples. Raw evidence is
fetched on demand from the archive. This keeps the database small and lets large
logs stream without being loaded into memory. Full schema:
reference/database-schema.md.
Plugins
Everything beyond the core dashboard - alerting, release tracking, Linear sync, HTTP ingest, access-log analytics - is an optional plugin, toggled per application in Settings → Plugins. Disabled means disabled: routes 404, UI hidden, nothing running in the background. See Plugins overview for the toggle model and a page per plugin.