Skip to main content

An adapter to Linux kernel support for inotify directory-watching.

Project description

Overview

inotify functionality is available from the Linux kernel and allows you to register one or more directories for watching, and to simply block and wait for notification events. This is obviously far more efficient than polling one or more directories to determine if anything has changed. This is available in the Linux kernel as of version 2.6 .

We’ve designed this library to act as a generator. All you have to do is loop, and you’ll see one event at a time and block in-between. After each cycle (all notified events were processed, or no events were received), you’ll get a None. You may use this as an opportunity to perform other tasks, if your application is being primarily driven by inotify events. By default, we’ll only block for one-second on queries to the kernel. This may be set to something else by passing a seconds-value into the constructor as block_duration_s.

Example

Code:

import logging

import inotify.adapters

_DEFAULT_LOG_FORMAT = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'

_LOGGER = logging.getLogger(__name__)

def _configure_logging():
    _LOGGER.setLevel(logging.DEBUG)

    ch = logging.StreamHandler()

    formatter = logging.Formatter(_DEFAULT_LOG_FORMAT)
    ch.setFormatter(formatter)

    _LOGGER.addHandler(ch)

def _main():
    i = inotify.adapters.Inotify()

    i.add_watch('/tmp')

    try:
        for event in i.event_gen():
            if event is not None:
                (header, type_names, filename) = event
                _LOGGER.info("WD=(%d) MASK=(%d) COOKIE=(%d) LEN=(%d) MASK->NAMES=%s "
                             "FILENAME=[%s]",
                             header.wd, header.mask, header.cookie, header.len, type_names,
                             filename)
    finally:
        i.remove_watch('/tmp')

if __name__ == '__main__':
    _configure_logging()
    _main()

You may also choose to pass the list of directories to watch via the paths parameter of the constructor. This would work best in situations where your list of paths is static. Also, the remove_watch() call is included in the example, but is not strictly necessary. The inotify resources is cleaned-up, which would clean-up any inotify-internal watch resources as well.

Directory operations to raise events:

$ touch /tmp/aa
$ rm /tmp/aa
$ mkdir /tmp/dir1
$ rmdir /tmp/dir1

Screen output from the code, above:

2015-04-24 05:02:06,667 - __main__ - INFO - WD=(1) MASK=(256) COOKIE=(0) LEN=(16) MASK->NAMES=['IN_CREATE'] FILENAME=[aa]
2015-04-24 05:02:06,667 - __main__ - INFO - WD=(1) MASK=(32) COOKIE=(0) LEN=(16) MASK->NAMES=['IN_OPEN'] FILENAME=[aa]
2015-04-24 05:02:06,667 - __main__ - INFO - WD=(1) MASK=(4) COOKIE=(0) LEN=(16) MASK->NAMES=['IN_ATTRIB'] FILENAME=[aa]
2015-04-24 05:02:06,667 - __main__ - INFO - WD=(1) MASK=(8) COOKIE=(0) LEN=(16) MASK->NAMES=['IN_CLOSE_WRITE'] FILENAME=[aa]
2015-04-24 05:02:17,412 - __main__ - INFO - WD=(1) MASK=(512) COOKIE=(0) LEN=(16) MASK->NAMES=['IN_DELETE'] FILENAME=[aa]
2015-04-24 05:02:22,884 - __main__ - INFO - WD=(1) MASK=(1073742080) COOKIE=(0) LEN=(16) MASK->NAMES=['IN_ISDIR', 'IN_CREATE'] FILENAME=[dir1]
2015-04-24 05:02:25,948 - __main__ - INFO - WD=(1) MASK=(1073742336) COOKIE=(0) LEN=(16) MASK->NAMES=['IN_ISDIR', 'IN_DELETE'] FILENAME=[dir1]

Notes

  • The design of inotify kernel-functionality is such that recursive monitoring is left as an exercise for the developer, and is not as trivial as the standard use-case.
  • Due to the GIL locking considerations of Python (or any VM-based language), it is strongly recommended that, if you need to be performing other tasks while you’re concurrently watching directories, you use multiprocessing to put the directory-watching in a process of it’s own and feed information back [via queue/pipe/etc..]. This is especially true whenever your application is blocking on kernel functionality. Python’s VM will remain locked and all other threads in your application will cease to function until something raises an event in the directories that are beign watched.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for inotify, version 0.2.0
Filename, size File type Python version Upload date Hashes
Filename, size inotify-0.2.0-py2-none-any.whl (10.7 kB) File type Wheel Python version 2.7 Upload date Hashes View
Filename, size inotify-0.2.0.tar.gz (5.6 kB) File type Source Python version None Upload date Hashes View

Supported by

AWS AWS Cloud computing Datadog Datadog Monitoring DigiCert DigiCert EV certificate Facebook / Instagram Facebook / Instagram PSF Sponsor Fastly Fastly CDN Google Google Object Storage and Download Analytics Pingdom Pingdom Monitoring Salesforce Salesforce PSF Sponsor Sentry Sentry Error logging StatusPage StatusPage Status page