Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!


Click here to return to the '10.4: Monitor file system events in real time' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
10.4: Monitor file system events in real time
Authored by: grasshoppermouse on Aug 20, '06 12:02:31PM
The command line tools linked in the hint all log events as they happen. The disadvantage of that is that filesystem activity by several processes are all mixed up. Using Garion's Python bindings, mentioned above, I whipped up a little script that sorts the file system events by PID. This makes it easier to examine filesystem changes caused by a particular app. To use it, you'll need to copy the file:
fsevents.so
from the bindings module, linked above, into:
/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/site-packages
(You can't do a normal Python install unless you have pyrex installed.) Then simply paste the following code into a text file, and save it in:
/usr/local/bin
and
$ chmod +x scriptname
Here's the script (you can name it whatever you want):

#! /usr/bin/python

# Raw, mostly untested code. Use at your own risk.

import fsevents, os, time

eventdict = {}

def deleteHandler(o):
    addEvent(o.pid, o.vnode, 'deleted')

def createHandler(o):
    addEvent(o.pid, o.vnode, 'created')
    
def modifiedHandler(o):
    addEvent(o.pid, o.vnode, 'modded')

def dirCreatedHandler(o):
    addEvent(o.pid, o.vnode, 'new dir')

def renamedHandler(o):
    addEvent(o.pid, o.string[0], 'mv from')
    addEvent(o.pid, o.string[1], 'mv to')

def addEvent(pid, pth, event):
    if pid not in eventdict: eventdict[pid] = {'name':getprocessname(pid), 'events':[], 'paths':[], 'time':[]}
    eventdict[pid]['events'] += [event]
    eventdict[pid]['paths']  += [str(pth)]
    eventdict[pid]['time']   += [time.strftime('%X %x')]

def getprocessname(pid):
    try:
        # Get the process name
        return os.popen("ps -p " + str(pid)).readlines()[1].split('/')[-1].split(' -')[0].strip()
    except:
        return '??'

def outputLog():
    for k in eventdict.keys():
        print
        print eventdict[k]['name'], k
        for i, e in enumerate(eventdict[k]['events']):
            print eventdict[k]['time'][i], e.ljust(7), eventdict[k]['paths'][i]

x = fsevents.Scanner()
x.setEventHandler( fsevents.FSE_DELETE, deleteHandler )
x.setEventHandler( fsevents.FSE_CREATE_FILE, createHandler )
x.setEventHandler( fsevents.FSE_CONTENT_MODIFIED, modifiedHandler )
x.setEventHandler( fsevents.FSE_CREATE_DIR, dirCreatedHandler )
x.setEventHandler( fsevents.FSE_RENAME, renamedHandler )
x.startScanning()

print "Logging..."
while 1:
    try:
        time.sleep(.5)
    except:
        x.stopScanning()
        outputLog()
        break
To use the script, type
$ sudo scriptname
in the terminal, launch your installer, or whatever. When you're done, terminate with ctrl-c, and all filesystem events recorded while the script was running will be output, sorted by process id.

[ Reply to This | # ]