As a software developer, I cannot avoid log files. Application servers and LAMP machines are always around the corner waiting for me, so I must accept log files and do my best.

There are two kinds of log files I work with:

  • static: the server wrote the content and never touched the file again
  • dynamic: the server keeps appending content as the monitored process continues

The log files could be on my hard disk or located on a remote machine. During my workflow, a “remote machine” can also be a Docker container.

I leave the math to you, but it should be clear that different combinations arise. Luckily, with Emacs everything goes smoothly and I can move seamlessly across any scenario.

When it comes to static files there are no surprises. If the log file is local, inspecting it with counsel-grep-or-swiper is pretty much all I need. Since I rarely need to modify a log file, I usually enable read-only-mode with C-x C-q to prevent accidental edits. For a remote static file, the same easily applies thanks to TRAMP.

Things get more interesting with dynamic logs. On local files, with auto-revert-mode I can see the changes in the buffer as soon as the underlying file changes. If I want something fancier, auto-revert-tail-mode behaves like the good old tail -f. Dynamic remote logs, however, require a different approach. Activating auto-revert-mode is not enough, I also need to set auto-revert-remote-files to t for the desired behaviour.

What if years of tail -f made you totally indifferent to such niceties? You can follow Michael Albinus suggestion and use dired-do-shell-command in Dired.

Actually, you can even improve a little on his tip. Leave the ending & out, and go straight with dired-do-async-shell-command which in Dired is aptly bound to &. Refer to the manual for further details: Shell Commands in Dired.