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
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"):
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)
--- /dev/null
+#!/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)