~/log-explorer ☀ LIGHT kql regex json diff ☕ Support me apps ← about me
🔒 100% client-side · Your logs never leave this browser · No upload · No server
██╗ ██████╗ ██████╗ ███████╗██╗ ██╗██████╗ ██╗ ██████╗ ██████╗ ███████╗██████╗ ██║ ██╔═══██╗██╔════╝ ██╔════╝╚██╗██╔╝██╔══██╗██║ ██╔═══██╗██╔══██╗██╔════╝██╔══██╗ ██║ ██║ ██║██║ ███╗ █████╗ ╚███╔╝ ██████╔╝██║ ██║ ██║██████╔╝█████╗ ██████╔╝ ██║ ██║ ██║██║ ██║ ██╔══╝ ██╔██╗ ██╔═══╝ ██║ ██║ ██║██╔══██╗██╔══╝ ██╔══██╗ ███████╗╚██████╔╝╚██████╔╝ ███████╗██╔╝ ██╗██║ ███████╗╚██████╔╝██║ ██║███████╗██║ ██║ ╚══════╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
Log Explorer
Drag & drop a log file, paste lines, or open one of ten demo logs · Apache · Nginx · syslog · JSON · CSV · Entra ID · CloudTrail · Windows events · Kubernetes
📋
Drop log file here or click to browse
.log · .txt · .json · .csv — plain-text logs, JSON lines or arrays, CloudTrail, Entra ID and Windows event exports · Processed entirely in your browser
Parsing…
▸ Insights — found automatically
▸ Event Timeline
Errors
Warnings
Info / OK
All Critical Error Warn Info Debug OK
Log Lines
# Timestamp Level Source Message
Patterns · click any row to filter

Guide — from raw log file to the lines that matter

Load a file, read the timeline, then narrow it down. Nothing is uploaded.
1Load a log

Drop a file, pick one, or use ✎ paste log text. No log to hand? Ten built-in demos — web, cloud and security logs — are generated in the page.

2Let it detect the format

Apache access and error logs, Nginx, syslog, JSON lines and arrays, CSV exports, Entra ID sign-ins, CloudTrail and Windows events are recognised automatically.

3Read the insights and timeline

Insights list what stands out — spikes, brute force, scanners, gaps. On the timeline, drag across a stretch to zoom in.

4Filter down

Combine level chips, text or /regex/ search, IP, user and status filters — or press show → on an insight to filter in one click.

5Check patterns and export

Click a row in Patterns — top IPs, users, ports, error messages — to filter on it. Export the filtered lines as .log or the parsed fields as .csv.

What each panel answers

WHENTimeline
spike
a burst of errors at one moment
gap
nothing logged — stopped or switched off
drag
zoom the table to that stretch
WHATFilters and search
level chips
one severity at a time
search
text, /regex/ or !exclude; press /
IP
prefix match, e.g. 45.83.
WHOInsights and patterns
insights
spray, brute force, lockouts, scans
top IPs / users
who caused the noise
top errors
the message to fix first
SHAREExport
.log
filtered lines, original text
.csv
timestamp, level, user, IP, status, message

How to read and analyse log files in your browser

Log Explorer parses web, system, cloud and security logs locally — Apache, Nginx, syslog, JSON, CSV, Entra ID sign-ins, AWS CloudTrail and Windows events — extracts timestamps, levels, users, IP addresses and status codes, and turns them into automatic insights, a zoomable timeline, filters and a patterns summary. The sections below cover the supported formats, how the timeline and stats are calculated, how to triage an incident, what sensitive data hides in logs, and where a browser tool stops and a log platform starts.

Getting started

What does Log Explorer do?

Drop in a log file and it detects the format, parses every line, extracts timestamps, levels, users, IPs and status codes, and gives you insights (what stands out and why), a timeline chart you can zoom by dragging, filters, a searchable table and a patterns panel — all in the browser, with nothing uploaded.

I don't have a log file to hand. Can I try it?

Yes — the demo buttons under the drop zone generate ten realistic logs in your browser, each with something to find:

  • Web & apps — an Nginx access log with a 28-minute 5xx incident and a vulnerability scanner; the same outage in an Apache error log (proxy errors, authz denials, a path traversal probe); a structured JSON application log with durations and stack traces; a Kubernetes log with probe failures and a container restart.
  • Security — Entra ID sign-ins with a password spray, smart lockouts, MFA fatigue and a risky sign-in from abroad; AWS CloudTrail with a leaked CI access key, data pulled from S3 and StopLogging; a Windows Security CSV export with password guessing, lockouts, a new administrator and a cleared audit log; a UFW firewall log with a port scan and a rate-limited SSH brute force; a Linux syslog with failed SSH logins and an OOM kill.
  • Other — a deliberately messy mixed log with five different timestamp styles.

