From: Michael on
Hi,

Is there a way to catch the error time and sas programs, which
generates the errors?

Thanks a lot,
Mike
From: Chris Jones on
On 1 Dec, 08:56, Michael <michae...(a)gmail.com> wrote:
> Hi,
>
> Is there a way to catch the error time and sas programs, which
> generates the errors?
>
> Thanks a lot,
> Mike

One method is to use PROC PRINTTO log="<programname>.log" ; RUN; to
output the log, then have a generic process to read all the logs back,
parsing them for ERROR: and WARNING: lines.

As for the error time... you'd need a way of outputting the current
time at each run;/quit; boundary - you could simply use a %PUT
statement each time, but there may be a SAS option which does this,
although I'm not aware of it if it does exist!
From: Michael Raithel on
Dear SAS-L-ers,

In his very helpful response to another SAS-L Mike (man, there are millions of us, "Mikes" out there, aren't there?!?!?), Chris Jones posted the following:

>
> One method is to use PROC PRINTTO log="<programname>.log" ; RUN; to
> output the log, then have a generic process to read all the logs back,
> parsing them for ERROR: and WARNING: lines.
>
> As for the error time... you'd need a way of outputting the current
> time at each run;/quit; boundary - you could simply use a %PUT
> statement each time, but there may be a SAS option which does this,
> although I'm not aware of it if it does exist!

Chris, following up on the latter part of your reply, in SAS 9.2 the date/time is printed after every SAS step when the FULLSTIMER option is enabled. Here is a simple example for our friend, the other Mike:

1 options fullstimer;
2
3 proc print data=sashelp.class;
4 run;

NOTE: There were 19 observations read from the data set SASHELP.CLASS.
NOTE: PROCEDURE PRINT used (Total process time):
real time 1.50 seconds
user cpu time 0.03 seconds
system cpu time 0.01 seconds
Memory 840k
OS Memory 5744k
Timestamp 12/2/2009 8:24:18 AM

Since the OP was a bit light on the specifics of what, exactly, he wanted to do (which is very uncharacteristic for a "Mike"), perhaps harvesting that Timestamp will suffice for his purposes.

Chris, best of luck in all of your SAS endeavors!


I hope that this suggestion proves helpful now, and in the future!

Of course, all of these opinions and insights are my own, and do not reflect those of my organization or my associates. All SAS code and/or methodologies specified in this posting are for illustrative purposes only and no warranty is stated or implied as to their accuracy or applicability. People deciding to use information in this posting do so at their own risk.

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Michael A. Raithel
"The man who wrote the book on performance"
E-mail: MichaelRaithel(a)westat.com

Author: Tuning SAS Applications in the MVS Environment

Author: Tuning SAS Applications in the OS/390 and z/OS Environments, Second Edition
http://www.sas.com/apps/pubscat/bookdetails.jsp?catid=1&pc=58172

Author: The Complete Guide to SAS Indexes
http://www.sas.com/apps/pubscat/bookdetails.jsp?catid=1&pc=60409

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Infinities and indivisibles transcend our finite understanding,
the former on account of their magnitude, the latter because
of their smallness; Imagine what they are when combined. - Galileo Galilei
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
From: Michael on
On Dec 2, 9:34 pm, michaelrait...(a)WESTAT.COM (Michael Raithel) wrote:
> Dear SAS-L-ers,
>
> In his very helpful response to another SAS-L Mike (man, there are millions of us, "Mikes" out there, aren't there?!?!?), Chris Jones posted the following:
>
>
>
> > One method is to use PROC PRINTTO log="<programname>.log" ; RUN; to
> > output the log, then have a generic process to read all the logs back,
> > parsing them for ERROR: and WARNING: lines.
>
> > As for the error time... you'd need a way of outputting the current
> > time at each run;/quit; boundary - you could simply use a %PUT
> > statement each time, but there may be a SAS option which does this,
> > although I'm not aware of it if it does exist!
>
> Chris, following up on the latter part of your reply, in SAS 9.2 the date/time is printed after every SAS step when the FULLSTIMER option is enabled..  Here is a simple example for our friend, the other Mike:
>
> 1    options fullstimer;
> 2
> 3    proc print data=sashelp.class;
> 4    run;
>
> NOTE: There were 19 observations read from the data set SASHELP.CLASS.
> NOTE: PROCEDURE PRINT used (Total process time):
>       real time           1.50 seconds
>       user cpu time       0.03 seconds
>       system cpu time     0.01 seconds
>       Memory                            840k
>       OS Memory                         5744k
>       Timestamp            12/2/2009  8:24:18 AM
>
> Since the OP was a bit light on the specifics of what, exactly, he wanted to do (which is very uncharacteristic for a "Mike"), perhaps harvesting that Timestamp will suffice for his purposes.
>
> Chris, best of luck in all of your SAS endeavors!
>
> I hope that this suggestion proves helpful now, and in the future!
>
> Of course, all of these opinions and insights are my own, and do not reflect those of my organization or my associates. All SAS code and/or methodologies specified in this posting are for illustrative purposes only and no warranty is stated or implied as to their accuracy or applicability. People deciding to use information in this posting do so at their own risk.
>
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> Michael A. Raithel
> "The man who wrote the book on performance"
> E-mail: MichaelRait...(a)westat.com
>
> Author: Tuning SAS Applications in the MVS Environment
>
> Author: Tuning SAS Applications in the OS/390 and z/OS Environments, Second Editionhttp://www.sas.com/apps/pubscat/bookdetails.jsp?catid=1&pc=58172
>
> Author: The Complete Guide to SAS Indexeshttp://www.sas.com/apps/pubscat/bookdetails.jsp?catid=1&pc=60409
>
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> Infinities and indivisibles transcend our finite understanding,
> the former on account of their magnitude, the latter because
> of their smallness; Imagine what they are when combined. - Galileo Galilei
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Thanks go to Mike and Chris.

Just wondering whether you have some samples to parse errors? Or is
there a system parameter to read _Error_ = 1 or 0 to figure out
whether the programs have run successfully? If there is a system
parameter, the job would be much easier. Any hints on this one?

Thanks,
Mike
From: xlr82sas on
On Dec 3, 5:36 pm, Michael <michae...(a)gmail.com> wrote:
> On Dec 2, 9:34 pm, michaelrait...(a)WESTAT.COM (Michael Raithel) wrote:
>
>
>
>
>
> > Dear SAS-L-ers,
>
> > In his very helpful response to another SAS-L Mike (man, there are millions of us, "Mikes" out there, aren't there?!?!?), Chris Jones posted the following:
>
> > > One method is to use PROC PRINTTO log="<programname>.log" ; RUN; to
> > > output the log, then have a generic process to read all the logs back,
> > > parsing them for ERROR: and WARNING: lines.
>
> > > As for the error time... you'd need a way of outputting the current
> > > time at each run;/quit; boundary - you could simply use a %PUT
> > > statement each time, but there may be a SAS option which does this,
> > > although I'm not aware of it if it does exist!
>
> > Chris, following up on the latter part of your reply, in SAS 9.2 the date/time is printed after every SAS step when the FULLSTIMER option is enabled.  Here is a simple example for our friend, the other Mike:
>
> > 1    options fullstimer;
> > 2
> > 3    proc print data=sashelp.class;
> > 4    run;
>
> > NOTE: There were 19 observations read from the data set SASHELP.CLASS.
> > NOTE: PROCEDURE PRINT used (Total process time):
> >       real time           1.50 seconds
> >       user cpu time       0.03 seconds
> >       system cpu time     0.01 seconds
> >       Memory                            840k
> >       OS Memory                         5744k
> >       Timestamp            12/2/2009  8:24:18 AM
>
> > Since the OP was a bit light on the specifics of what, exactly, he wanted to do (which is very uncharacteristic for a "Mike"), perhaps harvesting that Timestamp will suffice for his purposes.
>
> > Chris, best of luck in all of your SAS endeavors!
>
> > I hope that this suggestion proves helpful now, and in the future!
>
> > Of course, all of these opinions and insights are my own, and do not reflect those of my organization or my associates. All SAS code and/or methodologies specified in this posting are for illustrative purposes only and no warranty is stated or implied as to their accuracy or applicability. People deciding to use information in this posting do so at their own risk.
>
> > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> > Michael A. Raithel
> > "The man who wrote the book on performance"
> > E-mail: MichaelRait...(a)westat.com
>
> > Author: Tuning SAS Applications in the MVS Environment
>
> > Author: Tuning SAS Applications in the OS/390 and z/OS Environments, Second Editionhttp://www.sas.com/apps/pubscat/bookdetails.jsp?catid=1&pc=58172
>
> > Author: The Complete Guide to SAS Indexeshttp://www.sas.com/apps/pubscat/bookdetails.jsp?catid=1&pc=60409
>
> > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> > Infinities and indivisibles transcend our finite understanding,
> > the former on account of their magnitude, the latter because
> > of their smallness; Imagine what they are when combined. - Galileo Galilei
> > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>
> Thanks go to Mike and Chris.
>
> Just wondering whether you have some samples to parse errors? Or is
> there a system parameter to read _Error_ = 1 or 0 to figure out
> whether the programs have run successfully? If there is a system
> parameter, the job would be much easier. Any hints on this one?
>
> Thanks,
> Mike- Hide quoted text -
>
> - Show quoted text -

Hi SAS-Lers,

This is a little complex but quite powerful. If you call a meta data
collector macro at the end of the batch job you can collect many
system macro variables and if you have a registerd TLA associated with
the job you can read and update the meta data repository with key
information like the start and end time of job.

I call this macro at the end of my batch jobs %mta(als,on); /*
'als' points to the registry for the als project and 'on' - on means
update meta data some programmers do want every batch run captured in
the meta data */

Here is what the mta macro does

1. Update the meta data with key job stats
2 Close the log
3. Read the log for key information like data modification
dates
4. Run log scrubbers on the closed log for errors and
warnings - update meta data
5. Open the log and add a summary to the end of the log
6. Close the log

I will eventually post most of the meta tools on my site.

Here are some code snippits (to give you an idea of what I do )

%Macro mta(tla,status) / des="Build meta data repository";

%if "%left(%sysfunc(getoption(%quote(SYSIN))))" ne "" %then %do; /*
only collect for batch runs not interactive runs */


OPTIONS
NOSOURCE /* turn sas source statements off */
NOMACROGEN /* turn MACROGENERATON off */
NOSYMBOLGEN /* turn SYMBOLGENERATION off */
NONOTES /* turn NOTES off */
NOSOURCE2 /* turn SOURCE2 show gererated source off */
NOMLOGIC /* turn MLOGIC macro logic off */
NOMPRINT /* turn MPRINT macro statements off */
NOCENTER /* turn NOCENTER I do not like centering */
NOMTRACE /* turn MTRACE macro tracing */;
run;

filename zrqtn catalog "work.savlog.savlog.catams";

/* close log so it can be read it */
proc printto log=zrqtn print="/dev/null";
run;
proc sql;
select
distinct
catx(' ',libname,path) into :&tla._libpth1
- :&tla._libpth99
from
sashelp.vlibnam
;quit;


/* read the log for datasets read or written
*/
data dtmtry.ddt_dtminpout;
infile "&log";
input;
file print;
infile=lowcase(_infile_);
if prxmatch("/&ref../",infile)>0 then put _infile_;;
run;

/* Run the PERL logcheck program on log */
filename ztqaxy pipe "/usr/xxxx/tools/check &log";
data chkdup;
infile ztqaxy;
input;
out=_infile_;
run;
filename ztqaxy clear;

/* run my logscrub */
%utl_batchk(&log);

/* macro to get creation dates
*/
%macro credte
(que);
rec
+1;
id = open
(libdsn,'i');
pth=pathname(scan(libdsn,
1,'.'));
dte=put(attrn
(id,'crdte'),best22.);
dtepth=cats
(dte,'@',pth,'@',libdsn);
call symputx("&que"!!put(rec,3. -
l),dtepth);
rc = close
(id);
%mend
credte;

/* much faster - gets all outputs but misses a few inputs quite
fast */
data ddt_dtminpout
(keep=dtepth);
retain rec
0 ;
length dtepth
$300;
infile
"&log";

input;
infile=lowcase
(_infile_);
file
print;
if substr(left(infile),1,4)='note' then
do;

select;
when (substr(infile,7,5) eq 'table' and substr(infile,
13,4) ne 'work') do;
libdsn=scan(infile,3,'
');
%credte
(dtm_dsnout);

end;
when (substr(lowcase(infile),7,12) eq 'the data set' and
substr(left(substr(infile,20,5)),1,4) ne 'work') do;
libdsn=scan(infile,5,'
');
%credte
(dtm_dsnout);

end;
when (index(infile,'read from the data set')>0 and index
(infile,'work')=0) do;
libdsn=scan(infile,11,'
');
libdsn=substr(libdsn,1,length(libdsn)-1); /* remove
sentence period */
%credte
(dtm_dsninp);

end;

otherwise ;

end;

end;

run;

%put
_user_;

%let &tla._sqlrc =&sqlrc;
%let &tla._sysday =&sysday;
%let &tla._sysjob =&sysjobid;
%let &tla._sysmac =&sysmacroname;
%let &tla._sysscp =&sysscp;
%let &tla._sysrc =&sysrc;
%let &tla._sysusr =&sysuserid;
%let &tla._syserr =&syserr;
%let &tla._sysver =&sysvlong;
%let &tla._engine =%sysfunc(getoption(%quote(engine)));
%let &tla._sysin =%substr(%sysfunc(getoption(%quote
(sysin))),10);
%let &tla._sysinfo =&sysinfo;
%let &tla._syslast =&syslast;
%let &tla._sysindex =&sysindex;
%let &tla._fmtsearch =%sysfunc(getoption(fmtsearch));
%let &tla._sasautos =%sysfunc(getoption(sasautos));
%let &tla._sqlobs =&sqlobs;
%let &tla._sqloops =&sqloops;
%let &tla._sysodspath =&sysodspath;
%let &tla._sqlobs =&sqlobs;
%let &tla._sqlxobs =&sqlxobs;
%let &tla._syslckrc =&syslckrc;
%let &tla._sysmsg =&sysmsg;
%let &tla._sysprocessname =&sysprocessname;
%let &tla._sysfilrc =&sysfilrc;
%let &tla._syslibrc =&syslibrc;

%let &tla._datetime =%sysfunc(datetime());
%let &tla._pgm=%scan(%getfyl(%sysfunc(getoption(%quote(sysin)))),
1,%str(.));
%let &tla._validation=v_%substr(&pgm,5);

proc sql noprint;
select count(*) into :&tla._numfot from sashelp.vtitle where
type='f';
select count(*) into :&tla._numtyt from sashelp.vtitle where
type='t';
%if &&&tla._numfot ne 0 %then %do;
select trim(text) into :&tla._fot1 - :&tla._fot%left
(&&&tla.._numfot) from sashelp.vtitle where type='F';
%end;
%if &&&tla._numtyt ne 0 %then %do;
select trim(text) into :&tla._tyt1 - :&tla._tyt%left
(&&&tla.._numtyt) from sashelp.vtitle where type='T';
%end;
quit;

data _null_;
length xpath $200 fileref $16;
set sashelp.vextfl;
fileref=cats(%upcase("&tla._"),compress(fileref,'#'));
call symputx(fileref,xpath);
run;

%let &tla._pthlst=%sysfunc(pathname(%scan(&syslast,1,%str(.))));
%let &tla._pthend=%sysfunc(pathname(%scan(&syslast,1,%str(.))))/
%scan(&syslast,2,%str(.)).sas7bdat;

data _null_;
length lib $200;
set sashelp.voption(where=(optname='FMTSEARCH'));
str=compress(setting,'()');
fmtnum=countc(strip(str),' ');
do i=1 to fmtnum;
lib=pathname(scan(scan(str,i,' '),1,'.'));
call symputx("&tla._fmtlib"!!put(i,2. -l),lib);
end;
stop;
run;

data _null_;
length lib $200;
set sashelp.voption(where=(optname='SASAUTOS'));
str=compress(setting,'()"');
str=compbl(strip(str));
fmtnum=countc(strip(str),' ');
do i=1 to fmtnum;
lib=scan(str,i,' ');
call symputx("&tla._sasautos"!!put(i,2. -l),lib);
end;
stop;
run;

filename qr54zt pipe "lu &sysuserid";
data _null_;
infile qr54zt length=l missover;
input buf $varying200. l;
if _n_=2 then do;
FulNam=compress(substr(buf,index(buf,'is')+3),'.');
call symput("&tla._FulNam",trim(left(FulNam)));
end;
run;
filename qr54zt clear;

Data &tla._Mta(
Label="Get Meta Data from SAS Macro Dictionary"
Keep=Tla Program Question MacroCall RunTime
MacroRunTime Answer
) ;

Retain MacroRunTime 0;
Length TLA $3 Program Question $32 MacroCall RunTime
MacroRunTime 8 Answer $4096;
Set SasHelp.vmacro ( Where= ( upcase(name) =: upcase
("&tla._")) ) ;
TLA=upcase("&tla.");
Program=upcase("&&&tla._Pgm");
MacroCall=&sysindex;
Question=Name;
RunTime=input("&&&tla._datetime",best22.); /* have to do this
because of repeated calls inside macro */
if _n_=1 then MacroRunTime=Datetime();
Answer=left(Compbl(Resolve(Value)));
Run;

Proc Append
Base=&tla.try.&tla._Mta
(
Label="Master Meta data for the &tla project"
compress=yes
)
Data=&tla._Mta
Force;
Run;

/* put communications and results of log scrub at the end of the
log - extract from meta data repsitory
*/
proc
sql;

create
table logfnd
as

select

question
,answer

from

&tla.mta.mta

where
question eqt "DTM_DSN"
or
question eqt "DTM_COM"
or
question eqt "DTM_CHK"
or
countc(question,'_')
=2

order
by
question
;quit;

proc
printto;

run;
/* open the log and append useful information to the end of the
log
*/
proc printto print="/dev/null"
log="&log";

run;


page;

data
_null_;
set logfnd
end=dne;
if _n_=1 then
do;
putlog
"*************************************************************************************************************************";
putlog
"*
*";
putlog "* Summary of ACHME Check program and Important
communications
*";
putlog
"*
*";
putlog
"*************************************************************************************************************************";

putlog /;

end;
if question in ("DTM_CHKERR1" "DTM_CHKERR2") then
delete;
if question=: "DTM_DSN" then
do;
mtadte=input(scan(answer,
1,'@'),best22.);
dataset=scan(answer,
3,'.');
if question=:'DTM_DSNOUT' then
do;
answer=catx(' ',dataset,'dataset with creation date',put
(mtadte,datetime18.),'was created by this
program');

end;
else if question=: 'DTM_DSNINP' then
do;
answer=catx(' ',dataset,'dataset with creation date',put
(mtadte,datetime18.),'was used as input by this
program');

end;

end;
putlog question @24
answer;
if dne then
do;

putlog /;
putlog
"*************************************************************************************************************************";
putlog
"*
*";
putlog "* End of Summary of ACHME Check program and
Important
communications
*";
putlog
"*
*";
putlog
"*************************************************************************************************************************";

end;

run;

%end;

SAMPLE of wht can be put at the end of the log

*************************************************************************************************************************
*
*
* Summary of ACME Check program, Important communications and dataset
creation dates *
*
*
*************************************************************************************************************************

ALS_PRODLOG /
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/
mtaaft.log
ALS_RUNTIME
26NOV2008:14:06:03

ALS_CHKERR3 [line 645] ERROR: GENMOD did not
converge
ALS_CHKERR4 [line 680] NOTE: Variable CONSNTDTC is
uninitialized.
ALS_CHKERR5 [line 695] NOTE: Invalid second argument to
function SUBSTR at line 1426 column 5.

ALS_COM2 error in log can be ignored - convergence issue
with GENMOD - Per xxxxxxx
ALS_COM1 hardcode subject 890136 back into study, was
hardcoded out in legacy study.xxxxxxx wants all subjects to be ITT
ALS_COM3 Algorithm for ITT changed see email from xxxxxx
02feb2009 16:41
ALS_DM_ITT Subject is ITT if randomized and has informed
consent
ALS_DM_SAF Subject is SAFETY Evaluable if randomized, has
informed consent and is dosed

ALS_DSNINP2 xxxxxxxxxx dataset with creation date
23FEB09:18:22:29 was used as input by this
program
ALS_DSNOUT1 xxxxxxxxx dataset with creation date
24FEB09:12:34:08 was created by this
program
ALS_DSNOUT3 xxxxxxxxxxxx dataset with creation date
24FEB09:12:34:09 was created by this
program

Validation Programmer:
xxxxxxxxxxxxxxxxx

I certify that the production program and log above follow the
SAP and DDT, program and log follow ACHME SOPs and
that the results are correct. For complete details for this
object and all other 'als' objects run SAS view als_view

Signature
__________________________________



*************************************************************************************************************************
*
*
* End of Summary of ACHME Check program and Important
communications
*
*
*
*************************************************************************************************************************