How do I log file system read/writes by filename in Linux?

17

13

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

cmcginty

Posted 2010-12-29T01:26:34.700

Reputation: 2 249

Answers

17

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

cmcginty

Posted 2010-12-29T01:26:34.700

Reputation: 2 249

What is nmbd in the given strace command? – dragosrsupercool – 2014-12-12T14:27:39.270

1fanotify 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. – allquixotic – 2012-11-02T20:37:17.033

3

A quick Google search for fanotify shows a tool called fatrace from here.

– Thanh DK – 2013-04-23T07:26:25.057

9

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>

x29a

Posted 2010-12-29T01:26:34.700

Reputation: 393

+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 – 2016-09-24T09:35:36.650

3

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.

turbofan

Posted 2010-12-29T01:26:34.700

Reputation: 151

2

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

RedGrittyBrick

Posted 2010-12-29T01:26:34.700

Reputation: 70 632

I couldn't get the PID watcher to work, so not very useful if you don't know what file to watch – cmcginty – 2010-12-30T08:50:24.037

-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"
   }

Jon

Posted 2010-12-29T01:26:34.700

Reputation: 1

5could 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 – 2012-04-04T02:46:22.277