Log.mesa
Last modified by D. Swinehart, December 16, 1983 1:14 pm
Logging of errors and status reports; Spying for performance measurement
DIRECTORY
Basics USING [ BITAND ],
Commander USING [ Handle ],
IO USING [ STREAM ],
Rope USING [ ROPE ],
SpyLog USING [ Here ]
;
Log: CEDAR DEFINITIONS IMPORTS Basics, SpyLog = {
Variables
PD: TYPE = RECORD [
attended: BOOLEANFALSE,
sysIn: IO.STREAM,
sysOut: IO.STREAM, -- IOs for error and system status reporting
ch: Commander.Handle←NIL
];
pd: REF PD;
Types
ROPE: TYPE=Rope.ROPE;
Error, Information, Performance Logging
LogProc: TYPE = PROC[group: CARDINAL𡤁, info: LogInfo←[]];
LogInfo: TYPE = RECORD[
logCode: LogCode←none,
logD1: LONG CARDINAL𡤀,
logD2: LONG CARDINAL𡤀];
LogCode: TYPE = {
none, data, before, after, during, dataSmarts, dataParty, dataConv, lc1, lc2, lc3, lc4, lc5, lc6 };
loggingGroups: CARDINAL;
WriteData: PROC[info: LogInfo];
LOG: LogProc = TRUSTED INLINE {
IF Basics.BITAND[group, loggingGroups]#0 THEN {
WriteData[info]; SpyLog.Here[]; }; };
SLOG: PROC[group: CARDINAL𡤁] = TRUSTED INLINE {
IF Basics.BITAND[group, Log.loggingGroups]#0 THEN {
Noop[]; SpyLog.Here[]; }; };
Noop: PROC;
DoLog: PROC[groups: CARDINAL�];
Error reporting and management
Report finds an appropriate stream and prints a time-stamped version of remark. Clients can register procedures to interpret the WhereToReport atoms and obtain the appropriate stream for a given call, aided by the lead supplied in the Report call.
Problem is intended for reporting unexpected errors and conditions. It will raise the indicated signal, or an internal one by default, if the system is currently attended (there's an executive command.) In any case, it will report the remark argument. It will return automatically or if the operator proceeds from the signal, so the caller needs to do what is necessary to recover after calling Problem.
The other Problem... functions are for convenience in returning innocuous values from procedures.
The defaultIfNotFound parameter to the registration procedure indicates whether the message should be ignored (FALSE) or printed (TRUE) when the corresponding stream-finding procedure returns NIL.
WhereToReport: TYPE=ATOM;
ThHandle: TYPE = LONG CARDINAL -- Thrush.ThHandle --;
nullHandle: ThHandle = 0;
WhereProc: TYPE = PROC[fixedWhereData: REF, whereData: REF] RETURNS[s: IO.STREAMNIL];
DNFProc: TYPE = PROC[fixedWhereData: REF, whereData: REF] RETURNS[default: BOOL];
RegisterWhereToReport: PROC[
proc: WhereProc←NIL, where: WhereToReport, fixedWhereData: REFNIL, defaultIfNotFound: DNFProc←NIL];
IF defaultIfNotFound=NIL, answer assumed TRUE
FindWhere: PROC[where: WhereToReport, whereData: REF] RETURNS [s: IO.STREAMNIL];
Report: PROC[remark: ROPE, where: WhereToReport←NIL, whereData: REFNIL];
Problem: PROC[
remark: ROPENIL, where: WhereToReport←NIL, whereData: REFNIL];
ProblemBool: PROC[remark: ROPENIL, where: WhereToReport←NIL,
bool: BOOLFALSE, whereData: REFNIL]
RETURNS[sameBool: BOOL];
ProblemHandle: PROC[remark: ROPENIL, where: WhereToReport←NIL,
handle: ThHandle ← nullHandle, whereData: REFNIL]
RETURNS[sameHandle: ThHandle];
Command Logging, indirect execution.
Originally developed as part of ThMessageDBImpl
CLog: TYPE = REF CLogBody;
CLogBody: TYPE = RECORD [
logStream: IO.STREAM,
logReadPos: INT𡤀,
CommandProc: PROC[CLog]
CommandProc should consume any command in the log, such that if it's the last
command, we're at end of file
];
MakeCLog: PROC[fileName: ROPE, CommandProc: PROC[CLog]]
RETURNS[cLog: CLog];
WriteCLog: PROC[cLog: CLog, entry: ROPE];
DoCLog: PROC[cLog: CLog, entry: ROPE];
Write it at end, then read it and do it, using CommandProc
RedoCLog: PROC[cLog: CLog];
Typical thing to do after a MakeCLog, to replay an old one.
}.