[Git][NTPsec/ntpsec][master] 4 commits: temp-log.py: keep logs forever.
Gary E. Miller
gitlab at mg.gitlab.com
Fri Jan 27 03:55:59 UTC 2017
Gary E. Miller pushed to branch master at NTPsec / ntpsec
Commits:
2044d511 by Gary E. Miller at 2017-01-26T18:05:31-08:00
temp-log.py: keep logs forever.
- - - - -
774baf9b by Gary E. Miller at 2017-01-26T18:11:34-08:00
temp-log.py: simplify smartctl drive detection
- - - - -
517b704e by Gary E. Miller at 2017-01-26T18:32:55-08:00
temp-log.py: improve comments.
- - - - -
4f9623ac by Gary E. Miller at 2017-01-26T19:54:39-08:00
temp-log.py: remove subprocess.check_output() for Python 2.6 compatibility
Move all the system call stuff into one function.
- - - - -
1 changed file:
- contrib/temp-log.py
Changes:
=====================================
contrib/temp-log.py
=====================================
--- a/contrib/temp-log.py
+++ b/contrib/temp-log.py
@@ -1,11 +1,24 @@
#!/usr/bin/env python
-# temp-log.py: A script that will be run eventually as a daemon
-# to log temperatures of a system
-# Usage:
-# temp-log.py [-h] [-q] [-v] [-V] [-l LOGFILE]
-# Requires root to run
+"""\
+usage: temp-log.py [-h] [-l LOGFILE] [-o] [-q] [-v] [-w WAIT] [-V]
+
+Program to log system temperatures
+
+optional arguments:
+ -h, --help show this help message and exit
+ -l LOGFILE, --logfile LOGFILE
+ append log data to LOGFILE instead of stdout
+ -o, --once Run the output once and exit
+ -q, --quiet be quite
+ -v, --verbose be verbose
+ -w WAIT, --wait WAIT Set delay time in seconds, default is 60
+ -V, --version show program's version number and exit
+
+See the manual page for details.
+"""
import argparse
+import glob
import logging
import logging.handlers
import os
@@ -22,37 +35,57 @@ except ImportError as e:
sys.exit(1)
+def run_binary(cmd):
+ """\
+Run a binary
+Return output if good, None if bad
+"""
+
+ try:
+ # sadly subprocess.check_output() is not in Python 2.6
+ # so use Popen()
+ # this throws an exception if not found
+ proc = subprocess.Popen( cmd,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ universal_newlines=True)
+ output = proc.communicate()[0]
+
+ if proc.returncode:
+ # non-zero return code, fail
+ return None
+
+ except:
+ if args.verbose:
+ sys.stderr.write("Unable to run %s binary\n" % cmd[0])
+ # throws exceptoin
+ return None
+ return output
+
class CpuTemp:
"Sensors on the CPU Core"
- no_sensors = False
+ has_sensors = False
def __init__(self):
# check for sensors binary
- try:
- # sadly subprocess.check_output() is not in Python 2.6
- subprocess.check_output(["which", "sensors"],
- stderr=subprocess.STDOUT,)
- except:
- # skip sensors, many systems can not use sensors
- self.no_sensors = True
- if args.verbose:
- sys.stderr.write("Unable to find sensors binary")
+ ret = run_binary(["sensors", "-h"])
+ if ret is not None:
+ self.has_sensors = True
# pattern that matches the string that has the cpu temp
self._pattern = re.compile('^\s+temp\d+_input:\s+([\d\.]+).*$')
def get_data(self):
"Collects the data and return the output as an array"
- if self.no_sensors:
+ if not self.has_sensors:
return None
_index = 0
_data = []
# grab the needed output
- # sadly subprocess.check_output() is not in Python 2.6
- _output = subprocess.check_output(['sensors', "-u"],
- universal_newlines=True).split('\n')
- for record in _output:
+ output = run_binary(["sensors", "-u"])
+
+ for record in output.split("\n"):
match = self._pattern.match(record)
if match and match.group(1):
_now = int(time.time())
@@ -66,34 +99,37 @@ class CpuTemp:
class SmartCtl:
"Sensor on the Hard Drive"
_drives = []
+ has_smartctl = False
def __init__(self):
- if os.getuid() != 0:
- raise IOError("You must be root!")
- # Which drive to watch
- for child in os.listdir('/dev/'):
- if re.compile('sd[a-z]$').match(child):
- self._drives.append("/dev/"+str(child))
- self._drives = sorted(self._drives)
+ ret = run_binary(["smartctl", "-h"])
+ if ret is not None:
+ self.has_smartctl = True
+
+ if self.has_smartctl:
+ # Which drive to watch
+ for child in glob.glob('/dev/sd?'):
+ self._drives.append(child)
+ self._drives = sorted(self._drives)
def get_data(self):
"Collects the data and return the output as an array"
+ if not self.has_smartctl:
+ return None
+
data = []
for _device in self._drives[:]:
- try:
- # sadly subprocess.check_output() is not in Python 2.6
- _output = subprocess.check_output(["smartctl", "-A",
- _device],
- universal_newlines=True
- ).split('\n')
- for line in _output:
+ output = run_binary(["smartctl", "-A", _device])
+
+ if output is None:
+ # do not keep trying on failure
+ self._drives.remove(_device)
+ else:
+ for line in output.split("\n"):
if line.startswith('194 '):
now = int(time.time())
temp = line.split()[9]
data.append('%d %s %s' % (now, _device, temp))
- except:
- # do not keep trying on failure
- self._drives.remove(_device)
return data
@@ -105,42 +141,31 @@ class Temper:
plugged in, and the temper-python package must be installed and configured.
See their documentation for that procedure.
"""
- no_temper = False
+ has_temper = False
def __init__(self):
- # check for temper-poll binary
- try:
- # sadly subprocess.check_output() is not in Python 2.6
- subprocess.check_output(["which", "temper-poll"],
- stderr=subprocess.STDOUT,)
- except:
- # skip temper, many systems do not have it
- self.no_temper = True
- if args.verbose:
- sys.stderr.write("Unable to find temper-poll binary")
+ # check for sensors binary
+ ret = run_binary(["temper-poll", "-h"])
+ if ret is not None:
+ self.has_temper = True
def get_data(self):
"Collects the data and return the output as an array"
- if self.no_temper:
+ if not self.has_temper:
return None
data = []
_device = 'TEMPER0'
# grab the needed output
- # sadly subprocess.check_output() is not in Python 2.6
+ output = run_binary(["temper-poll", "-c"])
try:
- proc = subprocess.Popen(["temper-poll", "-c"],
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- universal_newlines=True)
- temp = proc.communicate()[0]
# make sure it is a temperature
- temp = float(temp)
+ temp = float(output)
now = int(time.time())
data.append('%d %s %s' % (now, _device, temp))
except:
- # bad data, ignore it
- self.no_temper = True
+ # bad data, ignore it, forever
+ self.has_temper = False
return data
@@ -188,15 +213,15 @@ parser.add_argument('-v', '--verbose',
action="store_true",
dest='verbose',
help="be verbose")
-parser.add_argument('-V', '--version',
- action="version",
- version="temp-log %s" % ntp.util.stdversion())
parser.add_argument('-w', '--wait',
default=[60],
dest='wait',
help="Set delay time in seconds, default is 60",
nargs=1,
type=int)
+parser.add_argument('-V', '--version',
+ action="version",
+ version="temp-log %s" % ntp.util.stdversion())
args = parser.parse_args()
@@ -211,11 +236,7 @@ def logging_setup(fileName, logLevel):
_file = logging.handlers.TimedRotatingFileHandler(
fileName,
when='midnight',
- interval=1,
- backupCount=5,
- encoding=None,
- delay=False,
- utc=False)
+ interval=1)
else:
_file = logging.StreamHandler(sys.stdout)
@@ -277,4 +298,5 @@ try:
log = sys.stdout
log_data()
except (KeyboardInterrupt, SystemExit):
+ print("") # be nice to bash
sys.exit(0)
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/33da600f8897baaf338dc2e98082aa3c841a4a27...4f9623acf55868f0bb08a5a8e5d6014cd3d2b95b
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ntpsec.org/pipermail/vc/attachments/20170127/7043d8fe/attachment.html>
More information about the vc
mailing list