Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- """Check if all processes matching a name were started after a config
- file's mtime.
- --snip--
- Tested under Python 2.7 and 3.4
- """
- from __future__ import (absolute_import, division, print_function,
- with_statement, unicode_literals)
- __author__ = "Stephan Sokolow (deitarion/SSokolow)"
- __appname__ = "restarted_since.py"
- __version__ = "0.1"
- __license__ = "MIT"
- import logging, os, subprocess, sys
- log = logging.getLogger(__name__)
- # Ticks per second
- tick_rate = os.sysconf(os.sysconf_names['SC_CLK_TCK'])
- def getpids(procname):
- """Simple abstraction for a couple of ways to get PIDs from names"""
- try:
- pidstr = subprocess.check_output(['pidof', procname])
- except subprocess.CalledProcessError:
- pidstr = subprocess.check_output(['pgrep', procname])
- return [int(x.strip()) for x in pidstr.strip().split()]
- def get_start_time(pid):
- """Given a PID, look up the start time in seconds since the epoch
- See `man 5 proc` for references used to implement.
- Passes through IOError with errno=ENOENT if the process went away.
- """
- # Read process start time as clock ticks since system boot
- with open("/proc/{}/stat".format(pid), 'rb') as fobj:
- proc_start_ticks_since_boot = int(fobj.read().strip().split()[21])
- # Read system boot time as seconds since the epoch
- sys_boot_time = None
- with open("/proc/stat", 'rb') as fobj:
- for line in fobj:
- key, val = line.split(None, 1)
- if key == b'btime':
- sys_boot_time = int(val)
- assert sys_boot_time
- # Translate process start time from ticks to seconds
- proc_start_secs_since_boot = proc_start_ticks_since_boot / tick_rate
- # Translate process start time from since-boot to since-epoch
- proc_start_secs_since_epoch = proc_start_secs_since_boot + sys_boot_time
- return proc_start_secs_since_epoch
- def get_mtime(path):
- """Thin wrapper for grabbing a file's mtime"""
- assert os.path.exists(path), "Path does not exist: {}".format(path)
- return os.stat(path).st_mtime
- def main():
- """The main entry point, compatible with setuptools entry points."""
- # If we're running on Python 2, take responsibility for preventing
- # output from causing UnicodeEncodeErrors. (Done here so it should only
- # happen when not being imported by some other program.)
- if sys.version_info.major < 3:
- reload(sys)
- sys.setdefaultencoding('utf-8') # pylint: disable=no-member
- from argparse import ArgumentParser
- parser = ArgumentParser(
- description=__doc__.replace('\r\n', '\n').split('\n--snip--\n')[0])
- parser.add_argument('--version', action='version',
- version="%%(prog)s v%s" % __version__)
- parser.add_argument('-v', '--verbose', action="count",
- default=2, help="Increase the verbosity. Use twice for extra effect")
- parser.add_argument('-q', '--quiet', action="count",
- default=0, help="Decrease the verbosity. Use twice for extra effect")
- parser.add_argument('process_name', help="Process name to be checked")
- parser.add_argument('config_file', help="UNIX timestamp to compare")
- args = parser.parse_args()
- # Set up clean logging to stderr
- log_levels = [logging.CRITICAL, logging.ERROR, logging.WARNING,
- logging.INFO, logging.DEBUG]
- args.verbose = min(args.verbose - args.quiet, len(log_levels) - 1)
- args.verbose = max(args.verbose, 0)
- logging.basicConfig(level=log_levels[args.verbose],
- format='%(levelname)s: %(message)s')
- earliest_started = min(get_start_time(i)
- for i in getpids(args.process_name))
- if earliest_started > get_mtime(args.config_file):
- sys.exit(0)
- else:
- sys.exit(1)
- if __name__ == '__main__':
- main()
- # vim: set sw=4 sts=4 expandtab :
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement