Streams
When defining a stream, you should use a command that follows new writes on logs and print them as they arise.
The command should not print older lines.
For example, tail -f /var/log/nginx/access.log
will print the last 10 lines first, then follow appended lines.
This a problem because restarting reaction will result in the same 10 logs potentially printed multiple times.
Examples of good commands:
Plain file
Follow logs of one file
tail -fn0 <FILE>
Follow multiple files as one stream. It will print some extra lines. Check them and see if they will match your regexes.
tail -fn0 <FILE1> <FILE2>
Follow multiple files as one stream.
This alternative pattern can work for any command.
sh
will launch multiple commands in background, then until all of them exit.
sh -c 'tail -fn0 <FILE1> & tail -fn0 <FILE2> & wait'
⚠️ tail -f
and logrotate
When files are rotated, tail -f
may stay on the rotated file and miss new inputs.
Using tail -F
instead permits to listen on a specific path, even if the actual file under it changes.
See its manual for more details.
SystemD / JournalD
Logs of one systemd unit
journalctl -fn0 -u <UNIT>
Logs of multiple systemd units
journalctl -fn0 -u <UNIT> -u <UNIT>
Docker
Logs of one container
docker logs -fn0 <CONTAINER>
Logs of all the services of a docker compose file
docker compose --project-directory /path/to/directory logs -fn0
⚠️
docker logs
print program'sstderr
tostderr
as well, andreaction
only readsstdout
. So we might need to capturestdout
andstderr
depending on how your container does log:
cmd: ['sh', '-c', 'exec docker logs -fn0 <container> 2>&1']
There is virtually no overhead, as the sh
process replaces itself with the docker logs
command.
In reaction v2, stderr is read as well, so this trick is no longer needed.