Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

CORE::GLOBAL::* for auditing which files are read and written?

by tim.bunce (Scribe)
on Nov 06, 2008 at 17:28 UTC ( [id://722050]=perlquestion: print w/replies, xml ) Need Help??

tim.bunce has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to understand the behaviour of several big perl apps that use many custom modules. They read and write lots of files in a directory tree.

I'd like to be able to get a list of which files were read or written by the process.

I was hoping there would be a handy module on CPAN which would override CORE::GLOBAL::open (and symlink, rename, etc. etc.) to keep a record of the calls and parameters.

I couldn't see one. Is there one I'm missing?

  • Comment on CORE::GLOBAL::* for auditing which files are read and written?

Replies are listed 'Best First'.
Re: CORE::GLOBAL::* for auditing which files are read and written?
by moritz (Cardinal) on Nov 06, 2008 at 17:36 UTC
    I know of no Perl solution, but in general you can (ab)use strace on most Unix systems, DTrace on Solaris, FreeBSD and MacOS X and FileMon on Windows.

    There's a DTrace patch for perl floating around somewhere (you'll find a link to it in the p5p archives) that enables dtracing perl code (and not just the perl interpreter), I don't know if that's needed for the dtrace approach.

      Shouldn't; I believe that was for letting dtrace see into what perl is doing (so you'd be able to monitor sub entry/exit and what not at the perl level similar to how you can watch system calls at the kernel level). This snippet from a dtrace FAQ might even be enough:

      dtrace -n 'syscall::open*:entry { printf("%s %s",execname,copyinstr(ar +g0)); }'

      I think last I looked there were some good dtrace intros at opensolaris.org if you want to extend or tweak that to show different stuff.

      Update: And as to the original question Devel::Trace might also be of use (although for serious programs it'd be a boatload of output).

      The cake is a lie.
      The cake is a lie.
      The cake is a lie.

Re: CORE::GLOBAL::* for auditing which files are read and written?
by ig (Vicar) on Nov 06, 2008 at 21:27 UTC

    Operating system audit tools might be sufficient if all you want is a list of files accessed.

Re: CORE::GLOBAL::* for auditing which files are read and written?
by salva (Canon) on Nov 07, 2008 at 11:11 UTC
    It can not be done that way, at least not in a completely shameless manner.

    The current support for prototypes in perl 5 has some misfeatures that make impossible to replace a good number of builtins without limiting how they can be used (stat, truncate, etc.).

    And the file test operators (i.e. -f), can not be overrided at all.

    Maybe playing with the runops loop... thinking about new features for Devel::NYTProf?

      I thought the prototype issue had been resolved (in relation to getting autodie to work).

      "thinking about new features for Devel::NYTProf?" - no, this is unrelated. Though I am thinking of adding an option to NYTProf to make builtins get treated as calls to xsubs.

Re: CORE::GLOBAL::* for auditing which files are read and written?
by BrowserUk (Patriarch) on Nov 08, 2008 at 01:18 UTC
Re: CORE::GLOBAL::* for auditing which files are read and written?
by alexlc (Beadle) on Nov 11, 2008 at 04:22 UTC
    Tim:


    Per the perldoc:
    http://perldoc.perl.org/CORE.html
    ... you can globally override CORE::GLOBAL::open with your own function.

    It was a bit harder to do than I though though...

    BEGIN { *CORE::GLOBAL::open = sub (*;$@) { ($package, $filename, $line) = caller(); print "LOGGING: intercepted `open` call from ( package: '$package' +, file: '$filename', line: '$line' ) with args: '??', ".join(", ",map +{ "'$_'" } @_) . "\n"; if(defined($_[0])) { use Symbol qw(); my $handle = Symbol::qualify($_[0],(caller)[0]); no strict 'refs'; if(@_ == 1) { return CORE::open($handle); } elsif(@_ == 2) { return CORE::open($handle, $_[1]); } else { return CORE::open($handle, $_[1], @_[2..$#_]); } } else { if(@_ == 1) { return CORE::open($_[0]); } elsif(@_ == 2) { return CORE::open($_[0], $_[1]); } else { return CORE::open($_[0], $_[1], @_[2..$#_]); } } }; } open(my $fh, "<", ".bashrc") or die "unable to use hacked up open func +tion: $!"; my $top = <$fh>; print $top;

    Which returns:
    LOGGING: intercepted `open` call from ( package: 'main', file: './core +over.pl', line: '34' ) with args: '??', '', '<', '.bashrc' # ~/.bashrc: executed by bash(1) for non-login shells.
    Note: i had done this before, but couldn't quite remember how to make it work with open($fh ..) instead of open(FH ..), so perl.com helped me out:
    http://www.perl.com/pub/a/2002/06/11/threads.html?page=2
    -- AlexLC

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://722050]
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (5)
As of 2024-04-19 21:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found