Yes, MPEX can do this...
DISCLAIMERS-UP-THE-YIN-YANG: this command/expression program is NOT
SUPPORTED IN ANY WAY by ANYONE with more than a smattering of interest in
the HP3000 -- not me, VESOFT, HP, or even the tooth fairy!
This command/expression program makes use of features in the VESOFT/MPEX
Expression programming language that are NOT DOCUMENTED, and, therefore, are
SUBJECT TO CHANGE WITHOUT NOTICE -- if VESOFT upgrades MPEX and this stops
working, well....
This command/expression program is BASED upon the DOCUMENTED "features" of
NSD's JobRescue, however NOT ALL FEATURES were implemented -- just those
that met our particular needs. [unused keywords are ignored] This is also
the features documented nearly 5 years ago, so I suspect vast improvements
in the commercial package have been made since...
First file: autop3k.CMD22.VESOFT <--- note the location of where this
resides
[keep with file code=171]
---------------- cut here -----------------------
var numtocheck:integer;
var numtoskip:integer;
var phrases:string[2048];
var phrasei:array[128] of integer;
var phrasel:array[128] of integer;
var phrasenum:integer;
var skipphrases:string[2048];
var skipi:array[128] of integer;
var skipl:array[128] of integer;
var skipnum:integer;
var grec:string[256];
var e:integer; (* global variable to hold "errlines" fnum *)
var errcount:integer;
var anyerror:boolean;
var fj:string[16];
var currentjob:string[80];
var spoolf:string[16];
var bypass:boolean;
var emailaddress:string[64];
var boothill:boolean; (* flag to indicate TOMBSTONE tests are performed *)
(* ----------- Reporting/maintenance functions ---------- *)
subroutine notifyoperator(rd:value string; rt:value string;
email:value string; host:value string;
originator:value string);
var f:integer;
var b:string[80];
var w:string[8];
begin
mpe("tellop "+chr(27)+"&dCATTENTION: "+20*(chr(7)+"*"));
mpe("tellop "+chr(27)+"&dCATTENTION: "+CHR(27)+"&dB"+
"Autopsy/3000 detected an");
mpe("tellop "+chr(27)+"&dCATTENTION: "+CHR(27)+"&dB"+
"error in "+fj+" ("+currentjob+")");
mpe("tellop "+chr(27)+"&dCATTENTION: "+CHR(27)+"&dB"+
"See "+spoolf+".SPOOLBAD.SYS");
mpe("tellop "+chr(27)+"&dCATTENTION: "+20*(chr(7)+"*"));
mpe("%warnf operator.sys;Autopsy/3000 detected an error in "+
fj+" ("+currentjob+") -- see "+spoolf+".SPOOLBAD.SYS");
w:=randomname;
while fexists(w) do w:=randomname;
f:=vefopen(w+",old;maybuild;rec=-132,,v,ascii;acc=out");
vefwrite(f,78*'*');
vefwrite(f,strwrite("*** ",
"C O R O N E R ' S R E P O R T":70:'center',
" ***"));
vefwrite(f,78*'*');
for b in file (strchange(spoolf,"o","e")+'.SPOOLBAD.SYS,old')
Do vefwrite(f,b);
vefclose(f);
(* e-mailer command below -- modify as needed for e-mail system *)
if email <> "<undefined>" then
mpe("%insendfl.cmd.sys "+w (* file *)
+","+email+"@"+host (* recipient *)
+',"'+currentjob+' ('+fj+') Aborted: '+rt+'"' (* subject *)
+","+originator (* sender (orig job) *)
+",Coroner@"+HPSYSNAME (* sender's alias *)
+",[log in to unmask]"); (* reply-to address *)
mpe("purge "+w);
end;
subroutine savespoolfile(f:value string; g:value string);
begin
mpe("PURGE "+f+'.'+g+'.sys'); (* OK to overwrite outdated STDLIST *)
vefclose(vefopen(f+"."+g+".sys,old;maybuild;disc="+strwrite(
vefinfo(f+".out.hpspool").eof)+";rec=-132,,v,ascii"));
mpe("file spoolsav="+f+"."+g+".sys,old");
if mpe("print "+f+".out.hpspool;out=*spoolsav;page=0")<>0 then
mpe("echo Autopsy/3000 unable to copy "+f+" to "+g)
else begin
(* mpe("deletespoolfile #"+f); *)
end;
mpe("reset spoolsav");
end;
subroutine logstatus (bad:boolean; rd:value string; rt:value string);
begin
vefwrite ('spoollog.pub.sys,old;maybuild;rec=-80,,f,ascii;disc=1000;cir'+
';acc=append',
strwrite(spoolf:7,'|',fj:7,'|',currentjob:26,'|',rd,'-',rt,'|',
(IF BAD THEN " ERR!" ELSE "") ) );
end;
(* ----------------- Scanning functions ----------------- *)
subroutine checktest (r:value string; c:boolean);
begin
if (r MATCHES "@COMMANDSIGNOREDUNTILMATCHING@") then
c:=false;
if (r matches "@RESUMEEXECUTION@") then
c:=TRUE;
end;
subroutine tombstarttest (r:value string; c:boolean);
begin
if (r MATCHES "@F-I-L-E---I-N-F-O-R-M-A-T-I-@") then
c:=true;
end;
subroutine tombendtest (r:value string; c:boolean);
begin
if (r matches "@----------------------------@") then
c:=false;
end;
subroutine testrec(r:value string; p:value string);
begin
pos(p,ups(r))<>0
end;
subroutine CheckMailRedirect(r:value string);
begin
if (r MATCHES "@QUINCY=@") then begin
emailaddress:=REMTOKEN(r,"=");
writeln("Redirecting e-mail to "+Emailaddress);
end;
end;
subroutine test (r:value string; ae:boolean; c:boolean; t:boolean;
rd:value string; rt:value string);
var le:boolean; (* "local" error flag *)
var tp:integer;
begin
checktest(r,c);
if c then begin
le:=false;
for tp in range(1,phrasenum,1) do
le:=le or testrec(r,phrases[phrasei[tp]:phrasel[tp]]);
if le then
for tp in range(1,skipnum,1) do
if testrec(r,skipphrases[skipi[tp]:skipl[tp]]) then
le:=false;
if le or t then begin
if not ae then begin
writeln ('Autopsy/3000: Found errors in ',currentjob);
MPE ("PURGE "+strchange(spoolf,"o","e")+".SPOOLBAD.SYS");
e:=vefopen (strchange(spoolf,"o","e")+'.SPOOLBAD.SYS,'+
'old;maybuild;rec=-256,,v,ascii;acc=out');
vefwrite(e,"Autopsy/3000 detected an error in "+fj+
" ("+currentjob+")");
vefwrite(e,"This job completed at: "+rt+" on "+rd);
vefwrite(e,"The error(s) were:");
errcount := 0;
end;
if errcount < 100 then begin
writeln ("Autopsy/3000: ",grec:'garbage');
vefwrite(e,strwrite(grec:'garbage'));
end;
errcount := errcount + 1;
ae:=true;
end;
CheckMailRedirect(r);
end;
end;
subroutine scan(rd:value string; rt:value string);
var rectocheck:string[256];
var anyerror:boolean;
var checking:boolean;
var tombstone:boolean;
begin
anyerror:=false;
checking:=true;
tombstone:=false;
for grec in file(spoolf+".out.hpspool,old") do begin
rectocheck:=ups(strchange(grec," ",""));
if BOOTHILL then
tombstarttest(rectocheck,tombstone);
test(rectocheck,anyerror,checking,tombstone,rd,rt);
tombendtest (rectocheck,tombstone);
end;
anyerror or false
end;
(* --------------- initialization routines -------------- *)
subroutine getphrases;
var line:string[256];
VAR T: STRING[256];
VAR J:STRING[256];
VAR PHRASE: STRING[256];
VAR GLOBAL:BOOLEAN; (* if true, applies to ALL $STDLISTS *)
VAR LOCAL:BOOLEAN; (* if true, applies to CURRENT $STDLIST *)
(* if BOTH false, does not apply... *)
var x:integer;
BEGIN
GLOBAL := TRUE;
LOCAL := FALSE;
BYPASS := FALSE;
phrases:="";
skipphrases:="";
emailaddress:="<undefined>@<nowhere>";
boothill := TRUE;
phrasenum:=0;phrasei[0]:=0; phrasel[0]:=0;
skipnum:=0; skipi[0]:=0; skipl[0]:=0;
for line in file ('OPTIONS.DATA.VESOFT,OLD')
do if not bypass then begin
line:=strrtrim(line);
T:=UPS(TOKEN(LINE," "));
IF GLOBAL THEN BEGIN
IF T="$DEFINE" THEN BEGIN
IF UPS(NTOKEN(LINE,2," "))="JOB" THEN BEGIN
GLOBAL := FALSE;
J:=UPS(REMTOKEN(REMTOKEN(LINE," ")," "));
LOCAL := (currentjob MATCHES J);
END;
END;
END;
IF NOT GLOBAL THEN BEGIN
IF T="$DEFINE" THEN BEGIN
IF UPS(NTOKEN(LINE,2," "))="END" THEN BEGIN
GLOBAL := TRUE;
LOCAL := FALSE;
END;
END;
END;
IF GLOBAL OR LOCAL then begin
IF T='$PHRASE' OR T='$ERROR' THEN BEGIN
PHRASE:=UPS(REMTOKEN(LINE," ")); (* UPSHIFT remainder of line
*)
PHRASE:=STRCHANGE(PHRASE," ",""); (* REMOVE spaces *)
phrasenum:=phrasenum+1;
phrases:=phrases+phrase;
phrasei[phrasenum]:=phrasei[phrasenum-1]+phrasel[phrasenum-1];
phrasel[phrasenum]:=len(phrase);
end;
if T='$NOERROR' THEN BEGIN
PHRASE:=UPS(REMTOKEN(LINE,' '));
PHRASE:=STRCHANGE(PHRASE," ",""); (* REMOVE spaces *)
skipnum:=skipnum+1;
skipphrases:=skipphrases+phrase;
skipi[skipnum]:=skipi[skipnum-1]+skipl[skipnum-1];
skipl[skipnum]:=len(phrase);
end;
if T="$BYPASS" then begin
J:=UPS(REMTOKEN(LINE,' '));
IF currentjob matches J then
bypass:=true;
end;
IF T="$NOTIFY" THEN BEGIN
IF emailaddress="<undefined>@<nowhere>" or LOCAL then
emailaddress:=REMTOKEN(LINE," ");
end;
if T="$NO-TOMBSTONE" then begin
(* For this job (or all jobs if GLOBAL), do NOT check *)
(* for tombstones. OPTIONS should include error lines *)
(* from tombstone such as "ERROR NUMBER:" or "FILE NAME:" *)
boothill := FALSE;
end;
end;
end;
END;
subroutine MainLine;
VAR RF: TFILECOMBINED; (* SUSPECT *)
var emailuser:string[32];
var emailhost:string[32];
begin
SVARSET ("MPEXFILESET", (* SUSPECT *)
TOKEN(VEPARMS,";")+
(IF UPS(RHT(VEPARMS,6))=":SPOOL" THEN "" ELSE ":SPOOL"));
WITH RF DO begin
FOR RF IN DIRFILESMPEX (SVAR ("MPEXFILESET"),907,0,908,0,909,0)
DO BEGIN
currentjob:=spool.fmtlogon;
spoolf:=strwrite('o',spool.spoolfilenum);
fj:=spool.fmtjob;
bypass:=(spool.file<>'$STDLIST'); (* don't check/move reports, etc.
*)
if not bypass then getphrases;
if bypass then
writeln ("-----Bypassing: #",SPOOLF, ": ",currentjob,
(if spool.file<>'$STDLIST' then " (not a $STDLIST)" else
""))
else begin
writeln ("-----Processing: #",SPOOLF, ": ",currentjob);
try
anyerror:=scan(strwrite(spool.readydate),strwrite(spool.readytime))
;
recover anyerror:=true;
if anyerror then begin
if errcount>99 then begin
vefwrite(e,"Coroner's Warning: too many error lines!");
vefwrite(e," 100 lines displayed, "+strwrite(errcount)
+" 'error' lines counted");
end;
vefclose(e,"SQUEEZE;xltrim");
emailuser:=token(emailaddress,"@");
emailhost:=remtoken(emailaddress,"@");
if emailhost="" then emailhost:=hpsysname;
notifyoperator(strwrite(spool.readydate),
strwrite(spool.readytime),
emailuser,emailhost,
spool.jobname+"!"+spool.user+"."+spool.account+"@"+hpsysname);
(* savespoolfile(spoolf,"spoolbad"); *)
end else begin
(* savespoolfile(spoolf,"spoolok"); *)
end;
logstatus(anyerror,
strwrite(spool.readydate),
strwrite(spool.readytime));
end;
end;
end;
END;
(* real "main line" *)
MainLine;
-------------------- cut here -------------------
second file you need:
INSENDFL.CMD.SYS <--- the location for this can be changed, but note the
above routine makes an explicit reference to this at this location. If you
move it, update the above expression program to match
-------------------- cut here -------------------
var BUFFER:string[256];
var SENDFILE:string[256];
var RECIPIENT:string[80];
var SUBJECT:string[50];
var SENDER:string[64];
var ALIAS:string[64];
var REPLY:string[64];
var GROUPMEMBER:string[80];
var GROUPtarget:string[80];
var dest:string[16];
var workfile:string[36];
var tempfile:integer;
subroutine feed(x:value string);
begin
vefwrite(tempfile,x);
end;
subroutine HEADER(s1:value string; s2:value string);
begin
feed(s1+":"+strrtrim(s2));
end;
subroutine FoldedHEADER(s2:value string);
begin
feed(" "+strrtrim(s2));
end;
subroutine PARSEPARMS;
begin
sendfile :=ntoken(veparms,1,",","'"""); (* $STDIN *)
recipient:=ntoken(veparms,2,",","'"""); (* [REQUIRED] *)
subject :=ntoken(veparms,3,",","'"""); (* defaults to filename *)
sender :=ntoken(veparms,4,",","'"""); (* defaults to u.a@machine *)
alias :=ntoken(veparms,5,",","'"""); (* defaults to sender *)
reply :=ntoken(veparms,6,",","'"""); (* only added if non-null *)
if (recipient = "") then begin
writeln("Usage:");
escapef("INSENDFL [file-to-send], recipient@address, [subject],"+
" [sender], [sender's alias], [reply-to]");
end;
if (sender="") then begin
sender:=hpuser+"."+hpaccount;
end;
if (alias="") then begin
alias:=sender;
end;
if (pos("@",sender)=0) then begin
sender := sender +"@"+hpsysname;
end;
if (subject="") then begin
subject:=sendfile; (* if using default sendfile, $stdin, *)
end; (* use null subject, otherwise filename *)
if (sendfile="") then begin
sendfile:="$STDIN";
end;
writeln ("-----Sending ", sendfile, " to ", recipient);
writeln ("from ", sender, " (using '", alias, "' as an alias)");
writeln ("Subject: ", subject);
if (reply<>"") then writeln("and redirecting responses to "+reply);
end;
subroutine PROCESSGROUPS;
var i:integer;
begin
i:=1;
FOR GROUPMEMBER IN FILE(RECIPIENT-"*"+",OLD") DO begin
dest:=ups(token(groupmember,":"));
grouptarget:=remtoken(groupmember,":");
if (i=1) then HEADER("TO",GROUPMEMBER)
else FoldedHeader(","+GroupMember);
i:=i+1;
end;
end;
subroutine PROCESS;
begin
writeln ("Loading message for ",recipient);
(* not needed for "internet" messages *)
(* HEADER("VERSION","3.00"); *)
HEADER("From",alias+" <"+SENDER+">");
if (reply <> "") then begin
HEADER("Reply-to",reply);
end;
HEADER("Date",STRWRITE(TODAY:'%1W, DD MMM YYYY') +
" " + STRWRITE(CLOCK:'%024h:%0m'));
HEADER("SUBJECT",SUBJECT);
IF (RECIPIENT[0:1] = "*") THEN
PROCESSGROUPS
ELSE
HEADER("To",RECIPIENT);
feed(""); (* CREATE the "seperator" line between headers & message *)
FOR BUFFER IN FILE(SENDFILE+",OLD")
DO feed(STRRTRIM(BUFFER));
feed("."); (* terminate the message *)
END;
BEGIN (* MAIN *)
PARSEPARMS;
(* create a temp file *)
workfile:=strwrite("/tmp/mailbag_",hppin:6:'zerofill');
tempfile:=vefopen(workfile+",old;maybuild;disc=999999;acc=append"+
";rec=-256,,v,ascii");
PROCESS;
vefclose(tempfile);
(* Now, "really" feed it to sendmail... *)
mpe("run sendmail.pub.sendmail;info='-t';stdin="+WORKFILE);
mpe("purge "+workfile);
END;
---------------- cut here -----------------------
Jobstream that pulls it all together:
%PRINT CORONER.JOB.SYS
---------------- cut here -----------------------
!job coroner,manager.sys,pub;outclass=,1
!mpex
%tellop *************************************
%tellop *** Autopsy/3000 ***
%tellop *** -- Beginning $STDLIST scan -- ***
%tellop *** Any job aborts reported MUST ***
%tellop *** be reviewed immedieately!!! ***
%tellop *************************************
%while true
%if fexists('lastrun.pub.sys') then
% setvar line vefread('lastrun.pub.sys,old')
%else
% setvar line strwrite(today:'MM/DD/YY','\',clock:"%24h:%0m","T")
%endif
%setvar day token(line,'\')
%setvar tyme remtoken(line,'\')
% autop3k @[log in to unmask]@((spool.readydate=!day and spool.readytime>!tyme) &
or spool.readydate>!day)
% calc vefwrite('lastrun.pub.sys,old;acc=out;maybuild;'+&
'rec=-80,,f,ascii;disc=1',&
strwrite(today:'MM/DD/YY','\',clock:"%24h:%0m","T"))
% pause 300
%endwhile
%exit
!eoj
---------------- cut here -----------------------
> -----Original Message-----
> From: Girard, Frank [mailto:[log in to unmask]]
> Sent: Monday, May 22, 2000 2:21 PM
> To: [log in to unmask]
> Subject: Error Trapping in a job stream.
>
>
> Is there any way to catch fatal errors in jobs that abort
> other than looking
> at the standard list -- sometimes hours later? Does MPEX have this
> capability? I'm looking to catch things like Missing Colon
> before command,
> Program ended in an error state: remainder of job flushed,
> and any others
> that happen because of an abnormal condition. The job stream
> itself is not
> being edited, the program is aborting on some data exception,
> or data base
> problem, like a user that did not get aborted by abortjob, and had a
> database that was being autoresized by Bradmark software. I
> want to send an
> E-mail through Kick Mail from the HP to our Operations center
> to notify them
> of the problem. The jobs don't get checked till 7:00 - 8:00
> AM when the job
> is usually done by.
>
> Thanks
>
> Frank Girard
> J. Baker Inc.
> [log in to unmask]
>
|