Free Access Log Analyzer
Paste nginx or Apache access log lines for a summary of statuses, paths and clients, a table of requests, or just the errors.
What is an Access Log Analyzer?
Web servers write one line per request to an access log: who asked, when, for what, and what they got back. This analyzer reads nginx and Apache access log lines and summarises them, lists every request in a table, or picks out the failures.
It reads the NCSA Common Log Format, Apache’s default, and the Combined format that nginx and many Apache setups use, which adds the referer and user agent. Request lines are split into method, path and protocol, and malformed ones, such as TLS handshakes sent to a plain HTTP port, are kept as written.
Key Features
A Summary in One Paste
Request count, time range, status classes, the five busiest paths and clients, and total bytes sent appear together.
Errors With Line Numbers
Errors only lists every 4xx and 5xx response with its line, status, method, path and client, ready to search for in the full log.
A Sortable Request Table
Requests lays out every parsed line in columns, so you can scan statuses and paths instead of raw text.
Both Common Formats
Lines with or without referer and user agent are read, and lines in neither format are skipped and listed by number.
IP Addresses Stay Private
Logs are parsed in your browser, so client IP addresses and URLs aren’t uploaded anywhere.
Perfect for everyone
- Sysadmins and DevOps engineers
- Developers debugging production errors
- Site owners checking traffic and bots
How to Use the Access Log Analyzer
Paste log lines and choose a summary, the full table, or the errors.
Copy the Log Lines
Use tail -n 1000 /var/log/nginx/access.log, or copy from your hosting panel. Paste a few lines or many thousands.
Read the Summary
Status classes show the overall health, and top paths and clients show where traffic and trouble come from.
List the Errors
Errors only shows each failing request with its line number, so you can find it in the full log or match it to application logs.
Scan the Request Table
Requests shows every line in columns. Download the report to attach to an incident or ticket.
Access Logs, Analysed
Every answer here is the analyzer’s report for the log lines beside it, in Summary or Errors only mode as the chip says. Guess the status counts first.
“203.0.113.7 - - [25/Oct/2026:09:14:02 +0000] "GET / HTTP/1.1" 200 5320 "-" "Mozilla/5.0" 203.0.113.7 - - [25/Oct/2026:09:14:03 +0000] "GET /app.js HTTP/1.1" 304 0 "https://example.com/" "Mozilla/5.0" 198.51.100.23 - - [25/Oct/2026:09:15:10 +0000] "POST /api/login HTTP/2.0" 401 42 "-" "curl/8.4.0"”
“203.0.113.7 - - [25/Oct/2026:09:14:02 +0000] "GET / HTTP/1.1" 200 5320 "-" "Mozilla/5.0" 198.51.100.23 - - [25/Oct/2026:09:15:10 +0000] "POST /api/login HTTP/2.0" 401 42 "-" "curl/8.4.0" 10.0.0.5 - - [25/Oct/2026:09:17:00 +0000] "GET /api/orders HTTP/1.1" 502 157 "-" "Go-http-client/1.1"”
“127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326 127.0.0.1 - - [10/Oct/2000:13:56:02 -0700] "GET /missing.html HTTP/1.0" 404 209”
“203.0.113.7 - - [25/Oct/2026:09:14:02 +0000] "GET / HTTP/1.1" 200 5320 "-" "Mozilla/5.0" 203.0.113.7 - - [25/Oct/2026:09:14:03 +0000] "GET /about HTTP/1.1" 200 2210 "-" "Mozilla/5.0"”
“203.0.113.7 - - [25/Oct/2026:09:14:02 +0000] "GET / HTTP/1.1" 200 5320 "-" "Mozilla/5.0" 2026/10/25 09:14:05 [error] 1234#0: upstream timed out 203.0.113.7 - - [25/Oct/2026:09:14:09 +0000] "GET / HTTP/1.1" 200 5320 "-" "Mozilla/5.0"”
“192.0.2.99 - - [25/Oct/2026:09:16:00 +0000] "GET /wp-login.php HTTP/1.1" 404 162 "-" "python-requests/2.31.0" 192.0.2.99 - - [25/Oct/2026:09:16:01 +0000] "GET /.env HTTP/1.1" 404 162 "-" "python-requests/2.31.0" 192.0.2.99 - - [25/Oct/2026:09:16:02 +0000] "GET /.git/config HTTP/1.1" 404 162 "-" "python-requests/2.31.0"”
“203.0.113.7 - - [25/Oct/2026:09:14:02 +0000] "HEAD /health HTTP/1.1" 200 - "-" "kube-probe/1.30" 203.0.113.7 - - [25/Oct/2026:09:14:12 +0000] "HEAD /health HTTP/1.1" 200 - "-" "kube-probe/1.30"”
“192.0.2.1 - - [25/Oct/2026:09:16:01 +0000] "\x16\x03\x01" 400 157 "-" "-"”
“10.0.0.5 - - [25/Oct/2026:09:17:00 +0000] "GET /api/orders?page=2 HTTP/1.1" 502 157 "-" "Go-http-client/1.1"”
“{"time":"2026-10-25T09:14:02Z","status":200,"path":"/"}”
What Each Field in a Log Line Means
A Combined Log Format line has nine fields. These ten notes explain each one and how to read it.
Client Address
The first field is the IP that connected. Behind a load balancer or CDN it’s their address unless the server uses the real IP module.
“Why might every line show the same IP?”
Identity and User
The second field is from identd and is nearly always a dash. The third is the HTTP authentication user, or a dash.
“What fills the second field today?”
Timestamp
The time the request was received, in brackets, with the server’s UTC offset, such as 25/Oct/2026:09:14:02 +0000.
“Is the time when the request started or finished?”
Request Line
The method, path with query string, and protocol in quotes, such as GET /api/orders?page=2 HTTP/1.1.
“Does the path include the query string?”
Status Code
The HTTP status sent back. 2xx is success, 3xx redirect, 4xx a client error, and 5xx a server error.
“Which class means the server failed?”
Bytes Sent
The size of the response body in bytes, or a dash when there was no body, as with 304 and HEAD responses.
“What does a dash in the bytes field mean?”
Referer
The page that linked to this request, from the Referer header, or a dash. Browsers often shorten it to the origin.
“Which header fills the referer field?”
User Agent
The client software from the User-Agent header. Bots, scripts and health checks name themselves here.
“Which field shows that curl made a request?”
Common Versus Combined
The Common format stops after bytes, while Combined adds referer and user agent. nginx’s default combined format is the latter.
“Which format has the user agent?”
Escaped Request Lines
Binary data, such as a TLS handshake sent to port 80, is written as escapes like \x16\x03\x01. It usually means a client used HTTP on an HTTPS port, or the reverse.
“What does \x16\x03\x01 in a request usually mean?”
Log Format Directives in nginx and Apache
Each field in a log line comes from a directive in log_format or LogFormat. These are the ones behind the Combined format, plus two worth adding.
$remote_addr and %h
The client address. nginx’s $remote_addr and Apache’s %h both become the first field, and both change when a real IP module is on.
$time_local and %t
The request time in the server’s local zone with its offset. nginx also offers $time_iso8601, which this analyzer doesn’t read.
$request and %r
The full first line of the request, quoted. A missing or broken request line is logged as a dash or as escaped bytes.
$status and %>s
The final status. In Apache, %s is the original status and %>s is the one after internal redirects, which is what you want.
$body_bytes_sent and %b
Body bytes without headers. nginx’s $bytes_sent and Apache’s %O include headers, so totals from them run slightly higher.
$http_referer and %{Referer}i
Any request header can be logged this way. Combined adds the referer and user agent after the bytes field.
$request_time and %D
Time taken to serve the request, in seconds for nginx and microseconds for Apache. Appended after the combined fields, these lines still parse here.
$upstream_response_time
How long the proxied application took, in nginx. Comparing it with $request_time shows whether the delay was the app or the client.
Reading the Status Codes
The status classes tell you where to look. These are the codes that matter most in access logs.
304 Not Modified
The browser’s cached copy is still current, so no body is sent. Lots of 304s are good caching, not a problem.
401 and 403
401 means credentials are missing or wrong, and 403 means they’re valid but not allowed. Bursts of 401 on a login path can be password guessing.
404 Not Found
A broken link or a probe. Requests for /wp-login.php, /.env or /.git on a site that doesn’t have them are scanners.
429 Too Many Requests
Rate limiting kicked in. Check whether it’s a misbehaving client or your limits are too tight.
502 and 504
The proxy couldn’t reach the application, or the application took too long. Check the app’s health and timeouts.
499 in nginx
An nginx-specific code meaning the client closed the connection before the response was sent, often because the app was slow.
Where to Find Your Access Logs
Default log paths differ by server, distribution and platform. Start with these.
nginx on Debian and Ubuntu
Access logs live in /var/log/nginx/access.log, with older ones rotated to access.log.1 and gzipped files after that.
Apache httpd
Debian-family systems write /var/log/apache2/access.log, while Red Hat-family systems use /var/log/httpd/access_log.
Docker Containers
The official nginx image sends its access log to standard output, so run docker logs with the container name to read it.
Kubernetes Ingress
The ingress-nginx controller logs every request through the cluster. Use kubectl logs on the controller pod in its namespace.
Compressed Rotations
Older rotated logs end in .gz. Read them with zcat or zless, then paste the lines you need.
When to Analyse an Access Log
Whenever you need to know what a web server has actually been serving.
Investigating a Spike in Errors
Paste the lines around an alert and list the 5xx responses, with paths and clients, to see what broke.
Spotting Bots and Scanners
Top clients and errors reveal IPs probing for admin pages and config files.
Checking a Deploy
Compare status classes before and after a release to confirm errors didn’t rise.
Finding Your Busiest Pages
Top paths show which pages and API endpoints take the most traffic.
Debugging a Client Report
Search a user’s IP or time and read their exact requests and the statuses they received.
Estimating Bandwidth
The bytes total shows how much a slice of traffic cost, before reaching for a full analytics tool.
Teaching Log Reading
Walk through real log lines field by field, with the table laying out each part.
Access Log Pitfalls
These make access logs harder to read, or the analysis misleading.
Proxy Addresses Instead of Clients
Behind a load balancer every request seems to come from it. Configure the real IP module and trusted proxies so logs record the client.
Mixing Error and Access Logs
nginx’s error log has a different format, so its lines are skipped here. Paste access log lines only.
Custom Log Formats
A log_format with extra fields, such as request time, may still parse if it starts with the combined fields. Fully custom or JSON formats won’t.
Time Zones
Each line carries the server’s offset, and servers in different zones log different local times. Compare offsets before lining up events.
Counting Health Checks as Traffic
Load balancer and Kubernetes probes can dominate a log. Filter their user agents out before judging real traffic.
Assuming 404s Are Broken Links
Most 404s on public servers are bots probing for known vulnerabilities. Look at the paths and user agents before fixing links.
Logging Sensitive Query Strings
Tokens in URLs end up in access logs. Strip or mask them in log_format, or move them to headers.
Reading Rotated Files Out of Order
access.log.1 holds older entries than access.log. Paste them oldest first if the time range matters.