From: lionel Date: Fri, 22 Jan 2016 12:50:20 +0000 (+0100) Subject: Added : inotify survey of /tmp (only remove working ...) X-Git-Url: http://gitweb.enneade.fdn.org/?a=commitdiff_plain;h=5eaffeae113e39ba135bb9e184d96a9873213df3;p=horusd.git Added : inotify survey of /tmp (only remove working ...) --- diff --git a/horusd.py b/horusd.py index 56e7e44..8f794bd 100755 --- a/horusd.py +++ b/horusd.py @@ -4,11 +4,14 @@ import logging # Logs import time # sleep import string # split strings -#import python-daemon +import os,select from daemon import runner # daemonization -#from multiprocessing import Process +from inotifyx import binding +from inotifyx.distinfo import version as __version__ + +from multiprocessing import Process #import subprocess #import shlex @@ -21,36 +24,146 @@ class App(): def __init__(self): self.stdin_path = "/dev/null" - self.stdout_path = "/home/lionel/work/python/horusd/stdout.log" - self.stderr_path = "/home/lionel/work/python/horusd/stderr.log" - self.pidfile_path = "/home/lionel/work/python/horusd/horusd.pid" + self.stdout_path = "/home/lionel/work/python/horusd/log/stdout.log" + self.stderr_path = "/home/lionel/work/python/horusd/log/stderr.log" + self.pidfile_path = "/home/lionel/work/python/horusd/pid/horusd.pid" self.pidfile_timeout = 5 def run(self): - if __name__ == '__main__': -# All functions definitions took place above +# We must put all functions before the 'if __name__ blabla' - logger.info("horusd started") +# The inotify class : + class InotifyEvent(object): + ''' + InotifyEvent(wd, mask, cookie, name) + A representation of the inotify_event structure. See the inotify + documentation for a description of these fields. + ''' + + wd = None + mask = None + cookie = None + name = None + + def __init__(self, wd, mask, cookie, name): + self.wd = wd + self.mask = mask + self.cookie = cookie + self.name = name + + def __str__(self): + return '%s: %s' % (self.wd, self.get_mask_description()) + + def __repr__(self): + return '%s(%s, %s, %s, %s)' % ( + self.__class__.__name__, + repr(self.wd), + repr(self.mask), + repr(self.cookie), + repr(self.name), + ) + + def get_mask_description(self): + ''' + Return an ASCII string describing the mask field in terms of + bitwise-or'd IN_* constants, or 0. The result is valid Python code + that could be eval'd to get the value of the mask field. In other + words, for a given event: + + >>> from inotifyx import * + >>> assert (event.mask == eval(event.get_mask_description())) + ''' + + parts = [] + for name, value in constants.items(): + if self.mask & value: + parts.append(name) + if parts: + return '|'.join(parts) + return '0' + + def get_events(fd, *args): + ''' + get_events(fd[, timeout]) + + Return a list of InotifyEvent instances representing events read from + inotify. If timeout is None, this will block forever until at least one + event can be read. Otherwise, timeout should be an integer or float + specifying a timeout in seconds. If get_events times out waiting for + events, an empty list will be returned. If timeout is zero, get_events + will not block. + ''' + return [ + InotifyEvent(wd, mask, cookie, name) + for wd, mask, cookie, name in binding.get_events(fd, *args) + ] -## Begin the infinit loop by polling signals values - loop_counter = 0 + def heartbeat(min): + seconds = int(min) * 60 while True: - time.sleep(2) - loop_counter=loop_counter+1 -# Every 300 loops (around 600s/10min on normal conditions), -# we write informations to the log file and verify power unit keep alive. - if (loop_counter) == 3: - logger.info("Still Alive.") - loop_counter = 0 + logger.info("HB : alive") + time.sleep(seconds) + return False +# All functions definitions took place above + if __name__ == '__main__': + logger.info("horusd started") + + ''' + Launching the heartbeat function + ''' + p = Process(target=heartbeat, args=(2,)) + p.start() + heartbeat_pid = p.pid + logger.info("heartbeat loop launched (pid " + str(heartbeat_pid) + ")") + + ''' + Preparing main loop + ''' + constants = {} + + for name in dir(binding): + if name.startswith('IN_CREATE') or name.startswith('IN_DELETE'): + globals()[name] = constants[name] = getattr(binding, name) + + init = binding.init + rm_watch = binding.rm_watch + add_watch = binding.add_watch + + ''' + Entering infinite loop + ''' + + path = "/tmp" + fd = init() + wd_to_path = {} + + wd = add_watch(fd, path) + wd_to_path[wd] = path + + try: + while True: + events = get_events(fd) + for event in events: + path = wd_to_path[event.wd] + parts = [event.get_mask_description()] + if event.name: + parts.append(event.name) + logger.debug("parts[] == " + str(parts)) + if parts[0][0:3] == "IN_": + logger.info('%s: %s' % (path, ' '.join(parts))) + except: + logger.error("While loop interrupted : aborting") + os.close(fd) + # Faut arrêter les Process ... + # Invocation of the daemon part # Means : if it's working : DON'T TOUCH ANYTHING if __name__ == "__main__": - app = App() logger = logging.getLogger("horusd") - loglevel = "info" + loglevel = "debug" if (loglevel=="DEBUG") or (loglevel=="debug"): logger.setLevel(logging.DEBUG) elif (loglevel=="INFO") or (loglevel=="info"): @@ -62,7 +175,7 @@ if __name__ == "__main__": else: logger.setLevel(logging.DEBUG) formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") - handler = logging.FileHandler("horusd.log") + handler = logging.FileHandler("log/horusd.log") handler.setFormatter(formatter) logger.addHandler(handler) diff --git a/test.py b/test.py new file mode 100755 index 0000000..0a2006f --- /dev/null +++ b/test.py @@ -0,0 +1,112 @@ +#!/usr/bin/python2.7 +# -*- coding:Utf-8 -*- +import os, select + +from inotifyx import binding +from inotifyx.distinfo import version as __version__ + + +constants = {} + +for name in dir(binding): + if name.startswith('IN_CREATE') or name.startswith('IN_DELETE'): + globals()[name] = constants[name] = getattr(binding, name) + + +init = binding.init +rm_watch = binding.rm_watch +add_watch = binding.add_watch + + +class InotifyEvent(object): + ''' + InotifyEvent(wd, mask, cookie, name) + + A representation of the inotify_event structure. See the inotify + documentation for a description of these fields. + ''' + + wd = None + mask = None + cookie = None + name = None + + def __init__(self, wd, mask, cookie, name): + self.wd = wd + self.mask = mask + self.cookie = cookie + self.name = name + + def __str__(self): + return '%s: %s' % (self.wd, self.get_mask_description()) + + def __repr__(self): + return '%s(%s, %s, %s, %s)' % ( + self.__class__.__name__, + repr(self.wd), + repr(self.mask), + repr(self.cookie), + repr(self.name), + ) + + def get_mask_description(self): + ''' + Return an ASCII string describing the mask field in terms of + bitwise-or'd IN_* constants, or 0. The result is valid Python code + that could be eval'd to get the value of the mask field. In other + words, for a given event: + + >>> from inotifyx import * + >>> assert (event.mask == eval(event.get_mask_description())) + ''' + parts = [] + for name, value in constants.items(): + if self.mask & value: + parts.append(name) + if parts: + return '|'.join(parts) + return '0' + + +def get_events(fd, *args): + ''' + get_events(fd[, timeout]) + + Return a list of InotifyEvent instances representing events read from + inotify. If timeout is None, this will block forever until at least one + event can be read. Otherwise, timeout should be an integer or float + specifying a timeout in seconds. If get_events times out waiting for + events, an empty list will be returned. If timeout is zero, get_events + will not block. + ''' + return [ + InotifyEvent(wd, mask, cookie, name) + for wd, mask, cookie, name in binding.get_events(fd, *args) + ] + + +if __name__ == '__main__': + import sys + + path = "/tmp" + fd = init() + wd_to_path = {} + + wd = add_watch(fd, path) + wd_to_path[wd] = path + + try: + while True: + events = get_events(fd) + for event in events: + path = wd_to_path[event.wd] + parts = [event.get_mask_description()] + if event.name: + parts.append(event.name) + if parts[0][0:3] == "IN_": + print '%s: %s' % (path, ' '.join(parts)) + except KeyboardInterrupt: + pass + + finally: + os.close(fd)