Are the demo logs downloaded from somewhere?

No. They are generated by JavaScript in your tab from a fixed seed, so the same button always produces the same log and nothing leaves the page. The timestamps are anchored to the last six hours, so the timeline always looks like something that just happened. Addresses come from the documentation ranges (192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24), and names use Microsoft's contoso.com example tenant and AWS's example account and keys.

Why did a demo open on my first visit?

So you can see what the tool does before you have a log to hand. The first time you open the page it generates the Nginx demo and shows a short banner with things to try; after that the page starts empty. ✕ start empty clears it at once, and a link with ?demo=entra (or cloudtrail, winsec, ufw, apacheerr…) opens a specific demo directly.

Can I paste log lines instead of uploading a file?

Yes — ✎ paste log text opens a box you can paste into. Handy for a few lines out of a terminal, a chat message or a ticket, where saving a file first would be silly.

Which demo should I try first?

The Nginx access log shows the basics: the timeline has a visible error spike, the insights name the spike window and the scanner IP hammering /wp-admin and /.env, and each show → filters to exactly those lines. For security work, open Entra ID sign-ins — the insights walk through the whole attack, from the spray to the risky sign-in. The messy mixed log is the one to try if you want to see what happens when a file mixes formats — detection picks whichever style is most common and the rest falls back to timestamp-and-keyword extraction.

Does any of this reach a server?

No. The file is read with the browser's FileReader API, parsed in JavaScript, and held in memory. There is no back end, no upload endpoint and no storage — which is the point, because production logs routinely contain customer IPs, tokens in URLs and internal host names.

Does it work offline?

Yes, once the page has loaded. Parsing, the chart and the demo generators are all part of the page, so you can disconnect and keep working — useful on a jump box or an air-gapped laptop.

Formats and parsing

Which log formats are supported?

Auto-detected: Apache common and combined access logs and the Apache 2.4 error log, Nginx access logs, syslog / systemd (including UFW / iptables firewall lines), IIS W3C, JSON lines and JSON arrays with any field names, CSV exports with a time column, and a generic fallback that pulls a timestamp and a level out of almost anything. On top of that, three security sources are recognised by their fields and get their own parsing — see below.

Which security logs does it understand?

Microsoft Entra ID sign-ins (the JSON download from the portal or Microsoft Graph): error codes such as 50126, 50053, 500121 and 53003 are translated, interrupts like “MFA required” are kept apart from real failures, and location and risk level end up in the message. AWS CloudTrail ({"Records":[…]} files or JSON lines): identity, access key, source IP, API call and error code are extracted, StopLogging and DeleteTrail are marked critical and IAM changes as warnings. Windows event logs exported with Get-WinEvent … | Export-Csv: the multi-line Message field is parsed for account name, source address, logon type and group, and around 25 security event IDs (4624, 4625, 4740, 4720, 4732, 1102…) get a name and a sensible level.

How does format detection work?

A file that is one JSON document (an array, or an object holding Records/value) or a CSV with a header row is read as records first. Otherwise the first 200 non-empty lines are tested against each format's signature, and whichever passes on more than 30% of them wins. That means a file can start with a banner or a few comment lines without confusing it, and a log that mixes formats falls back to the generic parser rather than mis-parsing everything.

What if my format is not recognised?

The generic parser still works. It looks for a timestamp anywhere in the line — ISO 8601, RFC 3339, YYYY-MM-DD HH:MM:SS, syslog-style Mmm DD HH:MM:SS or an Apache bracketed date — and a level keyword anywhere in the text. You lose the structured fields such as IP and status, and you keep the timeline, the level filters, search and export.

Which timestamp formats are understood?

ISO 8601 and RFC 3339 with or without milliseconds and timezone, 2026-08-18 14:32:07, Apache's 18/Aug/2026:14:32:07 +0000, the Apache error log's Tue Aug 18 14:32:07.123456 2026, syslog's Aug 18 14:32:07, the PowerShell/Windows 8/18/2026 2:32:07 PM, and Unix epoch seconds or milliseconds in JSON. Syslog has no year, so the current year is assumed — unless that would put the line in the future, in which case it is last year.

