1. Shortest, Median, and Longest REST Request Duration
Use this when a request has a start line and an end line with the same request id. The goal is to calculate elapsed time from timestamps, keep only completed requests, then sort by duration.
Fast ergonomic path
- Click
STARTon any request-start row and press Enter. A Filter is created and the view immediately narrows to matching rows. - Temporarily disable that Filter with its checkbox, click
ENDon any end row, and press Enter. Re-enable the Filter; START and END are now both include clauses. - Click the request id, for example
4711, and press S. Set Type toStringif needed; this groups matching START and END rows. - Click a timestamp on any remaining row and press D. Keep Type
Date-time; Log Explorer fills the timestamp position and length. - Click
ENDand press Enter to add the final END-only Filter, then click the generated duration and press S to sort byTime-span.
| Stage | Operator settings | Why |
|---|---|---|
| 1. Filter | Include clause with two lines: START and END .
Optional exclude: /health. |
Keeps only request lifecycle rows and removes noisy probes. |
| 2. Sort | Mode Positional, Pos 1, Len 4, Type
String, Order Ascending. |
Groups each request id. Stable sorting keeps START before END when the source log was chronological. |
| 3. Diff | Pos 7, Len 24, Type Date-time. |
Replaces the timestamp on the END row with the elapsed time from the START row. |
| 4. Filter | Include: END . |
Leaves one duration row per completed request. |
| 5. Sort | Mode Positional, Pos 7, Len 24, Type
Time-span, Order Ascending. |
Shortest request is first, longest is last. The median is around the middle row of the sorted view. |
Descending. The slowest request moves to the first row.Sample input
[4711] 2026-03-13T09:14:02.105Z START GET /api/orders [4711] 2026-03-13T09:14:02.248Z END 200 GET /api/orders [4712] 2026-03-13T09:14:02.110Z START POST /api/payments [4712] 2026-03-13T09:14:03.031Z END 201 POST /api/payments
After Diff and END filter
[4711] 00:00:00.143 END 200 GET /api/orders [4712] 00:00:00.921 END 201 POST /api/payments
2. Compare Two OCR Accuracy Runs by Language
Use this when two test runs print the same language table in the same order. Zip the two files while loading so run A and run B alternate line by line.
Fast ergonomic path
- Drop both OCR result files together and choose
New / Zipso old and new rows alternate. - Optional: add a Filter and type
%as the Include value to keep rows that contain accuracy values. Skip this when the pasted content is already only language rows. - Click the numeric part of the
bestvalue, for example95.6, and press D. Set Type toNumberand confirm the position targets the best column. - Double-click any row from the second run. Log Explorer creates a new source Filter for the clicked source, which keeps the new-minus-old delta rows.
- Click the delta column and press S to sort regressions or improvements.
| Stage | Operator settings | Why |
|---|---|---|
| Load | Drop both run files together and choose New / Zip. |
Interleaves matching language rows: old afr, new afr, old amh, new amh. |
| 1. Filter optional | Include: %, or skip this stage if only data rows are loaded. |
Removes headers while avoiding assumptions about language-code length. |
| 2. Diff | Pos 34, Len 4, Type Number. |
Compares the numeric part of the best column. The app extends the
output by one character for numeric diffs, so the percent sign is replaced by a
padded delta. |
| 3. Filter | Double-click a row from the second run, or add a Filter and enable only that source swatch. | Keeps the rows that contain new-minus-old deltas. |
| 4. Sort | Mode Positional, Pos 34, Len 5, Type
Number, Order Ascending. |
Worst regressions appear first. Switch to Descending for best
improvements. |
Sample input fragment
OCR LANGUAGE ACCURACY from sample PDFs (character-position comparison):
Lang 72dpi 300dpi 600dpi best ABBY char-pos
afr 2.8% 95.6% 95.2% 95.6%
amh 33.2% 27.0% 48.6% 48.6%
ara 32.4% 77.8% 78.0% 78.0%
asm 21.0% 63.0% 62.8% 63.0%
aze 48.1% 95.4% 96.0% 96.0%
bel 9.7% 94.2% 94.0% 94.2%
ben 40.4% 67.5% 67.5% 67.5%
bod 3.4% 17.1% 67.5% 67.5%
Column positions for this table
afr 2.8% 95.6% 95.2% 95.6%
012345678901234567890123456789012345678
^ language starts at 5
^ best numeric value starts at 34
3. Find Long Gaps Between Errors
This shows Diff as a time-between-events tool. It is handy for spotting bursts, recovery windows, and quiet periods.
Fast ergonomic path
- Click
ERRORon any row and press Enter. AddExceptionandstatus=500as extra lines in the same Include clause when those should count too. - Click a timestamp on any filtered row and press D. The Diff stage is prefilled from the selected timestamp.
- Click the new elapsed-time value and press S. Set Type to
Time-spanand Order toDescending.
| Stage | Operator settings | Result |
|---|---|---|
| 1. Filter | Include clause with ERROR, Exception, and
status=500 on separate lines. |
Keeps any line matching one of those alternatives. |
| 2. Diff | Select the timestamp on one row, press D, set Type
Date-time if needed. |
Each error row receives the elapsed time since the previous error row. |
| 3. Sort | Use the same timestamp/duration column, Type Time-span, Order
Descending. |
The largest quiet gap before an error moves to the top. |
Sample input
2026-03-13T10:02:11.007Z ERROR api CheckoutException id=823 2026-03-13T10:02:12.512Z ERROR api CheckoutException id=824 2026-03-13T10:19:40.822Z ERROR worker RetryExhausted id=411
4. Normalize Noisy Values Before Sorting
Replace is useful before Sort when ids, timestamps, or paths prevent similar lines from grouping together visually.
Fast ergonomic path
- Click the endpoint token, such as
/api/orders, and press Enter to create the first Filter. - Click
status=on a response row and press F, or use the Filter button, to add a second Filter stage for AND-style narrowing. - Select a volatile id or path segment and press R. Type the replacement,
for example
<id>. - Click the number after
status=and press S, or add Sort and switch Mode toBy Valuewith Anchorstatus=.
| Stage | Operator settings | Use case |
|---|---|---|
| 1. Filter | Include: /api/orders. Add a second Filter with Include
status= for AND behavior. |
Focuses the view on one endpoint and only response lines. |
| 2. Replace | Select a known tenant, trace id, or long generated path segment and replace it
with a short marker such as <id>. |
Reduces visual noise before comparing rows. |
| 3. Sort | Mode By Value, Anchor status=, Side
After, Type Number. |
Groups response codes while keeping related continuation lines attached. |
Tip
Replace is literal text replacement, including multi-line search and replacement. For one-off
cleanup, select the exact noisy text in the viewer and press R.
5. Split or Join Lines with Replace and Delete
Use Replace when one physical row contains several logical records, or when wrapped log output needs to be joined before sorting and diffing.
Fast ergonomic path
- To split one long row, click or select the repeated delimiter, such as
;or|, and press R. In Replacement, enter the delimiter you want, press Enter inside the edit box, then enter the next-line prefix if you need one. - To join wrapped rows, click the whitespace at the end of the first physical line or the indentation at the start of the continuation line. Press Delete to create a delete-style Replace.
- When joining lines with a space, press R instead of Delete and set Replacement to one space.
- After the shape is normalized, continue with Enter, S, or D to filter, sort, or diff the newly split or joined records.
| Goal | Operator settings | Result |
|---|---|---|
| Split packed key-values | Search is ; . Replacement is two actual lines: first
;, then an empty second line. |
Each key-value becomes easier to filter or sort on its own line. |
| Split concatenated JSON-ish events | Search is } {. Replacement is two actual lines: first
}, second {. |
One event per line, suitable for source filtering and timestamp sorting. |
| Join stack trace or wrapped message lines | Select the line break or indentation and press Delete, or replace it with a single space. | Multi-line messages become one sortable row again. |
Before split
ts=10:02:11; level=ERROR; user=42; path=/api/orders
After replacing ; with a two-line replacement
ts=10:02:11; level=ERROR; user=42; path=/api/orders
Before join
2026-03-13 ERROR Checkout failed
user=42 order=991 payment=timeout
After deleting the line break and indentation
2026-03-13 ERROR Checkout failed user=42 order=991 payment=timeout
6. Compare Two Log Files Without Losing File Identity
When multiple files are loaded together, Log Explorer keeps source colors through filters, replacements, diffs, and sorts.
Fast ergonomic path
- Drop both files together. Choose
New / Zipfor paired old/new rows orNew / Appendfor one combined timeline. - Click a shared event token and press Enter to create the first Filter.
- Click the correlation id, language code, timestamp, or other grouping key and press S to sort both sources through the same rule.
- To inspect one file, double-click a row from that file. Log Explorer adds a source Filter for the clicked source.
| Goal | Load mode | Pipeline pattern |
|---|---|---|
| Compare old/new output line by line | New / Zip |
Filter data rows, Diff the fixed column, then Filter to the second source. |
| Search all logs as one timeline | New / Append |
Filter event text, Sort by timestamp, then use source colors to see which file contributed each row. |
| Inspect one file after a shared pipeline | Any multi-file mode | Double-click a row from the desired file, or add a Filter and enable only that source swatch. |
Profile idea
Save named profiles for recurring comparisons: OCR accuracy delta,
REST duration sort, Error burst gaps. Profiles persist locally and
can be exported from the app menu.
Operator Cheat Sheet
Use these rules of thumb when designing a new pipeline.
Keep or remove lines by literal text. Multiline clause text means alternatives. Stack filters for AND logic.
Perform literal whole-stage replacement. Empty replacement acts like deletion. Multi-line search and replacement are supported.
Extract a fixed position or a token before/after an anchor, parse it as string, number, date-time, or time-span, then move rows as blocks.
Compare each parsable row to the previous parsable row. Numeric and time diffs become sortable deltas; string diff keeps changed characters.