CSV timeline viewer
Load a CSV, TSV or JSON Lines log of timestamped events, then slice it by time range, search, and per-column filters — entirely in your browser.
About this tool
Paste a CSV, TSV, or JSON Lines export of timestamped events — an application log, an audit trail, an access log, a support-ticket dump — and slice it without opening a spreadsheet. The timestamp column is found for you, the time range is inclusive on both ends, the search box looks in every column at once, and the row numbers in the output always point back at the source file.
Everything runs locally in your browser. The data you paste is never uploaded.
Worked example
Input, with the column filter level == ERROR:
timestamp,level,service,message
2024-06-01T10:00:01Z,INFO,api,request started
2024-06-01T10:00:05Z,ERROR,api,upstream timeout
2024-06-01T10:00:09Z,WARN,worker,retrying job 42
2024-06-02T11:30:00Z,ERROR,worker,job 42 failed
Output:
# timestamp level service message
- -------------------- ----- ------- ----------------
2 2024-06-01T10:00:05Z ERROR api upstream timeout
4 2024-06-02T11:30:00Z ERROR worker job 42 failed
showing rows 1-2 of 2 matched (4 read) | time column: timestamp | span: 2024-06-01T10:00:05Z .. 2024-06-02T11:30:00Z
The leading # column is each row's position in the file you pasted, so a row you find after
sorting and filtering can still be located in the original. The footer states how many rows
matched and how many were read, so a page is never mistaken for the whole result.
What it understands
Timestamps: ISO 8601 / RFC 3339 (2024-06-01T10:00:05Z, with or without an offset),
2024-06-01 10:00:05, 2024/06/01 10:00:05, 06/01/2024 10:00:05, 01-Jun-2024 10:00:05,
Apache/nginx 01/Jun/2024:10:00:00 +0000, plain dates, and bare epoch values in seconds,
milliseconds, microseconds, or nanoseconds (chosen by magnitude).
Filters: one <column> <op> <value> condition per line, all of which must hold, with op one of
== != < <= > >= contains !contains startswith endswith matches. Comparison is
numeric when both sides are numbers, otherwise text. matches takes a regular expression.
Limits and edge cases
Input is capped at 200,000 lines and 200,000 data rows; limit caps one page at 100,000 rows.
In the aligned table, cells longer than 60 characters are truncated with … and embedded newlines
are shown as spaces — switch the output to CSV, JSON, or JSON Lines to get the untouched values.
Rows whose timestamp cannot be parsed are kept when no time range is set, sorted after every dated
row, and dropped (with a count in the footer) when from or to is used. Ragged rows are padded
with empty cells rather than rejected. There is no wall clock here, so relative ranges such as
"last hour" are not available — give explicit from / to values, which also makes a shared link
reproduce the same result later.
FAQ
How does it decide which column holds the time?
First it looks for a header that names a time — timestamp, time, date, datetime, ts,
created_at, event_time, TimeCreated, @timestamp and similar, ignoring case, spaces and
punctuation — and checks that the column's values actually parse. If no header matches, it falls
back to the first column where at least half of the values parse as timestamps. Set time_column
explicitly (a header name or a 1-based index) when a file has several date columns and you want a
specific one.
My timestamps have no timezone. Which one is assumed?
Values that already carry a Z or a ±hh:mm offset are used as-is. Values without one are read as
UTC unless you set tz_offset, which says how many hours the data is ahead of UTC — -5 for US
Eastern standard time, 5.5 for India. The same offset is applied to from and to when those
have no timezone either, so a range you type in local time selects the rows you expect.
Can I search only some columns, or use a regular expression?
Yes. Leave search_fields blank to search every column, or list the ones you want by name or
1-based index (message, service). Search is a case-insensitive substring by default; tick the
regex option to treat the search text as a regular expression such as job \d+, and tick match
case to compare exactly. An invalid pattern is reported as an error that names the syntax problem
rather than silently matching nothing.
How do I page through a big result?
limit is the page size and offset is how many matching rows to skip, so limit=100 with
offset=100 is the second page. The footer always reports the total number of matches, not just
the size of the page, so you can tell how many pages there are. Sorting and filtering happen before
paging, so pages stay consistent as you move through them.
What does the activity summary show?
Choosing the summary output replaces the rows with statistics over the whole match set, ignoring
limit and offset: how many rows were read and matched, the column list, the detected timestamp
column, the first and last matching event, and a histogram that buckets matches over time (from one
second up to a year per bucket, chosen so the chart stays about sixty rows tall). It is the quickest
way to see when a burst of errors actually started.
Does it accept JSON Lines and headerless files?
Both. JSON Lines input takes one JSON object per line — a whole JSON array of objects works too —
and the columns are the union of every object's keys, in first-seen order, with missing values left
blank. For a delimited file with no header row, turn the header option off; columns are then named
column1, column2, and so on, and you can also reference them by 1-based index anywhere a column
name is accepted.
Developer & Automation Access
Run it from the terminal
Same engine as this page, headless — via the gizza CLI:
gizza tool csv-timeline-viewer "timestamp,level,service,message
2024-06-01T10:00:01Z,INFO,api,request started
2024-06-01T10:00:05Z,ERROR,api,upstream timeout
2024-06-01T10:00:09Z,WARN,worker,retrying job 42
2024-06-02T11:30:00Z,ERROR,worker,job 42 failed"New to the CLI? Get gizza →
Open it by URL
Pre-fill and auto-run this tool with query parameters — the names match the API/CLI:
https://gizza.ai/tools/csv-timeline-viewer/?data=timestamp%2Clevel%2Cservice%2Cmessage%0A2024-06-01T10%3A00%3A01Z%2CINFO%2Capi%2Crequest%20started%0A2024-06-01T10%3A00%3A05Z%2CERROR%2Capi%2Cupstream%20timeout%0A2024-06-01T10%3A00%3A09Z%2CWARN%2Cworker%2Cretrying%20job%2042%0A2024-06-02T11%3A30%3A00Z%2CERROR%2Cworker%2Cjob%2042%20failed&format=auto&delimiter=auto&header=true&time_column=timestamp%20%28blank%20auto-detects%29&from=2024-06-01&to=2024-06-01T23%3A59%3A59Z&tz_offset=0&search=timeout&search_fields=message%2C%20service%20%28blank%20searches%20all%29®ex=true&case_sensitive=true&filters=level%20%3D%3D%20ERROR%0Aservice%20contains%20work&sort_by=timestamp%20%28blank%20sorts%20by%20time%29&order=asc&columns=timestamp%2C%20level%2C%20message%20%28blank%20shows%20all%29&limit=100&offset=0&output=tableMachine-readable descriptor: tool.json — title + parameters JSON Schema for agents.
