The basics
What is a LOG file?
A .log file is a program's diary. Web servers write one line per request, applications note what they did and what went wrong, installers record each step, games and launchers keep a log for crash reports. New lines are added at the end while the program runs, so a log keeps growing until something rotates or deletes it.
Logs are how people find out what happened after the fact: why a page returned an error, when a server slowed down, who signed in, whether an attack was tried. Support teams often ask for a log file because it shows what the user can't.
Three things that explain most confusion:
- There is no single log format.
.logonly says "this is a log". The layout inside depends entirely on the program, though many follow one of a handful of conventions, described below. - It's plain text, like a TXT file with rules on top, so any editor can open it. The challenge is size, not format.
- Not every log is a
.logfile. Windows keeps its system logs in binary.evtxfiles for Event Viewer, macOS stores its unified log in a compressed binary format you read with the Console app or thelogcommand, and Linux systems with systemd keep a journal that you read withjournalctl.
Anatomy
What's inside a log file
A log has no header and no structure the file itself enforces: each program decides what a line looks like. Most application logs follow the same pattern, though: time, severity, where it came from, and a message. Here is an excerpt from the sample application log below, part by part.
2026-10-27T09:14:02.118+01:00 INFO [main] app.Startup - Starting checkout-service 4.2.1
2026-10-27T09:14:02.354+01:00 DEBUG [main] app.Config - Loaded 14 settings from /etc/checkout/config.toml
2026-10-27T09:14:11.442+01:00 INFO [http-1] app.Http - request_id=7f3a1c GET /api/products 200 18ms
2026-10-27T09:14:15.877+01:00 WARN [http-3] app.Database - request_id=7f3a1f slow query (1240 ms > 1000 ms)
2026-10-27T09:14:19.733+01:00 WARN [http-1] app.Auth - request_id=7f3a21 sign-in failed user="eve\nINFO [main] app.Auth - admin signed in"
2026-10-27T09:14:21.064+01:00 ERROR [http-4] app.Payment - request_id=7f3a22 payment failed order=A-1001
java.net.SocketTimeoutException: Read timed out after 5000 ms
at app.payment.ExamplePayClient.charge(ExamplePayClient.java:88)
at app.payment.PaymentService.pay(PaymentService.java:41)
2026-10-27T09:14:23.410+01:00 INFO [http-4] app.Payment - request_id=7f3a22 payment ok order=A-1001 amount=34.00 EUR- 1
2026-10-27T09:14:02.118The timestamp
ISO 8601 date and time, to the millisecond. Written largest unit first, it sorts correctly as plain text.
- 2
+01:00The UTC offset
Says which time zone the clock was in (here Central European Time). Without it,
09:14is ambiguous, especially across servers or a daylight-saving change. - 3
INFO / DEBUG / WARN / ERRORThe level
How serious the event is. Padded to one width so the columns line up. Production systems often hide
DEBUGlines. - 4
[http-1]The thread
Which part of the program wrote the line. Requests handled at the same time interleave in the file, so this helps pull them apart.
- 5
app.PaymentThe logger name
The component that wrote the line, usually named after the module or class.
- 6
request_id=7f3a22A correlation ID
The same ID on every line about one request, so
grep 7f3a22collects its whole story, here a failed payment, a retry and a success. - 7
order=A-1001 amount=34.00 EURKey=value fields
Half-structured data inside the message, easy to search and extract. JSON Lines logs take this all the way, with every line a JSON object.
- 8
user="eve\nINFO [main] …"An escaped line break
Someone typed a line break and a fake log entry as their user name. The program wrote it as the two characters
\n, so it stays on one line instead of forging a second entry. That's log injection, defused. - 9
java.net.SocketTimeoutException … / at …A multi-line entry
A stack trace spreads one event over several lines that don't start with a timestamp. Tools that treat every line as an event miscount these.
Formats
Common log layouts: syslog, Combined Log Format, JSON Lines
| Layout | Written by | What a line looks like |
|---|---|---|
| Application text log | Most programs, via logging libraries (Log4j, Logback, Python logging, Serilog…) | Time, level, source and message; the exact layout is configurable |
| Syslog, RFC 5424 | Linux and network devices, sent to a syslog server | <PRI>1 TIMESTAMP HOST APP PROCID MSGID [STRUCTURED-DATA] MSG |
| BSD syslog, RFC 3164 | Older systems; many /var/log files still look like it | Oct 27 09:14:02 host app[4123]: message, with no year or time zone |
| Common and Combined Log Format | Apache httpd, Nginx and many other web servers | One line per HTTP request, fields separated by spaces |
| W3C extended log format | Microsoft IIS | A #Fields: header line names the columns, then one request per line |
| JSON Lines | Cloud services, containers, structured-logging libraries | One complete JSON object per line |
The Combined Log Format is what Nginx writes by default (access_log logs/access.log combined) and Apache's most common setting. Every field is fixed in place:
203.0.113.7 - - [27/Oct/2026:09:14:10 +0100] "GET /old-page HTTP/1.1" 301 162 "-" "ExampleBot/2.1 (+https://bot.example.org/about)"
│ │ │ │ │ │ │ │ └ User-Agent header, as sent by the client
│ │ │ │ │ │ │ └ Referer header ("-" = none)
│ │ │ │ │ │ └ bytes in the response body
│ │ │ │ │ └ HTTP status code
│ │ │ │ └ the request line: method, path, protocol
│ │ │ └ local time, with the server's UTC offset
│ │ └ user name from HTTP authentication ("-" = none)
│ └ identd user, practically always "-"
└ client IP address (or the last proxy's)Syslog (RFC 5424, 2009) starts each message with a priority in angle brackets: facility × 8 + severity. <134> is facility 16 (local0) and severity 6 (informational). A - marks any field that's empty, and structured data in square brackets carries key-value pairs; IDs containing @ belong to a private enterprise number, and 32473 is the one reserved for documentation.
<134>1 2026-10-27T09:14:12.301+01:00 web01.example.com checkout 4123 CART [exampleSDID@32473 cart="c-1093" qty="2"] item added
│ │ │ │ │ │ │ │ └ MSG, free text
│ │ │ │ │ │ │ └ STRUCTURED-DATA, or "-" if none
│ │ │ │ │ │ └ MSGID, a type of message
│ │ │ │ │ └ PROCID, often the process ID
│ │ │ │ └ APP-NAME
│ │ │ └ HOSTNAME
│ │ └ TIMESTAMP, RFC 3339 with offset
│ └ VERSION, 1 in RFC 5424
└ PRI: facility 16 (local0) × 8 + severity 6 (informational)JSON Lines puts one JSON value on each line, in UTF-8, with no blank lines. Every log processor can parse it without guessing the layout, and a value with a line break is written as \n inside its string, so one event is always one line. The files are often called .jsonl, but plenty of programs write JSON Lines to a .log file.
Time
Timestamps and time zones
A log is only as useful as its clock. Comparing a web server log with a database log, or tracing an attack across machines, means lining up timestamps written by different programs in different formats:
| Written as | Where you see it | Watch out for |
|---|---|---|
2026-10-27T08:14:02.118Z | JSON logs, cloud services; ISO 8601 / RFC 3339 in UTC | Nothing: unambiguous and sorts as text |
2026-10-27T09:14:02.118+01:00 | Application logs, RFC 5424 syslog | The same moment as the line above, in local time with its offset |
27/Oct/2026:09:14:02 +0100 | Apache and Nginx access logs | Doesn't sort as text across months |
Oct 27 09:14:02 | BSD-style syslog files | No year and no time zone |
2026-10-27 08:14:02 | IIS W3C logs (in UTC), many databases | Nothing in the line says which zone it is |
1793088842 | Unix time: seconds since 1 January 1970 UTC | Milliseconds (13 digits) vs seconds (10 digits) |
The hour that happens twice
When clocks go back at the end of daylight saving time (in the EU, on 25 October 2026), local times from 02:00 to 02:59 occur twice. A log in local time without an offset can't say which one it means, and its lines appear to go back in time. Logging in UTC, or with the offset, avoids it.
Severity
Log levels: from DEBUG to EMERGENCY
Most logging systems give each entry a level, so you can filter the noise. Syslog defines eight severities, numbered so that lower is worse; application libraries use a shorter list of names:
| Syslog severity (RFC 5424) | Typical application level | Meaning |
|---|---|---|
| 0 Emergency, 1 Alert, 2 Critical | FATAL, CRITICAL | The system or program can't go on |
| 3 Error | ERROR | Something failed: a request, a payment, a job |
| 4 Warning | WARN, WARNING | Unexpected but handled: a retry, a slow query |
| 5 Notice, 6 Informational | INFO | Normal events worth recording |
| 7 Debug | DEBUG, TRACE | Detail for developers, usually off in production |
Setting a level is a threshold: a server configured for warn records warnings and everything more severe, and drops the rest. Nginx's error_log directive and Python's logging module both work this way.
Keeping it small
Log rotation: .log.1, .log.2.gz and dated files
Left alone, a busy log fills the disk: Apache's documentation estimates 1 MB or more per 10,000 requests for an access log. Rotation renames the current file, starts a new one and deletes the oldest. On Linux the logrotate tool usually does this every day or week:
- Numbered copies:
app.logbecomesapp.log.1, the old.1becomes.2, and so on;rotate 7keeps seven. - Compression: with
compress, older copies are gzipped intoapp.log.2.gz;delaycompressleaves the newest copy uncompressed for a cycle, because the program may still be writing to it. Read them withzcat,zlessorzgrep, or open them as GZ files. - Dated names:
dateextnames copies likeapp.log-20261027instead of numbering them. - Telling the program: after a rename, a program keeps writing to its open file, now called
.log.1. logrotate either signals it to reopen the log (Apache uses a graceful restart) or usescopytruncate, which copies the file and empties the original, at the risk of losing a few lines.
"My log is empty" or "the disk is still full after deleting the log" usually have the same cause: the program still holds the old file open. New lines go to the renamed copy, and a deleted file's space isn't freed until the program closes it. Restart or signal the program.
How to
How to open and read a log file, even a huge one
Small logs open in any text editor. Big ones (hundreds of megabytes or more) make Notepad, TextEdit and many editors slow or unresponsive, because they load the whole file. Command-line tools read only what they need:
tail -n 100 app.log # the last 100 lines
tail -f app.log # keep printing new lines as they're written
less +F app.log # follow in less; Ctrl+C to scroll, F to follow again
grep -i "error" app.log # lines containing "error", any case
zgrep "A-1001" app.log.*.gz # search rotated, compressed logs
awk '{print $9}' access.log | sort | uniq -c | sort -rn # count status codes
jq -c 'select(.level == "error")' app.jsonl # filter JSON Lines
journalctl -u nginx --since "1 hour ago" # systemd journal
# Windows PowerShell
Get-Content app.log -Tail 50 -Wait- Windows: small
.logfiles open in Notepad. For system events, open Event Viewer (eventvwr.msc), which reads.evtxfiles fromC:\Windows\System32\winevt\Logs. - macOS: the Console app shows the unified system log and also opens
.logfiles; double-clicking a.logusually opens it there. In Terminal,log showandlog streamread the unified log. - Linux:
/var/logholds system and service logs, readable by root or members of theadmgroup on many distributions;journalctlreads the systemd journal. - Dedicated viewers such as lnav and klogg open multi-gigabyte logs quickly, highlight levels and merge several files by time.
- Spreadsheets: don't. Excel stops at 1,048,576 rows and may mangle timestamps; a CSV export from a log tool is a better route.
Related formats
.log vs .txt, .jsonl, .evtx and the journal
| Format | Text or binary | Structure | Read with |
|---|---|---|---|
.log | Text | Whatever the program writes, usually one event per line | Any editor, less, grep |
.txt | Text | None | Any editor |
.jsonl, .ndjson | Text | One JSON object per line | jq, any JSON parser, log platforms |
.evtx | Binary (XML-based records) | Windows event records with IDs and fields | Event Viewer, PowerShell Get-WinEvent |
| systemd journal | Binary | Indexed fields per entry | journalctl |
| macOS unified log | Binary, compressed | Messages with subsystem and category | Console, log show |
.csv | Text | A table with a header row | Spreadsheets, CSV parsers |
Text logs win on simplicity: any tool can read them, years later. Structured and binary logs win on searching and filtering at scale, which is why large systems ship text logs into a central log platform that parses and indexes them.
Privacy
Privacy and security: what logs give away
Logs record people as well as programs. A web server's access log alone holds visitors' IP addresses, the pages they viewed, when, and their browser; application logs often add user IDs, email addresses and search terms.
- IP addresses can be personal data. The GDPR names IP addresses among the online identifiers that can identify people (Recital 30), and the EU Court of Justice ruled in Breyer (C-582/14, 2016) that even a dynamic IP address can be personal data for a website operator. Keep logs only as long as you need them, and limit who can read them.
- Secrets leak into logs. Passwords in form fields, API keys and session tokens in URLs, and full database connection strings end up in log lines unless the program masks them, as the sample below does with
password=****. Check a log before you share it. - Log injection. If a program writes user input into a log unchanged, a line break in that input starts a fake new entry (CWE-117). Escape line breaks, or log as JSON, where they're escaped automatically. Apache's documentation also warns that raw logs can contain control characters sent by clients, so be careful printing them to a terminal.
- Logging libraries are code too. In December 2021 the Log4Shell flaw in Log4j (CVE-2021-44228) let attackers run code on servers simply by getting a crafted string written to a log.
- Logs are evidence. Attackers delete or edit them to hide their tracks, so security teams send copies to a separate server as they're written.
Before you post a log in a forum, a bug report or a shared link, search it for IP addresses, email addresses, names, tokens and passwords, and replace them. The samples on this page use only the IP ranges reserved for documentation (192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24 and 2001:db8::/32) and example.com host names, which are safe to publish.
Free downloads
Sample log files to download
Free sample log files for testing log viewers, parsers, shippers, upload limits and redaction tools. All data is fictional: IP addresses come only from the documentation ranges and host names from example.com, example.org and example.net. Each file was checked with a parser for its layout.
Loading…What's inside sample-app.log
A log can't contain comments without becoming part of the log, so the test cases are in the lines themselves. Open the file in a text editor to see these parts.
Lines 1 to 6: startup
Version, profile and time zone, then
DEBUGlines, including a database URL with the password already masked as****.Lines 7 to 12: requests
Each request has a
request_id, a method, path, status and duration. AWARNflags a slow query that took 1,240 ms.Line 13: an injection attempt
A user name containing a line break and a fake
INFOentry, logged with the line break escaped as\n, so it stays one line.Lines 14 to 21: a multi-line error and a retry
An
ERRORfollowed by a Java stack trace (the exception and threeatlines), then a retry and success, all sharingrequest_id=7f3a22.Lines 22 to 24: a job, UTF-8 and a server error
A scheduled cleanup job, a search for
cafélogged both URL-encoded and as UTF-8 text, then a500error.Lines 25 to 27: shutdown
A
SIGTERM, the connection pool closing, and a summary: 9 requests, 1 failed. Every timestamp has the+01:00offset.
All sample LOG files
Application log
sample-app.log · 2.8 KB (2,884 bytes)
27 lines from a fictional checkout service: ISO 8601 timestamps with offset, four levels, threads, logger names, request IDs, key=value fields, a masked password, an escaped injection attempt and a multi-line stack trace.
- Testing log viewers, highlighters and multi-line parsing
- Teaching what a log line contains
Nginx access log (Combined Log Format)
sample-nginx-access.log · 3.7 KB (3,805 bytes)
21 requests in the default
combinedformat: IPv4 and IPv6 clients from the documentation ranges, statuses 200, 201, 206, 301, 304, 401, 404 and 500, a crawler, scanner probes for/wp-login.phpand/.env, an authenticated user, and a User-Agent with quotes and a line break escaped by Nginx as\x22and\x0A.- Testing access-log parsers and analytics tools such as GoAccess
- Practising `awk`, `grep` and `sort` on web logs
JSON Lines log
sample-json-lines.log · 2.5 KB (2,520 bytes)
15 structured events, one compact JSON object per line, with UTC timestamps, nested objects, an array, a boolean, a stack trace and an injection attempt stored safely as
\ninside strings, and non-ASCII text (café crème,日本語).- Testing `jq`, log shippers and JSON Lines parsers
- Comparing structured and plain-text logging
Syslog messages (RFC 5424)
sample-syslog-rfc5424.log · 1.7 KB (1,743 bytes)
14 messages with priorities from 0 to 135, hosts given as names and as an IP address,
-for empty fields, the reservedtimeQuality,originandmetaelements, private@32473structured data with escaped\",\]and\\, and two messages whose UTF-8 text starts with a byte order mark, as RFC 5424 specifies.- Testing syslog parsers and collectors
- Checking structured-data escaping and BOM handling
IIS-style W3C extended log (CRLF)
sample-iis-w3c.log · 2.0 KB (2,070 bytes)
Windows line endings,
#Software,#Version,#Date,#Remarkand#Fieldsdirectives, then 10 requests with 15 space-separated fields in UTC, spaces in User-Agent strings written as+, and a domain user name.- Testing W3C log parsers and CRLF handling
- Field-mapping tests driven by a `#Fields` header
1 MB application log
sample-1mb.log · 1 MB (1,048,576 bytes)
10,188 application log lines over a fictional day, in the same layout as
sample-app.log, with LF line endings and exactly 1,048,576 bytes (1 MiB).- Upload limits and timeouts
- Log viewer, `grep` and parser performance
Ways to test with them
- Parsers: run each layout through your parser. Every line of
sample-nginx-access.logshould yield 9 fields, every line ofsample-json-lines.logone JSON object, andsample-app.log23 entries, because 4 of its 27 lines belong to a stack trace. - Escaping: the injection attempts in the app and JSON logs, and the escaped User-Agent in the Nginx log, should each stay one entry. A viewer that shows a separate "admin signed in" event has unescaped them.
- Encodings and line endings:
sample-iis-w3c.loguses CRLF,sample-syslog-rfc5424.loghas byte order marks in the middle of two lines, and the app and JSON logs contain UTF-8 text. None should produceÃor�. - Redaction: point a redaction tool at the samples; it should find the documentation IP addresses, the masked email
a***@example.comand thepassword=****field. - Upload limits:
sample-1mb.logis exactly 1,048,576 bytes, for testing a limit at the boundary.
Free to use for testing, teaching and demos, commercially or not, with no attribution needed. A link back to this page is always appreciated.
Put it online
Have a log file? Give it a link.
Drop a .log file on 99helpers and it gets its own web address. Anyone who opens the link reads it as plain text in their browser, which makes it easy to share with support or a colleague; remove personal data and secrets first.
Questions
LOG files, frequently asked
What is a .log file?
A plain-text record of events written by a program while it runs: errors, requests, sign-ins, steps of an installation. Usually one event per line, newest at the end.
How do I open a .log file?
Double-click it: Windows opens it in Notepad and a Mac in Console or TextEdit. For large logs, use less, tail or grep in a terminal, or a log viewer such as lnav or klogg.
Can I delete .log files?
Usually yes, if the program that wrote them isn't running and you don't need them for troubleshooting or an audit. For system and server logs, configure rotation instead of deleting by hand, and check your organisation's retention rules.
Why is my log file so big?
It's never rotated, or it's logging at DEBUG level. Set up rotation (logrotate on Linux) and raise the level to INFO or WARN in production.
What do .log.1 and .log.2.gz mean?
Rotated copies. .log.1 is the previous log, .log.2.gz the one before, compressed with gzip. Read compressed ones with zcat or zgrep.
How do I watch a log file live?
tail -f app.log on macOS and Linux, or Get-Content app.log -Wait in Windows PowerShell. New lines appear as the program writes them.
Where are the Windows event logs?
Not in .log files: Windows keeps them as binary .evtx files in C:\Windows\System32\winevt\Logs. Open them with Event Viewer.
Is it safe to share a log file?
Check it first. Logs often contain IP addresses, email addresses, user names and sometimes tokens or passwords. Replace them before posting a log publicly or attaching it to a bug report.
Related formats
Other file types explained
Keep going
Related
Sources
- RFC 5424: The Syslog Protocol
- Apache HTTP Server: log files (Combined Log Format, rotation, security)
- JSON Lines
- GDPR Recital 30: online identifiers
- CWE-117: Improper Output Neutralization for Logs
- logrotate manual page
Last reviewed 27 October 2026.