====== logtemp.py ======
Cloned from https://github.com/ntpsec/ntpsec/blob/master/ntpclients/ntplogtemp.py with everything but the lm-sensors stuff removed.
Run every 5 minutes:
*/15 * * * * logtemp -o -l /var/log/ntpsec/temps >/dev/null 2>&1
#! /usr/bin/env python
# -*- coding: utf-8 -*-
"""\
usage: ntplogtemp [-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.
"""
from __future__ import print_function, division
import argparse
import glob
import logging
import logging.handlers
import os
import re
import subprocess
import sys
import time
class logfile_header_class(logging.handlers.TimedRotatingFileHandler):
'A class to modify the file logging handler.'
def doRollover(self):
'function to add header to new file on rotation.'
if str is bytes:
super(logfile_header_class, self).doRollover()
else:
super().doRollover()
# self.stream.write('# time, sensor, value\n')
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].split("\n")
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 exception
return None
return output
class CpuTemp:
"Sensors on the CPU Core"
has_sensors = False
def __init__(self):
# check for 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 not self.has_sensors:
return None
_index = 0
_data = []
# grab the needed output
output = run_binary(["sensors", "-u"])
if output is not None:
for record in output:
match = self._pattern.match(record)
if match and match.group(1):
_now = int(time.time())
_cpu_temperature = match.group(1)
_data.append('%d LM%s %s' % (_now, _index,
_cpu_temperature))
_index += 1
else:
self.has_sensors = False
if args.verbose:
sys.stderr.write("No sensors returned temperatures. ",
"Have you run sensors-detect?")
return _data
# Work with argvars
parser = argparse.ArgumentParser(description="Temperature sensor daemon",
epilog="""See the manual page for details.""")
parser.add_argument('-l', '--logfile',
dest='logfile',
help="append log data to LOGFILE instead of stdout",
nargs=1)
parser.add_argument('-o', '--once',
dest='once',
help="Run the output once and exit",
action='store_true')
parser.add_argument('-q', '--quiet',
action="store_true",
dest='quiet',
help="be quite")
parser.add_argument('-v', '--verbose',
action="store_true",
dest='verbose',
help="be verbose")
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="ntplogtemp ntpsec-@NTPSEC_VERSION_EXTENDED@")
args = parser.parse_args()
def logging_setup():
"Create logging object"
logFormat = logging.Formatter('%(message)s')
# Create logger for cpuTemp
tempLogger = logging.getLogger()
tempLogger.setLevel(logging.INFO)
# Create file handler
if args.logfile:
# log to logfile
file = logfile_header_class(
args.logfile[0],
utc=True,
when='midnight',
interval=1)
else:
# log to stdout
file = logging.StreamHandler(sys.stdout)
file.setLevel(logging.INFO)
# Create the formatter and add it to the handler
file.setFormatter(logFormat)
# Add the handler to the logger
tempLogger.addHandler(file)
return tempLogger
def logData(log, data):
"log the data"
if data is not None:
for _item in data:
log.info(_item)
def log_data():
"Write all temperature readings to one file"
# Create objects
cpu = CpuTemp()
# Create the logger instance
Logger = logging_setup()
# Create data layout
# logData(Logger, ["# time, sensor, value"])
# Write data to their respective logs
while True:
logData(Logger, cpu.get_data())
if args.once:
sys.exit(0)
time.sleep(args.wait[0])
args = parser.parse_args()
if os.getuid():
sys.stderr.write("You must be root!")
sys.exit(1)
try:
log_data()
except (KeyboardInterrupt, SystemExit):
print("") # be nice to bash
sys.exit(0)