How are log levels detected?

From an explicit level field where the format has one (JSON level, syslog priority, a bracketed [ERROR]), otherwise from keywords in the line — CRIT, FATAL, ERROR, WARN, INFO, DEBUG, TRACE. For access logs the HTTP status code sets the level instead: 5xx is an error, 4xx a warning, 2xx and 3xx are OK.

Does it handle JSON logs with unusual field names?

Yes. Field names are matched case-insensitively against the common aliases — message/msg/text, level/severity/lvl (numeric pino/bunyan levels too), timestamp/time/ts/@timestamp/createdDateTime/TimeGenerated, ip/client_ip/ipAddress/sourceIPAddress, user/userPrincipalName, status/status_code, duration_ms/latency — including nested ones like http.status_code. When none exist the raw JSON is shown, so nothing is dropped. Click a line to see the whole object pretty-printed.

What about multi-line stack traces?

Each physical line is treated as one entry, so a Java or Python traceback appears as its first line plus its at … continuations. The continuation lines usually have no timestamp and no level, which makes them easy to spot but does inflate the line count. Structured JSON logging, where the stack is a field, avoids the problem entirely.

Are gzipped logs supported?

Not directly — decompress first with gunzip -c app.log.gz > app.log, or paste the output. Rotated plain-text files (access.log.1) work fine; rename them to .log or .txt if the file picker filters them out.

Can I load several files at once?

One at a time. To analyse several together, concatenate them first — cat access.log.2 access.log.1 access.log > all.log — which also keeps them in chronological order, something the timeline depends on.

The timeline and the stats

How does the timeline chart work?

Every parsed timestamp is placed into a bucket, and each bar is stacked by severity: red for errors and critical, yellow for warnings, green for everything else. The shape tells you in one glance whether a problem was a spike, a step change or a slow ramp.

What size are the buckets?

Chosen automatically so the chart has at most about 120 bars: per minute for a short file, per five minutes for a six-hour log, per hour for a week, per day beyond that. The label above the chart says which one is in use. Hover a bar for its exact counts.

Can I zoom into a spike?

Drag across the chart to zoom the table to that stretch, or click a single bar for just that bucket (click it again to undo). The selected window stays highlighted and appears as a ⏱ chip in the filter bar. That is the fastest triage path there is: see the red column, drag over it, read the twenty lines that actually matter instead of scrolling through fifty thousand.

Why does the timeline change when I filter?

The bars always show what your filters leave, on the same scale as the whole file, with the full file as a grey silhouette behind them. Filter on one IP and you see exactly when it was active; search timeout and you see when the timeouts started.

What does the “Time Range” stat mean?

The first and last timestamp that parsed successfully. If it looks wrong — a range of years in a file you know covers one day — you have either a syslog file spanning a year boundary or lines whose dates are being misread, and the messy demo log is a good way to see what that looks like.

Why is the parsed line count lower than the total?

Blank lines are skipped, and lines with no recognisable structure are counted but not given a timestamp. A large gap between the two numbers usually means the format was mis-detected, or the file mixes formats — in which case the generic parser is doing its best on lines it was not designed for.

What counts as an error in the stats?

Anything classified as ERROR, CRIT or FATAL, plus every 5xx response in an access log. Warnings cover WARN and 4xx. That mapping is deliberately blunt: a 404 is not a server fault, but a sudden wall of them is still worth seeing in yellow.

Filtering, searching and exporting

How do the level chips work?

Each chip filters the table to one severity, and combines with everything else that is active. Clicking Error and typing timeout in the search box gives you error lines mentioning timeouts — which is usually the first question you have about an incident.

How does the search work?

Plain text is a case-insensitive substring match over the whole line — message, path, user agent or raw JSON — so a pasted URL with dots and question marks just works. Wrap it in slashes for a regular expression: /5\d\d|timeout/, also case-insensitive. Start with ! to exclude: !healthcheck hides the noise. Matches are highlighted in the table, an invalid regex turns the box red instead of breaking anything, / jumps to the search box and Esc clears it.

What does the IP filter do?

Matches the client or source address — from access logs, but also from SSH lines, firewall SRC=, Entra ID, CloudTrail and Windows events — on a prefix: typing 45.83. isolates a whole range rather than one host. The user box next to it does the same for accounts, as a substring. Load the Nginx demo, copy the scanner IP out of the patterns panel, and paste it in: everything it touched appears at once.

