How to Tail and Filter Logs in Real Time on Linux

When you reproduce a bug or restart a service, the most useful view is often the log scrolling live as it happens. You want to see each new line when it is written, but you may also need to hide routine entries so the warning or error that matters does not disappear in the noise.
Linux provides several ways to follow logs. Use tail -F for a plain log file, less +F when you need to pause and search, and journalctl -f for output stored in the systemd journal. This guide shows how to use each tool and filter the live stream.
Quick Reference
For printable quick references, see the tail , grep , less , and journalctl cheatsheets.
| Task | Command |
|---|---|
| Follow a file | tail -f /var/log/app.log |
| Follow and survive rotation | tail -F /var/log/app.log |
| Follow only newly appended lines | tail -n 0 -F /var/log/app.log |
| Show last N lines, then follow | tail -n 100 -f /var/log/app.log |
| Follow several files at once | tail -F /var/log/a.log /var/log/b.log |
| Follow, scroll, search, and filter | less +F /var/log/app.log |
| Follow a systemd unit | journalctl -f -u nginx |
| Follow errors and more severe entries | journalctl -f -p err |
| Filter file logs by text | tail -F app.log | grep -i error |
| Filter journal messages by text | journalctl -f -u nginx -g 'timeout|failed' |
Follow a File with tail -f
The tail command prints the end of a file, and the -f (--follow) option keeps reading as new data is appended. This is the quickest way to watch a plain-text log:
tail -f /var/log/nginx/access.logThe terminal shows the last 10 lines and then waits, adding each new request as it arrives. Press Ctrl+C to stop. To start with more context, specify the number of existing lines to show:
tail -n 100 -f /var/log/nginx/access.logIf you want to ignore existing entries and display only lines appended after the command starts, set the initial line count to zero:
tail -n 0 -f /var/log/nginx/access.logOne catch is log rotation. Plain -f follows the open file descriptor, so it can keep watching the old file after that file is renamed. On GNU tail, -F is equivalent to --follow=name --retry: it watches the path and keeps trying to reopen the file when it is replaced or temporarily unavailable.
tail -F /var/log/nginx/access.logYou can also watch more than one file in the same session. Pass several paths, and tail prints a ==> path <== header each time the output switches to a different file:
tail -F /var/log/nginx/access.log /var/log/nginx/error.logThose headers tell you which file produced the lines that follow, which matters when two logs use a similar format.
Use -F for a long-running session on a rotating log. The tail command
guide covers line counts, byte offsets, and other follow options.
Filter a Live Stream with grep
Pipe the followed output into grep to keep only matching lines. The following command ignores case, so it matches error, ERROR, and other capitalization variants:
tail -F /var/log/app.log | grep -i errorIn this two-command pipeline, grep writes directly to the terminal and normally displays each match immediately. If you send its output into another command, GNU grep switches to full buffering. Add --line-buffered before the next pipeline stage so matches continue moving one line at a time:
tail -F /var/log/app.log | grep --line-buffered -i error | awk '{ print $1, $2, $NF }'Here, grep flushes each match to awk, which prints the first two and last whitespace-separated fields. A later command can still have its own buffering rules, so check each stage if output remains delayed.
Use extended regular expressions to match several severity words in one pass:
tail -F /var/log/app.log | grep -Ei 'error|warning|critical'To hide a noisy health-check endpoint while keeping all other requests, invert the match with -v:
tail -F /var/log/nginx/access.log | grep -v '/health'The grep command guide covers fixed strings, regular expressions, and inverted matches in more detail.
Scroll and Search with less +F
tail -f shows new lines but does not let you inspect earlier entries without stopping the command. The less pager has its own follow mode and lets you switch between live output and normal navigation:
less +F /var/log/app.logPress Ctrl+C to pause following. You can then scroll with the arrow keys or search forward by typing /pattern and pressing Enter.
To hide nonmatching lines, type &pattern and press Enter. Enter & followed by Enter to clear the filter. Press uppercase F to return to follow mode; any active filter remains in effect while new lines arrive. The less command
guide covers navigation, searches, and display options.
Follow a Service with journalctl -f
On a systemd system, service output captured by systemd-journald is read with journalctl. Use -f to follow new journal entries and -u to limit them to one unit:
journalctl -f -u nginxThis follows entries associated with the nginx unit, including service lifecycle messages and output sent to the journal. Applications can also write dedicated files. If Nginx access requests are stored in /var/log/nginx/access.log, follow that file with tail -F instead.
Because journal entries contain structured fields, you can filter by priority. A single priority includes that level and all more severe levels, so err shows err, crit, alert, and emerg entries:
journalctl -f -u nginx -p errUse -g (--grep) to match a regular expression against the MESSAGE field while following:
journalctl -f -u nginx -g 'timeout|failed'To follow warnings and more severe entries from the current boot across all accessible units, combine -f, -p, and -b:
journalctl -f -b -p warningThe journalctl command guide covers time ranges, boot selection, unit filters, and journal fields.
Which Tool to Use
The log destination determines the first choice. Use tail -F for a rotating plain-text file, then pipe it through grep when you need text filtering. Use less +F when you expect to pause, scroll backward, search, or interactively hide nonmatching lines. Use journalctl -f when the messages are stored in the systemd journal and you want to filter by unit, priority, boot, or message text.
Troubleshooting
Permission denied when opening a log
Check the file permissions with ls -l /path/to/log. Run sudo tail -F /path/to/log only if your account is authorized to read that log. For the system journal, administrators can use sudo journalctl, while many distributions also grant journal access through groups such as adm or systemd-journal.
No new lines appear
Confirm that the application is still appending to the path you opened. If the file was rotated or recreated, restart with tail -F. Also remember that tail follows appended data; it does not report text rewritten in place earlier in the file.
journalctl -p err misses a message containing ERROR
The -p option checks the structured PRIORITY field, not words inside the message. If an application logs the word ERROR without assigning an error priority, use a text filter such as journalctl -f -u SERVICE -g 'error'.
Conclusion
Start with the unfiltered stream to confirm that you have the correct source, then add one filter at a time so you do not hide the event you are trying to diagnose. When a filter proves useful more than once, save it as a shell alias or a short script so the next incident starts from a view you already trust.
Tags
Linuxize Weekly Newsletter
A quick weekly roundup of new tutorials, news, and tips.
About the authors

Dejan Panovski
Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 800+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.
View author page