Begin with a bounded, redacted excerpt
Logs are records produced by a particular application or infrastructure component. Before counting messages, preserve where the excerpt came from: service name, environment, time zone, collection method, and whether lines were omitted. Keep a request or trace identifier only if policy permits it. Redact tokens, personal data, and customer content while preserving the fields needed to understand the event.
A copied excerpt is evidence about those lines, not a complete view of the system. It may start after the initiating event, omit a related service, or combine messages from hosts with different clocks. Write down the capture interval and query criteria. When the exact order matters, check clock synchronization and the collector's timestamp handling rather than assuming that adjacent lines happened in a precise causal sequence.
Sort by signals without treating labels as truth
Structured logging formats can define explicit severity values and fields. For example, RFC 5424's syslog protocol assigns severity levels to messages. The OpenTelemetry log data model also describes structured event fields. Many application logs are plain text, though, and may use different words or no level at all. A keyword search for ERROR or WARN is a useful sorting step, not a universal severity parser.
Benchlight's Log Triage recognizes common severity words and reports unclassified lines. It gives a quick view of counts, but a word can appear in prose, an error code, a quoted request, or a message that is not actually marked with a structured level. Conversely, a failure may have no obvious keyword. Read the original line and, where available, prefer the event's explicit structured field.
Start with the first anomaly in the relevant time window, not automatically the highest count. A large number of downstream retries may be consequences of one earlier dependency failure. Compare the first warning or error with the first user-visible symptom and check whether the timeline is consistent. Treat that sequence as a hypothesis until traces, metrics, or controlled reproduction support it.
Use repeated lines as a clue, then inspect what was normalized
Repeated events can reveal a retry loop or recurring failure, but a duplicate count does not explain why the event repeated. Similar messages can refer to different requests or different resources. Preserve the raw lines next to any grouped report.
Benchlight's repetition view removes a leading timestamp and replaces every run of digits with a marker before grouping. This intentionally makes timestamps and numeric identifiers less likely to split otherwise similar messages, but it can merge materially different events. A status code, port, account number, or retry count may be important. Use the normalized groups to find candidates, then compare the original text, identifiers, and surrounding lines before making a claim.
For a useful comparison, choose one event from each group and put its timestamp, service, level, and message next to the others. Check whether a correlation ID, trace ID, host, or deployment version separates them. If a field is not stable, identify which component produced it and whether the collector rewrote it. Do not edit the source data to make the grouping look cleaner.
Follow the event across system boundaries
An application request may pass through a browser, gateway, application server, queue, and worker. Each component can emit a different event with a different clock and naming convention. A matching identifier across those records can help reconstruct a path, but the identifier's scope and uniqueness depend on the system that generated it. A request ID in one service may not be a distributed trace ID.
Compare logs with a trace or metric when those are available. A trace can show relationships among spans; a metric can show whether a behavior changed across a wider interval. Neither automatically proves root cause, but each adds a different observation. Record which system produced each piece and keep a link or query description that another person with appropriate access can reproduce.
When a dependency is implicated, verify the boundary. Check the request sent, the response status and timing, retry policy, and whether the caller received an error or merely timed out. Use a safe test environment for reproductions. Avoid retrying a production operation that could create duplicate side effects unless the service's idempotency rules are known.
Write a hypothesis that can be disproved
A practical incident note separates observation from inference. “The excerpt contains 14 timeout lines between 10:30 and 10:32” is an observation if the capture supports it. “The database caused the outage” is a causal explanation that needs corroboration. Add the next check that could disprove the hypothesis, such as a comparison with database latency or a request trace from the same interval.
Keep uncertainty visible. If the logs contain no request IDs, say that correlation could not be established from this sample. If a collector dropped lines, record the gap. If several services use unsynchronized timestamps, do not claim an exact cross-service order. The goal is to reduce uncertainty through the next targeted observation, not to fill missing context with a confident narrative.
Expose what a repeated pattern has merged
Use two invented lines to inspect the normalizer's effect:
2026-01-01T10:00:00Z ERROR upstream returned 500 for request 41
2026-01-01T10:00:01Z ERROR upstream returned 503 for request 42
Log Triage counts two ERROR lines and one repeated pattern. After removing the leading timestamps and replacing digit runs, both lines become ERROR upstream returned # for request #. That grouped result is correct for this normalization rule, but it has merged different status codes. A count of two therefore does not establish two identical failures. Read the retained original records before naming the incident or choosing a remediation.
Create a second grouping outside the heuristic if status matters: keep 500 and 503 distinct, then group only the request identifiers. A real logging pipeline could attach a structured status attribute so this distinction survives aggregation. OpenTelemetry's model separates severity, body, timestamps, and optional trace context; a keyword search over the whole line is not equivalent to reading those structured fields.
For example, add INFO message="no error found" as a third line. The current tool classifies it as ERROR because the word error appears and the ERROR rule is checked before INFO. That is a false severity inference caused by searching message text. Use the record's authoritative severity field when the source format supplies one. Do not rewrite operational records merely to satisfy the heuristic.
The next investigation depends on the unmerged evidence. If different status codes correlate with different routes, separate those routes. If a trace identifier is available, follow that request through the systems that recorded it. If only these two lines exist, document the narrower observation: two keyword-classified errors with different numeric statuses were grouped into one pattern. That statement gives the next investigator a testable lead without claiming a cause that the excerpt cannot establish.