What is the status filter for?

Access logs only. It narrows to a class of HTTP response: 5xx for server errors, 4xx for client errors, 3xx for redirects, 2xx for successes. Combined with a timeline click it answers “what broke, in that minute” without any grepping.

How do I export what I am looking at?

Two buttons: ⬇ .log writes the currently filtered lines back out in their original form, and ⬇ .csv writes the parsed fields — timestamp, level, and whichever of service, user, IP, path, status, port and duration the file has, plus the message — as a spreadsheet. Both respect every active filter, so what you see is exactly what you get.

Why export to CSV rather than keep the log format?

Because once the fields are separated you can pivot on them. A CSV of the 5xx window opens in Excel or pandas and answers “which endpoint, which client, what time” in a couple of minutes — and it is the right thing to attach to an incident ticket, because the recipient does not need this tool to read it.

Can I share a filtered view with a colleague?

Not as a link — the log lives only in your browser, so there is nothing to link to. Export the filtered .log or .csv and send that. It is also the safer habit: you decide exactly which lines leave your machine.

Patterns and insights

What are the insights?

A short list of findings computed from the whole file, each with a severity and a show → button that sets the filters for you. The checks: error spikes compared with the rest of the file, critical events, password spray (one source, many accounts), brute force (one source, few accounts), a successful sign-in after repeated failures, account lockouts, MFA fatigue, a successful sign-in from a rarely seen country, an identity suddenly used from a new IP, account and privilege changes, vulnerability scanners, port scans, out-of-memory kills and restarts, gaps with no log lines, p95 latency and the dominant error message. They are heuristics: they point at what deserves a look, they do not prove an incident.

What is in the Patterns panel?

Whatever the file supports: the spread of log levels, the most frequent error and warning messages (grouped so that numbers and IDs do not split them), top IPs, users, users with the most failures, HTTP status classes, paths, services or event IDs, AWS API calls, firewall destination ports and countries. Every row is clickable and adds a filter, so it doubles as navigation.

How do I spot a scanner or a bot?

Look for one IP with a request count far above the rest, hitting paths your application does not have — /wp-login.php, /.env, /.git/config, /phpmyadmin — and getting 404s for all of them. The Nginx demo contains exactly that pattern so you can see the shape before you meet it in a real log.

What does a spike in 404s usually mean?

Three common causes: a scanner (many different odd paths from one IP), a broken deployment (many requests for one asset path that no longer exists), or a bad link somewhere popular (one path, many different clients, often with a referrer). The top-paths list separates them immediately.

What does a wall of 499 or 502 mean?

499 is Nginx's own code for “client gave up before we answered” — it usually means your upstream got slow and users hit stop. 502 and 504 mean the upstream failed or timed out outright. Seeing 499s ramp before the 502s is the classic signature of a backend saturating rather than crashing.

How do I find the start of an incident?

Filter to errors, look at the first red bar on the timeline, click it, then clear the error filter and read the surrounding lines. The interesting event is almost always the last normal line before the errors — a deploy, a config reload, a certificate renewal, a restart.

What should I look for in a syslog file?

OOM kills (Out of memory: Killed process), units that failed and restarted (Main process exited, Scheduled restart job), repeated Failed password lines from one address, firewall [UFW BLOCK] lines, and disk or certificate warnings. The syslog and firewall demos cover all of them.

How do I investigate a suspicious sign-in?

Start from the insight, press show →, then widen: click the user in an expanded line to see everything that account did, and the IP to see every account that address tried. In the Entra ID demo that path goes from the spray, via the Conditional Access block on IMAP and nine denied MFA prompts, to the approval and the mailbox access that followed — the order a real investigation needs to establish.

Performance and large files

How large a file can it handle?

There is no hard limit — the practical ceiling is your browser's memory, and files of a few hundred megabytes are usually fine on a desktop. Parsing runs in batches so the tab stays responsive, and the progress bar shows real progress rather than a spinner.

Why does the table only show part of my file?

Rendering a hundred thousand table rows would freeze the page, so the table caps what it draws while the stats, timeline and patterns are computed over every line. Narrow with a filter or a timeline click and you are looking at all the matches that matter.

What is the fastest way to work with a huge log?

