# 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 " )