📄 staflog.rxp
字号:
/*****************************************************************************//* Software Testing Automation Framework (STAF) *//* (C) Copyright IBM Corp. 2001 *//* *//* This software is licensed under the Common Public License (CPL) V1.0. *//******************************************************************************//* STAF_SERVICE_INTERFACE_LEVEL:2 *//******************************************************************************//* REXX Logging Service for Software Testing Automation Framework (STAF) *//* -------------------------------------------------------------------------- *//* Desc: Request to log, query, list, delete, or purge log files. *//* -------------------------------------------------------------------------- *//* Options: *//* Log - Log a message *//* Log Path: *//* GLOBAL - <logdir>\GLOBAL<name.LOG> *//* MACHINE - <logdir>\MACHINE\<machine>\GLOBAL\<name.LOG> *//* HANDLE - <logdir>\MACHINE\<machine>\HANDLE\<handle>\<name.LOG> *//* *//* Log Levels: FATAL ERROR WARNING INFO TRACE TRACE2 TRACE3 *//* DEBUG DEBUG2 DEBUG3 START STOP PASS FAIL STATUS *//* RESERVED1-9 USER1-8 *//* *//* Query - query a log file *//* *//* List - List the directories or files *//* *//* Delete - Delete a log file *//* *//* Purge - Purge records from a log file *//* *//* Internal data format: (Note that all CAPS fields are unreadable) *//* 0 = <LEVEL><TOTLEN><DATE><TIME> *//* <machine>|<handle>|<name>|<LOGLEVEL><message> *//* 1 = <LEVEL><DATE><TIME><LOGLEVEL><DATALEN> *//* <machine>|<handle>|<name>|<message> *//* *//* Note: This program requires RxPP (REXX pre-processor) to be used to *//* generate the executable cmd file. *//* -------------------------------------------------------------------------- *//* History: *//* 0.10 DHR 02/01/1998 Initial implementation *//* 0.20 DHR 02/21/1998 Added variable resolution, PURGE, STATS, unique *//* variable id *//* 0.30 DHR 03/16/1998 Parser changes *//* 0.50 DHR 03/26/1998 Added new API data structure and log level format *//* 1.10 DHR 05/05/1998 Fixed DBCS error on date/time/level fields *//* 1.75 DHR 09/15/1998 Add the new INTERFACE_LEVEL, call format, *//* variable naming convention, fixed a bug *//* in the BEFORE code (Query/Purge) *//* 1.80 CVR 04/30/1999 Remove old variable name support, warn at INIT. *//* 1.81 CVR 11/01/1999 Updated to use CreatePath instead of ManagerDir *//******************************************************************************/options "EXMODE ETMODE"parse source osType invokeType functionNamecall STAFErrorText /* Set the STAF common error codes and text *//* Make sure we are being called correctly */if invokeType \= "FUNCTION" then RETURN MakeSTAFResult(STAFError.!ServiceConfigurationError)/* Call the appropriate function */SIGNAL VALUE TRANSLATE(functionName)/****************************************************************************//* Functions *//****************************************************************************//****************************************************************************//* STAFServiceInit - Initializes the service *//* *//* Accepts: The name of this service *//* The service parameters *//* Returns: 0 *//****************************************************************************/STAFServiceInit: parse arg serviceName, serviceParms /* Load system functions */ call RxFuncAdd "SysLoadFuncs", "REXXUTIL", "SysLoadFuncs" call SysLoadFuncs /* Load STAF functions */ call RxFuncAdd "STAFLoadFuncs", "RXSTAF", "STAFLoadFuncs" call STAFLoadFuncs /* Register Log to STAF */ call STAFRegister "STAF/Service/"serviceName if RESULT \= 0 then RETURN MakeSTAFResult(STAFError.!STAFRegistrationError,, STAFError.!STAFRegistrationError.!text": "RESULT) me = "STAF/Service/"serviceName"/" /* New variable style >= 1.75 */ oldme = "STAFLog/" /* Old variable style < 1.75 */ lineSep = '0D0A'x fileSep = '\' maxRetry = 30 maxSize = 4096 resolveMessage = 0 maskval = substr('1', 1, 32, '1') call STAFSubmit "LOCAL", "VAR", "RESOLVE {STAF/Config/BootDrive}", "RESOLVE {STAF/Config/Sep/Line}", "RESOLVE {STAF/Config/Sep/File}", "RESOLVE {"me"Directory}", "RESOLVE {"me"Retry}", "RESOLVE {"me"MaxRecordSize}", "RESOLVE {"me"Mask}", "RESOLVE {"me"ResolveMessage}", "RESOLVE {"oldme"Directory}", "RESOLVE {"oldme"Retry}", "RESOLVE {"oldme"MaxRecordSize}", "RESOLVE {"oldme"Mask}", "RESOLVE {"oldme"ResolveMessage}" if RESULT = 0 then do parse var STAFResult bootDriveRC ':' bootDrive '00'x, lineSepRC ':' newlineSep '00'x fileSepRC ':' newfileSep '00'x, meDirRC ':' meDir '00'x meRetryRC ':' meRetry '00'x, meRecSizeRC ':' meRecSize '00'x meMaskRC ':' meMask '00'x , meResMessRC ':' meResMess '00'x, oldmeDirRC ':' oldmeDir '00'x oldmeRetryRC ':' oldmeRetry '00'x, oldmeRecSizeRC ':' oldmeRecSize '00'x oldmeMaskRC ':' oldmeMask '00'x , oldmeResMessRC ':' oldmeResMess '00'x if lineSepRC = 0 then lineSep = newLineSep if fileSepRC = 0 then fileSep = newFileSep if (meDirRC \= 0) & (oldmeDirRC = 0) then do call DisplayOldVarErrorMessage "Directory",, bootDrive || filesep || "STAF" || filesep || serviceName end if (meRetryRC \= 0) & (oldmeRetryRC = 0) then call DisplayOldVarErrorMessage "Retry", maxRetry if (meRecSizeRC \= 0) & (oldmeRecSizeRC = 0) then call DisplayOldVarErrorMessage "MaxRecordSize", maxSize if (meMaskRC \= 0) & (oldmeMaskRC = 0) then call DisplayOldVarErrorMessage "Mask", maskval if (meResMessRC \= 0) & (oldmeResMessRC = 0) then call DisplayOldVarErrorMessage "ResolveMessage", resolveMessage endRETURN MakeSTAFResult(RESULT)/****************************************************************************//* STAFServiceAcceptRequest - Handles a service request from STAF *//* *//* Accepts: The name of this service *//* The name of the this machine *//* The name of the client machine *//* The effective name of the client machine *//* The trust level of the client machine *//* The registered name of the originating process *//* The handle of the originating process *//* The actual request string *//* *//* Returns: 0 , on success *//* >0, otherwise *//****************************************************************************/STAFServiceAcceptRequest: parse arg serviceName, thisMachine, clientMachine, clientEffective, , clientTrust, origName, origHandle, origRequest /* Initialization */ version = "1.81" loglevel = "" latestlevel = 1 infile = '' fsep = '|' /* Log file field seperator */ ext = ".log" /* Log file extension */ rc = STAFError.!OK errorBuffer = '' tmplogdata = '' tmplogdatacnt = 0 tmplogdatamax = 100 copysize = 500000 call LogMonErrorText numeric digits 10 /* Initialize digits to precision 10 */ /* Register Log to STAF */ call STAFRegister "STAF/Service/"serviceName if RESULT \= 0 then RETURN MakeSTAFResult(STAFError.!STAFRegistrationError, , STAFError.!STAFRegistrationError.!text": "RESULT) if clientTrust = 0 then RETURN MakeSTAFResult(STAFError.!AccessDenied, , STAFError.!AccessDenied.!text) call ProcessVars /* Query STAF for logging mask */ if datatype(maskval,b) & length(maskval) = 32 then logmask = maskval else do maskval_input = maskval maskval_rest = maskval logmask = substr('0', 1, 32, '0') /* Init levelmask to 32 zeros */ do while maskval_rest > '' /* Loop through maskval list */ parse var maskval_input maskval_level maskval_rest maskval_level = expandLevel(maskval_level) if datatype(maskval_level,b) = 0 | length(maskval_level) \= 32 then do logmask = substr('0', 1, 32, '1') leave end /* Overlay levelmask with a 1 in position where 1 in returned level */ logmask = overlay('1', logmask, pos('1',maskval_level)) maskval_input = maskval_rest end end parse var origRequest type . type = translate(type) if type = "VERSION" then RETURN MakeSTAFResult(STAFError.!Ok, version) else do if type \= "LOG" & type \= "QUERY" & type \= "LIST" & , type \= "DELETE" & type \= "PURGE" & type \= "HELP" then RETURN MakeSTAFResult(STAFError.!InvalidRequestString, , STAFError.!InvalidRequestString.!text || linesep || , "Requires QUERY, LOG, LIST, DELETE, PURGE, or HELP") end /* Initalize the parser for LOG or QUERY and validate input parameters */ call InitializeLogParser origMachine = clientEffective /* Query STAF for the TRUST level of the remote machine if used */ rmtmachine = OptionValue("RMTMACHINE") if rmtmachine > '' then do STAFRC = STAFSubmit("LOCAL", "TRUST", "GET MACHINE "rmtmachine) if STAFRC = 0 then trustlevel = min(trustlevel, STAFResult) else trustlevel = 0 end select when type = "QUERY" | type = "PURGE" then do totalcount = 0 purgecount = 0 call ValidateQueryPurgeInput originfile = infile if type = QUERY then do if trustlevel < 2 then RETURN MakeSTAFResult(STAFError.!AccessDenied, , STAFError.!AccessDenied.!text) /* If the size of the file is >= copysize then use a copy to query */ logcopied = 0 rc = FileStatus(infile, maxretry, "read") if rc = STAFError.!Ok then do call SysFileTree infile, stem, "FT" if stem.0 = 1 then do parse var stem.1 . outsize . . if outsize >= copysize then do logcopied = 1 copyfile = SysTempFileName(logdir || filesep || , ResolveVariable(optionValue("LOGNAME")) || ".???") '@copy' infile copyfile '>nul 2>nul' if rc > 0 then call STAFExit STAFError.!FileWriteError,, STAFError.!FileWriteError.!text": "copyfile call stream infile, "c", "close" infile = copyfile end end end end else do /* Purge Option */ if trustlevel < 4 then RETURN MakeSTAFResult(STAFError.!AccessDenied, , STAFError.!AccessDenied.!text) rc = FileStatus(infile, maxretry, "read/write") newfile = SysTempFileName(logdir || filesep"LM?????.TMP") end if rc = STAFError.!Ok then /* Make sure file READY */ do selcount = 0 logdata = '' do while(chars(infile) > 0) /* Read until EOF */ select = 1 loglevel = c2d(charin(infile,,1),1) /* Read the log level */ select when loglevel = 1 then do ldate = charin(infile,,4) ltime = charin(infile,,3) level = charin(infile,,4) totlen = c2d(charin(infile,,4),4) /* Read record length */ if datatype(c2d(ldate),'X') = 0 | datatype(c2d(level),'X') = 0 then call STAFExit errorBadLog, errorBadLog.!text": "originfile data = charin(infile,,totlen) /* Read <totlen> data */ parse var data machine (fsep) handle (fsep) name (fsep) message end when loglevel = 0 then do totlen = c2d(charin(infile,,4),4) /* Read record length */ data = charin(infile,,totlen) /* Read <totlen> data */ parse var data ldate +4 ltime +3 machine (fsep) handle (fsep) , name (fsep) +1 level +4 message if datatype(c2d(ldate),'X') = 0 | datatype(c2d(level),'X') = 0 then call STAFExit MakeSTAFResult(errorBadLog, errorBadLog.!text": "originfile) end otherwise call STAFExit MakeSTAFResult(errorBadLog, errorBadLog.!text": "originfile) end longlevel = level select = ValidateLogRecord() /* See if matched query criteria */ if type = "QUERY" then do if select = 1 then do call ProcessSelectedRecord /* Record selected */ if first > '' & selcount = first then leave /* Got all we need */ end else if select = 2 then leave /* Date range passed, time to leave */ end else do if loglevel = 0 then /* Save old non-purged records in new format */ do data = machine || fsep || handle || fsep || name || fsep || message totlen = dbwidth(machine) + dbwidth(handle) + dbwidth(name) + dbwidth(message) + 3 end totalcount = totalcount + 1 if first > '' then selcount = selcount + 1 if select = 0 | (first > '' & selcount > first) then do rc = charout(newfile, d2c(latestlevel,1) || d2c(ldate,4) || , d2c(ltime,3) || longlevel || d2c(totlen,4) || data) if rc \= 0 then call STAFExit MakeSTAFResult(STAFError.!FileWriteError, , STAFError.!FileWriteError.!text": "newfile) end else purgecount = purgecount + 1 end end if type = "PURGE" then do if purgecount = totalcount then rc = MakeSTAFResult(errorPurge, errorPurge.!text) else do call stream newfile, "c", "close" call stream infile, "c", "close" '@copy' newfile infile '>nul 2>nul' /* FIX to charin/charout */ call SysFileDelete newfile if rc \= 0 then call STAFExit MakeSTAFResult(STAFError.!FileWriteError, , STAFError.!FileWriteError.!text": "infile) rc = MakeSTAFResult(STAFError.!Ok, purgecount"/"totalcount) end end else /* Build Query Output */ do call stream infile, "c", "close" if stats then do i = 32 to 1 by -1 if statsarray.i > 0 then do statsmask = substr('0', 1, 32, '0') statsmask = overlay('1', statsmask, i) logdata = logdata || ResolveLevel(statsmask)"="statsarray.i || linesep end end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -