24

I'm looking for a simple method that will log file system operations. It should display the name of the file being accessed or modified.

I'm familiar with powertop, and it appears this works to an extent, in so much that it show the user files that were written to. Is there any other utilities that support this feature.

Some of my findings:

powertop: best for write access logging, but more focused on CPU activity
iotop: shows real time disk access by process, but not file name
lsof: shows the open files per process, but not real time file access
iostat: shows the real time I/O performance of disk/arrays but does not indicate file or process

1
  • This question itself is pretty much the best answer
    – Klesun
    Apr 5, 2021 at 18:17

5 Answers 5

19

So far iotop is the best overall solution. The following command gives you a real-time output of all the processes using the disk.

iotop -bktoqqq -d .5

where: -b     is batch mode
       -k     is kilobytes/s
       -t     adds timestamp
       -o     only show processes or threads actually doing I/O
       -qqq   removes output headers
       -d .5  updates every .5 seconds

Evenutaly you will notice that process will be accessing the disk. The simple way to investigate is to stop the process, and start it with strace. For example:

sudo strace -f nmbd -D

This will show you syscalls of the file system access.

Another option is inotify(7), where many distributions provide "inotify-tools" so you can watch a path via

inotifywait -r -mpath_you_want_to_watch

3
  • 1
    fanotify is a new filesystem notification framework in the Linux kernel (recently added around 2012). You may want to check that out. Tools and utilities that use it are still being written, so you may have to write one yourself, but it's much more robust than inotify, famin, or anything else you might've seen so far. Nov 2, 2012 at 20:37
  • 3
    A quick Google search for fanotify shows a tool called fatrace from here.
    – Thanh DK
    Apr 23, 2013 at 7:26
  • What is nmbd in the given strace command? Dec 12, 2014 at 14:27
12

Another option is http://linux.die.net/man/7/inotify where many distributions provide "inotify-tools" so you can watch a path via

inotifywait -r -m /<path you want to watch>
1
  • +1. « inotifywait efficiently waits for changes to files using Linux's inotify(7) interface. » Greatly helps fine-grain auditing by showing off any ACCESS and MODIFY <file> in the path monitored.
    – tuk0z
    Sep 24, 2016 at 9:35
6

I recently came across fatrace which uses fanotify. Works beautiful so I figured I would share. It does log all types of file operations including open/create/modify to stdout or optionally a file and you can even filter as to get only some types of operations. By default it monitors all mounts except the virtual ones. The author himself explains it well here.

1
  • it works beautifully!!
    – brauliobo
    Aug 13, 2023 at 18:03
2

For logging (rather than monitoring) you should consider using the Linux audit daemon introduced in kernel 2.6.

1
  • I couldn't get the PID watcher to work, so not very useful if you don't know what file to watch
    – cmcginty
    Dec 30, 2010 at 8:50
-3
#!/usr/bin/perl
use Cwd;
use File::Touch;
use File::Temp qw/tempfile/;
use Time::HiRes qw/sleep time alarm/;
use Term::ReadKey;
my ($wchar, $hchar, $wpixels, $hpixels) = GetTerminalSize();
if($hchar < 10) {print "please increase window size"; exit; }
my $mydir = getcwd;
my  ($fh, $tmpfile) = tempfile(UNLINK => 1);

while(1)
   {
   my $starttime = time;
   eval {
        local $SIG{ALRM} = sub { die "alarm\n" };
        alarm 0.4;
        $query = `find -neweraa $tmpfile 2>&1`; #change to mm for writes only
        touch($tmpfile);
        @files = split(/\n/,$query);
        alarm 0;
        };
   system('clear');
   foreach $file(@files) { $filecount{$file}++; }
   @sorted = sort {$filecount{$b} <=> $filecount{$a}} (keys %filecount);
   for ($x = 0;$x < $hchar-2; $x++) {print $filecount{$sorted[$x]}."\t".$sorted[$x]."\n";}
   my $endtime = time;
   my $length = ($endtime-$starttime);
   if ($length > 0.3) {print "program not designed for large trees, please use smaller tree.\n"; exit;}
   print "\n$length"."s\n"
   }
1
  • 5
    could you please update your answer with some details about how to use this code and what it will accomplish along with side-effects and limitations?
    – Jeremy W
    Apr 4, 2012 at 2:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .