DevOps Tools

Log Analyzer

Paste or drop an Nginx or Apache access log, a JSON lines (NDJSON) log or a plain application log and get instant statistics: status code classes, top paths, IPs and user agents, the most frequent errors, requests over time and bytes served. Filter by text or regex, level, status class and time range, then export the matching lines.

Private by design: anything you enter is processed in your browser only. It is never uploaded to or logged on our servers. Logs often contain IP addresses, user IDs, tokens and other personal data, so files are read and parsed entirely on your device and never uploaded. Share links include the pasted log text itself, so only share logs you are allowed to.

Samples:

Entries over time

Entries

About the log analyzer

When an incident starts, the first questions are usually the same: which status codes are we returning, since when, for which URLs and from which clients? This analyzer answers them from a raw log in seconds, without installing GoAccess, setting up an ELK stack or writing an awk pipeline. It recognises the Nginx and Apache combined and common log formats (with an optional request time at the end of each line), JSON lines from structured loggers such as pino, bunyan, zap, logrus, Serilog or the Docker json-file driver, and plain text application logs with levels like ERROR, WARN and INFO and ISO 8601 or syslog timestamps.

Format detection looks at the first hundred non-empty lines; switch the format manually if a log mixes styles. In plain text logs, lines without a timestamp or level (stack traces, wrapped messages) are attached to the entry above them, so an exception counts once. Error messages are grouped after numbers, UUIDs, IP addresses, e-mail addresses and long hex strings are replaced by placeholders, so "timeout after 3012 ms for user 81" and "timeout after 2950 ms for user 7" land in the same bucket. Times are shown in UTC; timestamps without a zone are assumed to be UTC, and syslog timestamps, which have no year, are given the current year.

Files of 50 MB and more are parsed in chunks so the page stays responsive, and the table renders the first 500 matching entries at a time while the statistics always cover every matching line. Click a bar in the timeline to zoom into that interval, or click an item in a top-10 list to filter on it. A filter wrapped in slashes, such as /POST .*\/login/ or /timeout|refused/i, is treated as a regular expression; build and debug complex patterns in the regex tester.

Related tools: convert epoch values from JSON logs with the Unix timestamp converter, check whether suspicious client IPs belong to the same network with the subnet calculator, turn the outage you just found into an uptime percentage with the SLA & uptime calculator, and use the peak requests per second from the timeline in the throughput estimator.

Reference Guide

Access log formats this tool parses:

ServerDefinition
Nginx combined (default)log_format combined '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"';
Nginx with timinglog_format timed '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_time';
Apache combinedLogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" combined
Apache common (CLF)LogFormat "%h %l %u %t \"%r\" %>s %b" common

Fields of a combined log line:

FieldNginxApacheExample
Client IP$remote_addr%h203.0.113.7
Identity (always -)literal -%l-
Auth user$remote_user%u- or alice
Time$time_local%t[24/Oct/2026:13:55:36 +0000]
Request line$request%r"GET /api/orders?page=2 HTTP/1.1"
Status$status%>s200
Body bytes$body_bytes_sent%b (- for 0)5120
Referer, user agent$http_referer, $http_user_agent%{Referer}i, %{User-agent}i"-" "curl/8.5.0"

HTTP status classes:

ClassMeaningCommon codes in logs
1xxInformational101 Switching Protocols (WebSocket upgrade)
2xxSuccess200 OK, 201 Created, 204 No Content, 206 Partial Content
3xxRedirection301 Moved Permanently, 302 Found, 304 Not Modified
4xxClient error400, 401, 403, 404, 429 Too Many Requests, 499 (Nginx: client closed the connection)
5xxServer error500, 502 Bad Gateway, 503 Service Unavailable, 504 Gateway Timeout

Shell one-liners for combined logs (field numbers assume the default format):

QuestionCommand
Top client IPsawk '{print $1}' access.log | sort | uniq -c | sort -rn | head
Requests per status codeawk '{print $9}' access.log | sort | uniq -c | sort -rn
Top paths returning 5xxawk '$9 ~ /^5/ {print $7}' access.log | sort | uniq -c | sort -rn | head
Requests per minuteawk '{print substr($4, 2, 17)}' access.log | uniq -c
Total bytes sentawk '$10 ~ /^[0-9]+$/ {s += $10} END {print s}' access.log
Follow errors livetail -F access.log | grep --line-buffered '" 5[0-9][0-9] '

jq for JSON lines logs:

QuestionCommand
Only errors, message fieldjq -r 'select(.level == "error") | .msg' app.log
Count by leveljq -r '.level' app.log | sort | uniq -c
Status 500 and abovejq -c 'select(.status >= 500)' app.log
Group in jq (slurp)jq -s 'group_by(.level) | map({level: .[0].level, count: length})' app.log
Skip non-JSON linesjq -R 'fromjson? | select(.msg)' app.log

Recognised JSON keys: level (level, severity, lvl, log.level, levelname, @l; numeric pino/bunyan levels 10–60), message (msg, message, @m, event, log), time (time, timestamp, ts, @timestamp, @t; ISO strings or epoch seconds/milliseconds) and HTTP fields such as status, path, method and remote_addr.

Example input

203.0.113.7 - - [24/Oct/2026:13:55:36 +0000] "GET /api/orders?page=2 HTTP/1.1" 200 5120 "https://shop.example.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" 0.042
198.51.100.23 - - [24/Oct/2026:13:55:37 +0000] "POST /api/checkout HTTP/1.1" 502 157 "-" "okhttp/4.12.0" 30.001

This sample loads automatically when you open the tool. Use Load Sample to bring it back.

Frequently Asked Questions

Nginx and Apache access logs in the common and combined formats, JSON lines (NDJSON) from structured loggers, and plain-text application logs with levels such as ERROR, WARN and INFO. The format is detected automatically.

No. Files are read and analysed in your browser, so IP addresses and other personal data in your logs never leave your device.

Files of tens of megabytes work in a modern browser. For very large logs, filter them first with grep or take a time slice.