logs können ganz oder zeilenweise nachgeladen werden

This commit is contained in:
2017-02-27 14:27:12 +01:00
parent fe957213d7
commit b6ac0b450f

View File

@@ -8,6 +8,7 @@
# #
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import proginit import proginit
import os
import shlex import shlex
import signal import signal
import subprocess import subprocess
@@ -17,15 +18,79 @@ from time import sleep, asctime
from xmlrpc.server import SimpleXMLRPCServer from xmlrpc.server import SimpleXMLRPCServer
class LogReader():
def __init__(self):
self.fhapp = None
self.logapp = "/var/log/revpipyloadapp"
self.posapp = 0
self.fhplc = None
self.logplc = "/var/log/revpipyload"
self.posplc = 0
def get_applines(self):
if not os.access(self.logapp, os.R_OK):
return None
else:
if self.fhapp is None or self.fhapp.closed:
self.fhapp = open(self.logapp)
lst_new = []
while True:
self.posapp = self.fhapp.tell()
line = self.fhapp.readline()
if line:
lst_new.append(line)
else:
break
return lst_new
def get_applog(self):
if not os.access(self.logapp, os.R_OK):
return None
else:
if self.fhapp is None or self.fhapp.closed:
self.fhapp = open(self.logapp)
self.fhapp.seek(0)
return self.fhapp.read()
def get_plclines(self):
if not os.access(self.logplc, os.R_OK):
return None
else:
if self.fhplc is None or self.fhplc.closed:
self.fhplc = open(self.logplc)
lst_new = []
while True:
self.posplc = self.fhplc.tell()
line = self.fhplc.readline()
if line:
lst_new.append(line)
else:
break
return lst_new
def get_plclog(self):
if not os.access(self.logplc, os.R_OK):
return None
else:
if self.fhplc is None or self.fhplc.closed:
self.fhplc = open(self.logplc)
self.fhplc.seek(0)
return self.fhplc.read()
class RevPiPlc(Thread): class RevPiPlc(Thread):
def __init__(self, pargs, logger, lst_proc): def __init__(self, pargs, logger, program):
super().__init__() super().__init__()
self.autoreload = False self.autoreload = False
self._evt_exit = Event() self._evt_exit = Event()
self.exitcode = 0 self.exitcode = 0
self._lst_proc = lst_proc self._lst_proc = shlex.split("/usr/bin/env python3 -u " + program)
#self._lst_proc = ["ls", "/"]
self._logger = logger self._logger = logger
self._pargs = pargs self._pargs = pargs
self._procplc = None self._procplc = None
@@ -34,19 +99,22 @@ class RevPiPlc(Thread):
def run(self): def run(self):
# Prozess starten # Prozess starten
self._logger.info("start plc program") self._logger.info("start plc program")
fh = None
if self._pargs.daemon: if self._pargs.daemon:
fh = open("/var/log/revpipyloadapp", "a") if os.access("/var/log", os.R_OK | os.W_OK):
fh = "/var/log/revpipyloadapp"
elif self._pargs.logfile is not None:
fh = self._pargs.logfile
if fh is not None:
fh = open(fh, "a")
fh.write("started {}\n".format(asctime())) fh.write("started {}\n".format(asctime()))
fh.flush() fh.flush()
elif self.pargs.logfile is not None:
fh = open(self.pargs.logfile, "a")
fh.write("started {}\n".format(asctime()))
fh.flush()
else:
fh = None
# Prozess erstellen # Prozess erstellen
self._procplc = subprocess.Popen(self._lst_proc, bufsize=1, stdout=fh, stderr=subprocess.STDOUT) self._procplc = subprocess.Popen(
self._lst_proc, bufsize=1, stdout=fh, stderr=subprocess.STDOUT
)
while not self._evt_exit.is_set(): while not self._evt_exit.is_set():
@@ -54,22 +122,31 @@ class RevPiPlc(Thread):
self.exitcode = self._procplc.poll() self.exitcode = self._procplc.poll()
if self.exitcode is not None: if self.exitcode is not None:
if self.exitcode > 0: if self.exitcode > 0:
# PLC Python Programm abgestürzt
self._logger.error( self._logger.error(
"plc program chrashed - exitcode: {}".format( "plc program chrashed - exitcode: {}".format(
self.exitcode self.exitcode
) )
) )
if self.zeroonexit: if self.zeroonexit:
# piControl0 auf NULL setzen
f = open("/dev/piControl0", "w+b", 0) f = open("/dev/piControl0", "w+b", 0)
f.write(bytes(4096)) f.write(bytes(4096))
self._logger.warning("set piControl0 to ZERO") self._logger.warning("set piControl0 to ZERO")
else: else:
# PLC Python Programm sauber beendet
self._logger.info("plc program did a clean exit") self._logger.info("plc program did a clean exit")
if not self._evt_exit.is_set() and self.autoreload: if not self._evt_exit.is_set() and self.autoreload:
# Prozess neu starten # Prozess neu starten
self._procplc = subprocess.Popen(self._lst_proc, bufsize=1, stdout=fh, stderr=subprocess.STDOUT) self._procplc = subprocess.Popen(
self._lst_proc, bufsize=1, stdout=fh,
stderr=subprocess.STDOUT
)
if self.exitcode == 0: if self.exitcode == 0:
self._logger.warning( self._logger.warning(
"restart plc program after clean exit" "restart plc program after clean exit"
@@ -110,6 +187,7 @@ class RevPiPyLoad(proginit.ProgInit):
self.evt_loadconfig = Event() self.evt_loadconfig = Event()
self.autoreload = None self.autoreload = None
self.logr = LogReader()
self.plc = None self.plc = None
self.plcprog = None self.plcprog = None
self.plcslave = None self.plcslave = None
@@ -151,15 +229,7 @@ class RevPiPyLoad(proginit.ProgInit):
self.zeroonexit = int(self.globalconfig["DEFAULT"].get("zeroonexit", 1)) self.zeroonexit = int(self.globalconfig["DEFAULT"].get("zeroonexit", 1))
# PLC Thread konfigurieren # PLC Thread konfigurieren
self.logger.debug("create PLC watcher") self.plc = self.plcthread()
self.plc = RevPiPlc(
self.pargs,
self.logger,
shlex.split("/usr/bin/env python3 -u " + self.plcprog)
)
self.plc.autoreload = self.autoreload
self.plc.zeroonexit = self.zeroonexit
self.logger.debug("created PLC watcher")
# XMLRPC-Server Instantiieren und konfigurieren # XMLRPC-Server Instantiieren und konfigurieren
if self.xmlrpc: if self.xmlrpc:
@@ -174,13 +244,16 @@ class RevPiPyLoad(proginit.ProgInit):
) )
self.xsrv.register_introspection_functions() self.xsrv.register_introspection_functions()
self.xsrv.register_function(self.xml_getapplog, "get_applog") self.xsrv.register_function(self.logr.get_applines, "get_applines")
self.xsrv.register_function(self.xml_getplclog, "get_plclog") self.xsrv.register_function(self.logr.get_applog, "get_applog")
self.xsrv.register_function(self.logr.get_plclines, "get_plclines")
self.xsrv.register_function(self.logr.get_plclog, "get_plclog")
self.xsrv.register_function(self.xml_plcdownload, "plcdownload")
self.xsrv.register_function(self.xml_plcexitcode, "plcexitcode") self.xsrv.register_function(self.xml_plcexitcode, "plcexitcode")
self.xsrv.register_function(self.xml_plcrestart, "plcrestart")
self.xsrv.register_function(self.xml_plcrunning, "plcrunning") self.xsrv.register_function(self.xml_plcrunning, "plcrunning")
self.xsrv.register_function(self.xml_plcstart, "plcstart") self.xsrv.register_function(self.xml_plcstart, "plcstart")
self.xsrv.register_function(self.xml_plcstop, "plcstop") self.xsrv.register_function(self.xml_plcstop, "plcstop")
self.xsrv.register_function(self.xml_plcupload, "plcupload")
self.xsrv.register_function(self.xml_reload, "reload") self.xsrv.register_function(self.xml_reload, "reload")
self.logger.debug("created xmlrpc server") self.logger.debug("created xmlrpc server")
@@ -192,15 +265,26 @@ class RevPiPyLoad(proginit.ProgInit):
def _sigexit(self, signum, frame): def _sigexit(self, signum, frame):
"""Signal handler to clean an exit program.""" """Signal handler to clean an exit program."""
self.logger.info("got exit signal") self.logger.debug("got exit signal")
self.stop() self.stop()
def _sigloadconfig(self, signum, frame): def _sigloadconfig(self, signum, frame):
self.logger.info("got reload config signal") """Signal handler to load configuration."""
self.logger.debug("got reload config signal")
self.evt_loadconfig.set() self.evt_loadconfig.set()
def plcthread(self):
"""Konfiguriert den PLC-Thread fuer die Ausfuehrung.
@returns: PLC-Thread Object"""
self.logger.debug("create PLC watcher")
th_plc = RevPiPlc(self.pargs, self.logger, self.plcprog)
th_plc.autoreload = self.autoreload
th_plc.zeroonexit = self.zeroonexit
self.logger.debug("created PLC watcher")
return th_plc
def start(self): def start(self):
"""Start python program and watching it.""" """Start plcload and PLC python program."""
self.logger.info("starting revpipyload") self.logger.info("starting revpipyload")
self._exit = False self._exit = False
@@ -222,7 +306,7 @@ class RevPiPyLoad(proginit.ProgInit):
self._loadconfig() self._loadconfig()
def stop(self): def stop(self):
"""Stop python program.""" """Stop PLC python program and plcload."""
self.logger.info("stopping revpipyload") self.logger.info("stopping revpipyload")
self._exit = True self._exit = True
@@ -236,35 +320,13 @@ class RevPiPyLoad(proginit.ProgInit):
self.tpe.shutdown() self.tpe.shutdown()
self.xsrv.server_close() self.xsrv.server_close()
def xml_getapplog(self): def xml_plcdownload(self):
self.logger.debug("xmlrpc call getapplog") pass
fh = open("/var/log/revpipyloadapp")
return fh.read()
def xml_getplclog(self):
self.logger.debug("xmlrpc call getplclog")
fh = open("/var/log/revpipyload")
return fh.read()
def xml_plcexitcode(self): def xml_plcexitcode(self):
self.logger.debug("xmlrpc call plcexitcode") self.logger.debug("xmlrpc call plcexitcode")
return -1 if self.plc.is_alive() else self.plc.exitcode return -1 if self.plc.is_alive() else self.plc.exitcode
def xml_plcrestart(self):
self.logger.debug("xmlrpc call plcrestart")
self.plc.stop()
self.plc.join()
exitcode = self.plc.exitcode
self.plc = RevPiPlc(
self.pargs,
self.logger,
shlex.split("/usr/bin/env python3 -u" + self.plcprog)
)
self.plc.autoreload = self.autoreload
self.plc.zeroonexit = self.zeroonexit
self.plc.start()
return (exitcode, self.plc.exitcode)
def xml_plcrunning(self): def xml_plcrunning(self):
self.logger.debug("xmlrpc call plcrunning") self.logger.debug("xmlrpc call plcrunning")
return self.plc.is_alive() return self.plc.is_alive()
@@ -274,13 +336,7 @@ class RevPiPyLoad(proginit.ProgInit):
if self.plc.is_alive(): if self.plc.is_alive():
return -1 return -1
else: else:
self.plc = RevPiPlc( self.plc = self.plcthread()
self.pargs,
self.logger,
shlex.split("/usr/bin/env python3 -u" + self.plcprog)
)
self.plc.autoreload = self.autoreload
self.plc.zeroonexit = self.zeroonexit
self.plc.start() self.plc.start()
return self.plc.exitcode return self.plc.exitcode
@@ -290,6 +346,9 @@ class RevPiPyLoad(proginit.ProgInit):
self.plc.join() self.plc.join()
return self.plc.exitcode return self.plc.exitcode
def xml_plcupload(self, file):
pass
def xml_reload(self): def xml_reload(self):
self.logger.debug("xmlrpc call reload") self.logger.debug("xmlrpc call reload")
self.evt_loadconfig.set() self.evt_loadconfig.set()