Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

--output FILE not in real time #6

Closed
setaur opened this issue Mar 11, 2021 · 5 comments
Closed

--output FILE not in real time #6

setaur opened this issue Mar 11, 2021 · 5 comments

Comments

@setaur
Copy link

setaur commented Mar 11, 2021

Hey I'm trying to use your tool to backtrack waking up disks in my ZFS pool.
When I run

# cd /mnt/magazyn #zfs mount
# fatrace -c

and in another terminal

# ls /mnt/magazyn

then immediately I get valid output in first terminal:

ls(26115): O /mnt/magazyn
ls(26115): R /mnt/magazyn
ls(26115): RC /mnt/magazyn

But when I try to redirect output to file using command

# cd /mnt/magazyn; fatrace -c -o /tmp/fatrace_output

(or fatrace -c > logfile or fatrace -c | tee logfile)
and in another terminal I start

# tail -f /tmp/fatrace_output

Accessing /mnt/magazyn, creating, delecting files - logfile stays empty. Only after stopping fatrace with CTRL-C all the missing content appears in the logfile.

It seems that this behavior only happens in case of ZFS mounts. Command started without "-c" saves a lot of logs into logfile in realtime, but I can't find any records from ZFS mounts.

My system: Debian 10 5.9.0-0.bpo.5-amd64
I tried fatrace from Debian Stable repository (0.13-2) and from this github. Result is the same.

@martinpitt martinpitt changed the title --output FILE not in real time for ZFS mounts --output FILE not in real time Mar 12, 2021
@martinpitt
Copy link
Owner

This is actually not specific to ZFS, I get this on ext4 as well. Regular stdout is line buffered, while outputting to a file uses much larger buffers. This is more efficient especially for large amounts of data, but prevents live tailing.

This is easy to fix, commit is coming. Thanks for the report!

@setaur
Copy link
Author

setaur commented Mar 15, 2021

Thank you for your fast response.
Actually I tested this new version of your program, but I still cannot use it for my purposes without non-trivial hacks.
I have a lot of mounts in my ZFS pool, which I am trying to track down. So I'm trying to create script to watch them all, by running fatrace on each mount and catch collective output - but I cannot. If I use -o FILE option, then I only can use this FILE once for only one mount. Another attempt leads to "Failed to open output file: File exists". I could just run

fatrace -c >> output_file & cd another/location; fatrace -c >> output_file

but then I don't have line buffering.

Ideally for me there should be extra '--line-buffered' option, just like in case of grep, for all outputs. Or to permit appending to existing file with '-o FILE' option. The latter would also allow for writing into created fifo.

@martinpitt
Copy link
Owner

But now "line buffered" is the default, why would you need an extra option for that?

@setaur
Copy link
Author

setaur commented Mar 15, 2021

fatrace -c >> output_file

still doesn't produce realtime output. In commit 06c83e0 you added setlinebuf (stdout);, but it's inside if (option_output) section, so it's working only with -o FILE option. But with that option I can only use one FILE per location. I want to spawn multiple instances of fatrace in multiple locations, all writing to one file. I cannot do this with -o FILE option, because it fails if FILE already exists.

After modifying code - moving line 595: setlinebuf (stdout); outside braces in example into line 598 - I can get desired program operation. fatrace -c >> output_file is now line-buffered and script like this can work:

#!/bin/bash

fatrace=/path/to/fatrace

finish() {
    [[ "$finished" ]] && exit
    finished=1
    pkill -P $$ fatrace
    rm "$fifo"
    exit
}
trap finish INT TERM EXIT

#fatrace_pids=()
Mountpoints=()
fifo=/tmp/"$(basename "$0").fifo"
mkfifo "$fifo"

while read mountpoint; do
    echo "# $mountpoint" >&2
    cd "$mountpoint" || continue
    Mountpoints+=("$mountpoint")
done < <(mount | grep '^magazyn' | awk '{print $3;}' )

echo '# start' >&2

for mountpoint in "${Mountpoints[@]}"; do
    cd "$mountpoint" || continue
    $fatrace --current-mount >> "$fifo" &
    echo "# fatrace in $mountpoint started" >&2
done 

echo -e '\n'

wait

echo "# finish"

All realtime output is concatenated into $fifo.

@martinpitt
Copy link
Owner

@setaur: Right, I was misled as this bug report talks about --output explicitly. But I see the point, this makes sense with output redirection as well. Done in commit e6e67bb

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants