Message normalization
Two log lines that describe the same problem rarely look identical. One mentions request #48213, the next #48219; one carries a UUID, an IP, or a timestamp that changes on every occurrence. Normalization strips out those volatile details so Log Lens can recognise both lines as the same underlying event and group them into a single issue instead of thousands of near-duplicates.
What gets replaced
Normalization scans the message and swaps variable fragments for stable placeholders. The rules run in a fixed order, from most specific to most generic, so a broad "any number" rule can't swallow a UUID or timestamp before the precise rules get their turn.
| Fragment in the message | Placeholder |
|---|---|
UUID (v1-v5, e.g. 550e8400-e29b-41d4-a716-446655440000) | {uuid} |
ISO-style date/time (e.g. 2026-07-25T14:03:11+00:00) | {time} |
IPv4 address (e.g. 192.168.0.14) | {ip} |
| Email address | {email} |
Deploy release path segment (/releases/20260725/) | /releases/{release}/ |
:<number> line reference (e.g. Handler.php:142) | :{line} |
| Any remaining bare integer | {n} |
After substitution the result is lower-cased, trimmed, and collapsed to single spaces, so casing and stray whitespace never split a group either.
Example
Before: User 48213 failed login from 192.168.0.14 at 2026-07-25T14:03:11Z
After: user {n} failed login from {ip} at {time}
Every login failure now normalizes to the same string, regardless of the user id, IP, or moment it happened.
Why the ordering matters
Because the generic integer rule ({n}) runs last, a UUID stays a UUID and a timestamp stays a timestamp. The :{line} rule also runs before {n}, so a stack-frame line number is tagged as :{line} rather than a naked {n} - keeping file references readable in grouped titles.
Where it fits
The normalized message is one of the inputs used to build an issue's fingerprint, so tuning your expectations here helps explain why certain events merge or stay separate.