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.
260 lines
9.9 KiB
260 lines
9.9 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 tools.path_tool
|
|
#import tools.i18n_tool
|
|
#import basic.text_const as T
|
|
import basic.constants as B
|
|
|
|
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.job = job
|
|
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["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
|
|
elif hasattr(job.par, B.PAR_MODUS) and getattr(job.par, B.PAR_MODUS) == "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")
|
|
os.makedirs(basedir, exist_ok=True)
|
|
# basedir = tools.path_tool.composePath(basedir, None)
|
|
# basedir = tools.path_tool.composePath(job, basedir, None)
|
|
logpath = job.getLogpath()
|
|
basedir = os.path.dirname(logpath)
|
|
os.makedirs(basedir, exist_ok=True)
|
|
# logpath = os.path.join(basedir , job.program + "_" + logTime + ".txt")
|
|
self.logDebug("logfile " + logpath)
|
|
if os.path.exists(logpath):
|
|
self.logfile = open(logpath, "a")
|
|
else:
|
|
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",
|
|
"rc8": "fatal",
|
|
"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 = self.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 getMessageText(self, job, text, args):
|
|
return 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:
|
|
try:
|
|
self.logfile.write(text + "\n")
|
|
except:
|
|
pass
|
|
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:
|
|
try:
|
|
self.debugfile.write(text + "\n")
|
|
except:
|
|
print("debug closed "+text)
|
|
|
|
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")
|