Data-Test-Executer Framework speziell zum Test von Datenverarbeitungen mit Datengenerierung, Systemvorbereitungen, Einspielungen, ganzheitlicher diversifizierender Vergleich
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

238 lines
9.2 KiB

# function for collecting and writing messages i.e. logging and calculate the return-code
# ------------------------------------------------------------------------
"""
there are two types of logging:
* log everything relevant to document the test-run in relation of the test-system and the test-effort
should be logged in order to archive these logfiles
* debug everything to know how this automatism is running should log into a debug-file. This file can be
removed after a few days
the logging is parametrized by the log-level (fatal ... trace). Especially the debug- and trace-message can be
switched on/of en detail in the functions and over special settings (parameter tool, component: these debugs should be switched on)
there are three types of functions:
* setFatal|Error|...() it logs, sets the top-message and return-code
* logFatal|Error|...() it logs without any effect for the program-result
* log()|debug(int) it logs depending on the special level-setting
at the end of a program there are some results:
* for each component there is a return-code, a top-message for documentation in the parameter-file, and a list of collected messages
+ for the main-program the result (return-code, top-message) will be summarized (the most relevant message will used)
"""
import basic.program
import os
import math
from datetime import datetime
import utils.path_tool
LIMIT_FATAL = 0
LIMIT_ERROR = 4
LIMIT_WARN = 8
LIMIT_MSG = 12
LIMIT_INFO = 16
LIMIT_DEBUG = 20
LIMIT_TRACE = 24
RC_OFFSET = 4
RC_FATAL = 8
RC_ERROR = 6
RC_WARN = 5
RC_MSG = 4
RC_INFO = 3
RC_DEBUG = 2
RC_TRACE = 1
class Message:
"""
Ausgaben erfolgen prioritaeten-gesteuert anhand
* Typ (fatal..trace)
* Einstellung (a) ueber Parameter ODER (b) in Funktion
Im Funktionskopf wird Einstellung gesetzt, z.B. verify=job.getDebugLevel (ggf keine Debug-Ausgabe) bzw. verify=job.getDebugLevel-1 (eingeschaltete Debug-Ausgabe)
"fatal": "4", # Abbruchfehlker, wird immer in debug und log ausgegeben, setzt RC
"error": "8", # Fehler, wird immer in debug und log ausgegeben, setzt RC
"warn": "12", # Warnung, wird immer in debug und log ausgegeben, setzt RC
"msg": "16", # Ergebnis, wird immer in debug und log ausgegeben, setzt RC
"info": "20", # Info, wird ggf. in debug und log ausgegeben, setzt RC
"debug": "24", # wird nur in debug ausgegeben, wenn log-level hoechstens auf eingestelltem job-level steht
"trace": "28", # wird nur in debug ausgegeben, wenn log-level hoechstens auf eingestelltem job-level steht
"""
def __init__(self, job, level, logTime, componente):
# (self, componente, out, level):
self.componente = componente # dezantrales Logsystem
verify = LIMIT_DEBUG
self.initErrorTyp()
self.rc = RC_INFO
if (level == 0):
self.level = LIMIT_DEBUG
else:
self.level = level
# init debugfile - except for each component
if componente is not None: # use general debugfile
self.debugfile = job.m.debugfile
self.debug(verify, "> > > debugfile uebernommen zu " + str(componente))
else:
debugpath = job.conf.confs["paths"]["debugs"] + "/debug_" + logTime[0:-4] + "00.txt"
print ("debugpathx "+debugpath)
if os.path.exists(debugpath):
self.debugfile = open(debugpath, "a")
else:
self.debugfile = open(debugpath, "w")
self.debug(verify, "> > > debugfile geoeffnet zu " + job.program + " mit " + debugpath)
# init logfile - except for components or unittest
self.logDebug("logfile " + str(componente) + ", " + str(job.par.basedir))
if componente is not None: #
self.logfile = self.debugfile
elif job.program == "unit":
self.logfile = self.debugfile
else:
self.setLogdir(job, logTime)
self.topmessage = ""
self.messages = []
print("message initialisiert mit level " + str(self.level))
def setLogdir(self, job, logTime):
basedir = job.par.basedir
basedir = basedir.replace("base", "log")
# basedir = utils.path_tool.composePath(basedir, None)
basedir = utils.path_tool.composePath(basedir, None)
os.makedirs(basedir, exist_ok=True)
logpath = os.path.join(basedir , job.program + "_" + logTime + ".txt")
self.logDebug("logfile " + logpath)
self.logfile = open(logpath, "w")
def initErrorTyp(self):
self.CONST_ERRTYP = {
"fatal": "4", # wird immer in debug und log ausgegeben, setzt RC
"error": "8", # wird immer in debug und log ausgegeben, setzt RC
"warn": "12", # wird immer in debug und log ausgegeben, setzt RC
"msg": "16", # wird immer in debug und log ausgegeben, setzt RC
"info": "20", # wird immer in debug und log ausgegeben, setzt RC
"debug": "24", # wird nur in debug ausgegeben, wenn log-level hoechstens auf eingestelltem job-level steht
"trace": "28", # wird nur in debug ausgegeben, wenn log-level hoechstens auf eingestelltem job-level steht
"rc1": "fatal",
"rc2": "error",
"rc3": "warn",
"rc4": "info",
"rc5": "debug",
"rc6": "trace",
"1": "fatal",
"2": "error",
"3": "warn",
"4": "info",
"5": "debug",
"6": "trace"
}
def getErrortyp(self, prio):
if prio <= LIMIT_FATAL:
return "FATAL"
elif prio <= LIMIT_ERROR:
return "ERROR"
elif prio <= LIMIT_WARN:
return "WARN"
elif prio <= LIMIT_MSG:
return "MESSAGE"
elif prio <= LIMIT_INFO:
return "INFO"
elif prio <= LIMIT_DEBUG:
return "DEBUG"
elif prio <= LIMIT_TRACE:
return "TRACE"
else:
return "NDEF"
def closeMessage(self) :
self.debug(LIMIT_INFO, "closeMessage ------------------------------------------- \n")
self.logfile.close()
self.debugfile.close()
def setRc(self, rc, text):
job = basic.program.Job.getInstance()
verify = -0+LIMIT_DEBUG
self.debug(verify, "setRc " + str(rc) + " " + str(self.rc)+ "\n")
if (int(rc) > self.rc):
self.rc = rc
self.topmessage = self.CONST_ERRTYP["rc"+str(rc)].upper() + ": " + text
elif (int(rc) == self.rc):
self.topmessage = self.CONST_ERRTYP["rc"+str(rc)].upper() + ": " + text
def isRc(self, rc):
rcId = int(int(self.CONST_ERRTYP[rc]) / 4 - RC_OFFSET)
print("< < < isRc " + str(self.rc) + " <=? " + str(rcId))
if self.rc <= int(rcId):
print("return True")
return True
else:
print("return False")
return False
def getFinalRc(self):
if (self.rc <= RC_OFFSET):
return 0
else:
return int(int(self.rc) - RC_OFFSET)
def setFatal(self, text):
""" Routine zum Setzen des RC und gleichzeitigem Schreiben des Logs """
self.setRc(RC_FATAL, text)
self.logFatal(text)
def setError(self, text):
""" Routine zum Setzen des RC und gleichzeitigem Schreiben des Logs """
self.setRc(RC_ERROR, text)
self.logError(text)
def setWarn(self, text):
""" Routine zum Setzen des RC und gleichzeitigem Schreiben des Logs """
self.setRc(RC_WARN, text)
self.logWarn(text)
def setMsg(self, text):
""" Routine zum Setzen des RC und gleichzeitigem Schreiben des Logs """
self.setRc(RC_MSG, text)
self.logInfo(text)
def logFatal(self, text):
self.log(LIMIT_FATAL, "FATAL: " + text)
self.debug(LIMIT_FATAL, "FATAL: " + text)
def logError(self, text):
self.log(LIMIT_ERROR, "ERROR: " + text)
self.debug(LIMIT_ERROR, "ERROR: " + text)
def logWarn(self, text):
self.log(LIMIT_WARN, "WARN: " + text)
def logMsg(self, text):
self.log(LIMIT_MSG, text)
self.log(LIMIT_MSG, "MSG: " + text)
def logInfo(self, text):
self.log(LIMIT_INFO, text)
def logDebug(self, text):
self.debug(LIMIT_DEBUG, text)
def logTrace(self, text):
self.debug(LIMIT_TRACE, text)
def log(self, prio, text):
""" eigentliche Schreibroutine: hierin wird debug-Level beruecksichtgigt"""
if (int(prio) <= int(self.level)) and (self.componente is None): # and self.logfile.closed == False:
self.logfile.write(text + "\n")
elif (int(prio) <= int(self.level)):
self.messages.append(text)
else:
self.debug(prio, self.getErrortyp(prio) + ": " + text)
def debug(self, prio, text):
""" eigentliche Schreibroutine: hierin wird debug-Level beruecksichtgigt"""
if (int(prio) < int(self.level)+1) : #and self.debugfile.closed == False:
self.debugfile.write(text + "\n")
def resetLog(self):
self.messages = []
def merge(self, submsg):
self.setRc(submsg.getFinalRc(), submsg.topmessage)
text = "\n".join(submsg.messages)
self.logInfo("\n"+text+"\n")