This article provides an introduction to Pyinotify’s features, how to install it, and examples of how to use it.
Review the previous article: Can you really use a search engine?
features
Pyinotify is a Python module that monitors file system changes. Pyinotify is based on a Linux kernel feature called inotify. Inotify is an event-driven notifier that exports system events from kernel to user mode through system calls. Pyinotify binds these system calls and provides a set of interface implementations on top of them that provide a generic and abstract way to operate on these functions.
The installation
Install the Pyinotify module using Python’s PIP tool.
$ pip install pyinotify
Copy the code
Quick start
Once you have Pyinotify installed, you can use the following examples to quickly monitor specific file or directory changes using Pyinotify. If you specify a directory, Pyinotify will listen for all files in that directory, but not subdirectories.
$ python -m pyinotify /tmp
Copy the code
Let’s do something with the/TMP directory:
$ touch test_file
$ echo "echo test" > test_file
$ chmod u+x test_file
$ rm -f test_file
Copy the code
Pyinotify listens for events generated by commands while manipulating them:
-- touch test_file -- <Event dir=False mask=0x100 maskname=IN_CREATE name=test_file path=/tmp pathname=/tmp/test_file wd=1> <Event dir=False mask=0x20 maskname=IN_OPEN name=test_file path=/tmp pathname=/tmp/test_file wd=1> <Event dir=False mask=0x4 maskname=IN_ATTRIB name=test_file path=/tmp pathname=/tmp/test_file wd=1> <Event dir=False mask=0x8 maskname=IN_CLOSE_WRITE name=test_file path=/tmp pathname=/tmp/test_file wd=1> -- echo "echo test" > test_file -- <Event dir=False mask=0x2 maskname=IN_MODIFY name=test_file path=/tmp pathname=/tmp/test_file wd=1> <Event dir=False mask=0x20 maskname=IN_OPEN name=test_file path=/tmp pathname=/tmp/test_file wd=1> <Event dir=False mask=0x2 maskname=IN_MODIFY name=test_file path=/tmp pathname=/tmp/test_file wd=1> <Event dir=False mask=0x8 maskname=IN_CLOSE_WRITE name=test_file path=/tmp pathname=/tmp/test_file wd=1> -- chmod u+x test_file -- <Event dir=False mask=0x4 maskname=IN_ATTRIB name=test_file path=/tmp pathname=/tmp/test_file wd=1> -- rm -f test_file -- <Event dir=False mask=0x200 maskname=IN_DELETE name=test_file path=/tmp pathname=/tmp/test_file wd=1>
Copy the code
It’s worth noting that Pyinotify by default listens for all events generated by the system.
The default event field reads as follows:
The field names | meaning |
---|---|
dir | Whether the object generating the event is a directory |
mask | Pyinotify has predefined event values for each event |
maskname | Name of the event corresponding to the event value |
name | The name of the object that generated the event |
path | Pyinotify listens for events |
pathname | Generates the absolute path to the event object |
wd | The resource descriptor that the Linux Kernel inotify listens on |
Pyinotify event list
The name of the event | meaning |
---|---|
IN_ACCESS | File accessed |
IN_ATTRIB | The file properties are changed |
IN_CLOSE_NOWRITE | Open and close the file in non-write mode |
IN_CLOSE_WRITE | Open and close the file in write mode |
IN_CREATE | A file or directory is created |
IN_DELETE | A file or directory is deleted |
IN_DELETE_SELF | The monitored file or directory is deleted (the monitored folder itself is deleted) |
IN_DONT_FOLLOW |
Not listening for symlinks (since kernel 2.6.15) |
IN_IGNORED | Inotify_rm_watch: the file is deleted or the file system is unmounted |
IN_ISDIR | The event is a directory |
IN_MASK_ADD | Update the MASK to the monitored pathnane |
IN_MODIFY | The file is modified. |
IN_MOVE_SELF | Monitored file or directory movement |
IN_MOVED_FROM | Files are moved out of monitored directories |
IN_MOVED_TO | Files are moved to the monitored directory |
IN_ONLYDIR | Only directories are monitored (since kernel 2.6.15) |
IN_OPEN | File opened |
IN_Q_OVERFLOW | Event Queue Overflow |
IN_UNMOUNT | The file system is unmounted |
Use the sample
With an understanding of Pyinotify and the system events it supports, we can override Pyinotify’s event methods to output events in a specified format.
code:
# -*- coding: utf-8 -*-import pyinotifyclass MyEvent(pyinotify.ProcessEvent):def process_IN_ACCESS(self, e):print("ACCESS:", e.pathname)def process_IN_ATTRIB(self, e):print("CHANGE ATTR:", e.pathname)def process_IN_MODIFY(self, e):print("MODIFY:", e.pathname)def process_IN_CREATE(self, e):print("CREATE:", e.pathname)def process_IN_DELETE(self, e):print("DELETE:", e.pathname)def process_IN_OPEN(self, e):print("OPEN:", e.pathname)def process_IN_CLOSE_WRITE(self, e):print("CLOSE:", e.pathname)if __name__ == "__main__":
watcher = pyinotify.WatchManager()
watcher.add_watch('/tmp', pyinotify.ALL_EVENTS, auto_add=True, rec=True)
myEvent = MyEvent()
notifier = pyinotify.Notifier(watcher, myEvent)
notifier.loop()
Copy the code
After running the sample code, let’s do the/TMP directory again:
$ touch test_file
$ echo "echo test" > test_file
$ chmod u+x test_file
$ rm -f test_file
Copy the code
Meanwhile, Pyinotify outputs the event as we expect:
-- touch test_file --
CREATE: /tmp/test_file
OPEN: /tmp/test_file
CHANGE ATTR: /tmp/test_file
CLOSE: /tmp/test_file
-- echo "echo test" > test_file --
MODIFY: /tmp/test_file
OPEN: /tmp/test_file
MODIFY: /tmp/test_file
CLOSE: /tmp/test_file
-- chmod u+x test_file --
CHANGE ATTR: /tmp/test_file
-- rm -f test_file --
DELETE: /tmp/test_file
Copy the code
The above sample code listens for all events. If you want to listen for some events, modify the add_watch parameter section:
mask = pyinotify.IN_CREATE | pyinotify.IN_DELETE
watcher.add_watch('/tmp', mask, auto_add=True, rec=True)
Copy the code
You can add more event methods and monitor more system critical directories.
conclusion
There are many similar checking tools available under Unix/Linux, such as Tripwire, Afick, etc. Such a tool configuration is relatively simple to use, but it does not redefine events generated by the system, and event reports need to be output by mail. Pyinotify can be easily developed and used based on usage requirements. Its advantage is that it can be easily integrated into various systems, and the event data generated by the system can be slightly sorted and pushed to ELK, OpenFalcon and other platforms for visual display and alarm.
See the official use case for more features of Pyinotify:
https://github.com/seb-m/pyinotify/wiki/List-of-Examples