Skip to main content

Issues and how events are grouped

An issue (an error group) is a collection of log events that share the same root cause. Instead of showing you thousands of raw lines, Log Lens folds repeated events into one issue with a count, a first-seen and last-seen time, and a sample message. This keeps the dashboard readable even when a single fault fires many times.

What decides the group

Every event is reduced to a group fingerprint - a SHA-256 hash of six things:

PartNotes
ModuleOr unassigned if none
Log typee.g. laravel, horizon, nginx
Severitye.g. ERROR, WARNING
Exception classDetected from the body, if any
TitleNormalized (short first line)
Source frameNormalized first non-library stack frame

Two events with the same fingerprint become the same issue. The title and source frame are normalized first, so volatile bits - IDs, timestamps, IP addresses, emails, line numbers, and bare digits - collapse to placeholders. That is why User 4182 not found and User 9007 not found land in one issue.

The source frame is the first frame in the trace that is not library code - the first one whose path contains neither /vendor/ nor /node_modules/. That is the frame that identifies your code as the culprit, and it is the same frame that survives the "skip vendor" view of a stack trace.

Upgrading: the source frame used to be the first frame containing /app/, which misfires on the most common Laravel container layout of all - an application rooted at /app, where every framework frame reads /app/vendor/laravel/… and matched first. The fingerprint therefore changes for any issue whose culprit was previously read as a framework internal: after upgrading, new occurrences of those errors open a new issue rather than adding to the old one. Nothing is lost - the old issues keep their history - and a reindex regroups the existing occurrences under the corrected fingerprints.

See Message normalization for the exact rules.

Group vs exact fingerprint

Each event also gets an exact fingerprint: the group fingerprint plus its normalized stack trace. Occurrences are inserted with INSERT OR IGNORE on this exact value, so identical events - same fault and same normalized stack - are deduplicated rather than counted twice, while genuinely distinct variants still record separately.

group fingerprint = module | log_type | severity | exception | title | source_frame
exact fingerprint = group fingerprint | stack

How counts and status behave

  • count, first_seen, and last_seen update automatically as new occurrences arrive.
  • Issues sort by occurrences (default), newest, or oldest.
  • If a new occurrence lands on an issue you had marked fixed, its status flips to reoccurred and the change is logged. See Reoccurrence detection.

Edge cases

  • Changing an event's module reassigns it to a different fingerprint, so module changes can split or move issues. Reindex after such changes.
  • Non-error levels only become issues if you index them.
  • Manually created issues live alongside detected ones but are never merged or pruned by ingestion.