Cut it down before loading. grep -i error big.log > errors.log, or sed -n '/14:00/,/15:00p' big.log for a time window, or tail -n 200000 big.log for the recent past. You lose the full-file statistics but gain a much faster loop — and you can always load the whole thing afterwards once you know what you are looking for.

My browser tab became slow or crashed.

The file was larger than the available memory. Split it (split -l 500000 big.log part-), pre-filter with grep, or use a desktop tool for the first pass. A browser tab typically has a couple of gigabytes to work with, and a log line costs far more in memory as a parsed object than as text on disk.

Does it stream the file or read it all at once?

It reads the file into memory and then parses in batches. That is what makes the timeline and the patterns possible over the whole file, and it is also why the practical limit is memory rather than time.

Privacy and safe handling

Is it really safe to open production logs here?

The tool never transmits your file — no upload, no API call, no storage. You can verify it: open the network tab and watch it stay empty while you load a file. That is the whole reason it exists, because production logs are exactly the thing you cannot paste into a cloud analyser.

Is anything saved between sessions?

Not your log. Two tiny flags are kept in localStorage — your light/dark choice and a “has visited” marker so the demo only opens automatically once — and nothing else. Reload the page and the log is gone, which also means nothing is left behind on a shared machine.

What about the analytics on the site?

Privacy-first page-view counting with no cookies and no personal data. It records that the page was viewed; it has no access to the file you opened, which never leaves the JavaScript running in your tab.

What sensitive data hides in logs?

More than people expect: client IP addresses (personal data under the GDPR), session tokens and API keys in query strings, email addresses in URLs and error messages, internal host names and file paths, and full stack traces revealing your dependency versions. Treat a log export with the same care as a database dump.

Can I share a log with support safely?

Filter to only the lines that matter, export that, and scrub what remains — sed -E 's/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/x.x.x.x/g' for IPs, and remove any token= or key= query parameters. Exporting a filtered slice rather than the whole file is already most of the work.

Are IP addresses in logs personal data?

Under the GDPR, yes — an IP address is generally treated as personal data, which is why log retention periods and access controls matter, and why uploading raw logs to a third-party service is a decision rather than a detail.

Troubleshooting

My file loaded but everything shows as unparsed.

The format was not recognised and no timestamp was found. Check the first few lines: if the timestamp is in a format not listed above, the generic parser has nothing to grab. CSV files need a header row with a time or date column to be read as records. Search, filtering and export still work on the raw text.

The timestamps are a year out.

Syslog lines carry no year. The current one is assumed, and a date that would land in the future is moved back a year, which handles the December-log-in-January case. A file covering more than a year is still ambiguous — convert to ISO timestamps at the source (journalctl -o short-iso) and the problem disappears permanently.

My timezone looks wrong.

Timestamps without an offset (syslog, the Apache error log, Windows CSV exports) are shown exactly as written; timestamps with one are shown in UTC. Most server and cloud logs are UTC already, so if you compare them to your local clock they will look shifted.

Everything is classified as INFO.

The lines contain no level keyword and no HTTP status. That is common for application logs that print bare messages. Adding a level to your log format is worth doing — it is the field that makes every downstream tool, including this one, useful.

The file picker will not accept my log.

It filters on .log, .txt, .json and .csv. Rename a rotated file (access.log.1 → access1.log), or drag it onto the drop zone, which accepts anything, or paste the contents.

Nothing happens when I drop a file.

Make sure you are dropping onto the drop zone itself rather than elsewhere on the page, and that the browser has not opened the file in a new tab instead — that happens when the drop lands outside the target. Clicking the zone and using the picker always works.

How do I start over?

✕ clear resets everything and returns you to the drop zone. There is nothing cached, so a reload does the same thing.

Which browsers work?

Any current version of Chrome, Edge, Firefox, Safari, Brave, Opera or Vivaldi, on desktop or mobile. No frameworks and no external libraries. A phone will struggle with a very large file simply because it has less memory.

Can this replace a real log platform?

No, and it is not trying to. Elastic, Loki, Splunk and Datadog exist for continuous ingestion, retention, alerting and correlation across hosts. This is the tool for the file you already have in front of you — the one that arrived attached to a ticket, or that you pulled off a box five minutes ago, where standing up a pipeline would take longer than reading the log.

Just want to read one log or config file? The free online notepad opens it in a tab with line numbers, go-to-line and regex search across all open files. Nothing is uploaded, and it works offline after your first visit.

More free tools