A ticket lands Monday morning: checkout errors spiked Saturday around 02:00. You tail the live access.log and see nothing but clean traffic — because Apache handed Saturday to logrotate days ago. The evidence still exists; it just lives in a different file now.
On a schedule, logrotate shifts access.log to access.log.1, compresses older files to .gz, and deletes them once the retention count runs out. Your schedule and retention are configured here:
$ cat /etc/logrotate.d/apache2 # Debian, Ubuntu
$ cat /etc/logrotate.d/httpd # RHEL, CentOS, Fedora
On this box, the family looks like:
$ ls -lh /var/log/apache2/access.log*
-rw-r----- 1 root adm 4.2M Oct 26 09:41 access.log
-rw-r----- 1 root adm 15M Oct 26 06:25 access.log.1
-rw-r----- 1 root adm 3.1M Oct 19 06:25 access.log.2.gz
-rw-r----- 1 root adm 3.0M Oct 12 06:25 access.log.3.gz
Saturday the 25th falls inside access.log.1 — still plain text, so the drill is familiar:
$ grep '25/Oct/2026:02:' /var/log/apache2/access.log.1 | grep -c ' 500 '
214
Cross one more rotation boundary and the files are compressed — grepbecomes zgrep:
$ zgrep '18/Oct/2026:02:' /var/log/apache2/access.log.2.gz
One caveat: logrotate's retention count is a hard limit. If that ticket had arrived two weeks later, the Saturday evidence would already be deleted.
In Grep Badger, each log opens in its own tab — access.log andaccess.log.1 in the same window, the same search in each tab, and the timeline a click away. The older .gz archives still need a quickgunzip first — one command, and they open like any other file.