#1
  1. PHP Wacko
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Sep 2003
    Location
    Washington DC
    Posts
    1,310
    Rep Power
    337

    How to monitor a file for changes?


    I am trying to write a script that will monitor a file for changes, and then send an email with the changes. I am unsure on how to proceed. Here is some meta-code of what I am trying to do:
    Code:
    while 1:
        #watch for changes in file
        
        #if change, read line of file, send email
    reading the file and sending an email is easy, I am just not sure how I would watch for the file to be changed.
  2. #2
  3. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,648
    Rep Power
    4248
    Check the file's date/time perhaps?
    Up the Irons
    What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
    "Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
    Down with Sharon Osbourne

    "I wouldn't hire a butcher to fix my car. I also wouldn't hire a marketing firm to build my website." - Nilpo
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2001
    Location
    Houston, TX
    Posts
    383
    Rep Power
    14
    You want the stat() command in the os module:

    stat(path)
    Perform a stat() system call on the given path. The return value is an object whose attributes correspond to the members of the stat structure, namely: st_mode (protection bits), st_ino (inode number), st_dev (device), st_nlink (number of hard links), st_uid (user ID of owner), st_gid (group ID of owner), st_size (size of file, in bytes), st_atime (time of most recent access), st_mtime (time of most recent content modification), st_ctime (time of most recent content modification or metadata change).
    My guess is that you probably want one of those.
  6. #4
  7. Hello World :)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2003
    Location
    Hull, UK
    Posts
    2,537
    Rep Power
    69
    I have to agree with scorp, you'll need to keep an eye on the last modifide time for the file, you can get this using the os.path.getmtime() function.. i'd sugest you take a look at the os.path module for more details.

    If your on *ix you could use cron to run the script every 5 min or so, if not your gonna have to loop, it may not be the most eligant way to do things but it work's

    You can then use the smtplib module to email the file as an attachment (or in the emails body) to wherever you need to. Pretty cool

    If you need any more help i'd be happy to lend a hand

    Have fun,
    Mark.
    programming language development: www.netytan.com Hula

  8. #5
  9. PHP Wacko
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Sep 2003
    Location
    Washington DC
    Posts
    1,310
    Rep Power
    337
    Thanks, stat() was all I need to get going. Right now the program sets itself up as a daemon, then I have a loop that keeps the script going. I use time.sleep(5) so it checks the file's modification time every 5 seconds.

    I'll put a link to the first version of a completed script when I am done, if anyone is interested.
  10. #6
  11. Hello World :)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2003
    Location
    Hull, UK
    Posts
    2,537
    Rep Power
    69
    You got my interest! Let us know when you done or if you need anything else..

    Mark.
    programming language development: www.netytan.com Hula

  12. #7
  13. onCsdfeu
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Location
    Canada
    Posts
    100
    Rep Power
    12
    I'd be interested, too, so feel free to post it as soon as you're done.
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Posts
    133
    Rep Power
    12
    This script, by A.M. Kuchling, might be of interest.
  16. #9
  17. PHP Wacko
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Sep 2003
    Location
    Washington DC
    Posts
    1,310
    Rep Power
    337

    1st draft


    Here is my first version of the log watching script. Right now, it is set up to monitor my php error log and email me on php parse or fatal error. It isn't very configurable yet, but if anyone has ideas for making it better, send them my way. This is mainly an excersise for learning python syntax, so I'm sure the script could be improved.
    Code:
    #!/usr/local/bin/python2.2
    def daemonize():
    	""" Become a daemon"""
    	import os,sys
    	if os.fork(): os._exit(0)
    	os.setsid()
    	sys.stdin  = sys.__stdin__  = open('/dev/null','r')
    	sys.stdout = sys.__stdout__ = open('/dev/null','w')
    	sys.stdout = sys.__stderr__ = os.dup(sys.stdout.fileno())
    
    def daemonize_log_watcher():
    	import time, os, re, smtplib
    
    	""" Configs.  Should  probably move these to a config file?  or take args? """
    	log_filename = 	'/var/log/php_errors.log'
    	search_keywords = ['PHP Parse error', 'PHP Fatal error']
    	mailserver = 'localhost'
    	From = 'py_log_watch@example.com'
    	To = 'email@example.com'
    	Subj = 'Log Watcher Alert'
    	
    	""" Open File, get last mod time """
    	file = open(log_filename, 'r')
    	watcher = os.stat(log_filename)
    	this_modified = last_modified = watcher.st_mtime
    	
    	""" Go to the end of the file """
    	file.seek(0,2)	
    	
    	""" Main Loop """
    	while 1:
    		if this_modified > last_modified:
    			last_modified = this_modified
    			""" File was modified, so read new lines, look for error keywords """
    			while 1:
    				line = file.readline()
    				if not line: break	
    				for keyword in search_keywords:
    					if re.search(keyword, line):
    						text = ('From: %s\nTo: %s\nSubject: %s\n' % (From, To, Subj)) + line
    						server = smtplib.SMTP(mailserver)
    						failed = server.sendmail(From, To, text)
    						server.quit()
    							
    		
    		watcher = os.stat(log_filename)
    		this_modified = watcher.st_mtime
    		time.sleep(1)
    
    if __name__=='__main__':
    	daemonize()
    	daemonize_log_watcher()
    Last edited by Stew_McGruff; September 23rd, 2003 at 06:05 PM.

IMN logo majestic logo threadwatch logo seochat tools logo