Macro LogSave

From sasCommunity
Jump to: navigation, search

http://www.listserv.uga.edu/cgi-bin/wa?A2=ind0110d&L=sas-l&F=&S=&P=8887


  • Date: Mon, 22 Oct 2001 10:09:59 -0400
  • Reply-To: "Fehd, Ronald J." <rjf2@CDC.GOV>
  • Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
  • Subject: tip: macro LOGSAVE v1

Below is my next version of macro LOGSAVE.

I received several suggestions, and read further in the NESUG Li and Troxell paper for some NOTES to search for.

Changes and Enhancements:

LOGSAVE now has three steps: ON, OFF, and SCAN

  1. SCAN allows scanning for ERROR, and either of WARNING, or selected NOTES
  2. SCAN can be rerun on the log, searching for additional messages
  3. Previous Lines to ERROR/WARNING/NOTE are saved

I thought the rolling load of the PreviousLines with the mod function was a cute trick.

Note: see the difference between the upper and lower bounds

     and the variables allocated by the array.

Use the test data and enjoy!  ;-)

Macro LogSave

;/* LOGSAVE Log: Save and Read, Searching for ERROR & WARNING msgs
            if found send email
            else delete log and txt file
RJF2 01Oct05
NESUG 2001: Advanced Tutorials, pg 92 proc printto of log
SAS(r) Shorts: Valuable Tips for Everyday Programming
Jeff McCartner & Raymond Hu
NESUG 2001: Coders Corner, pg 317 reading log, other NOTEs to look for
Macro to Report Problematic SAS Log Messages
Tianshu Li and John K Troxell,
RJF2 01Oct19 polishing, can now turn off logsave and scan
;/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
%macro LOGSAVE(
 ACTION       /* in ON, OFF, SCAN                */
,WARNING  = 0 /* search for WARNINGs?            */
,NOTES    = 0 /* search for NOTEs?               */
,PREVLINES= 3 /* number of previous line to show */
);%*-------------------------------------------------------------------;
 
%IF "&ACTION." eq "ON" %THEN %DO;%*write log to file;
%*note %global PATH;
proc PRINTTO log = "&PATH.&PROGNAME..log"
             new;%*.  . . . . . . . . . . . . . . . %IF ACTION=ON; %END;
 
%ELSE %IF "&ACTION." eq "OFF" %THEN %DO;
%*close log file, read and search for ERROR or WARNING msgs;
proc PRINTTO;                                                       run;
%* . . . . . . . . . . . . . . . . . . . . . . . . %IF ACTION=OFF; %END;
%ELSE %IF "&ACTION." eq "SCAN" %THEN %DO;
%local ERRWARN;%LET ERRWARN =0;%*default: no ERR|WARN msgs found;
%local LRECL;  %LET LRECL   =%sysfunc(getoption(LINESIZE));
data _NULL_;
length Line $ &LRECL.
       FirstWord $ 7;
array Prev(0:%eval(&PREVLINES.)) $ &LRECL.;
      %*note: allocates PREV1-PREV(N+1)
                        not PREV0-PREV(N);
retain ErrWarn 0
       N       0
       Prev1-Prev%eval(&PREVLINES.+1) '.'
       ;
file LOG;
do until(EndoFile);
   infile "&PATH.&PROGNAME..log"
          end   = EndoFile
          lrecl = &LRECL. pad;
   input @1 Line $char&LRECL..;
%*echo log back to log;
if length(Line) then                    put @1 Line $char&LRECL..;
N+1;
Prev(mod(N,%eval(&PREVLINES.+1))) = Line;
FirstWord = scan(Line,1,':');
if                             FirstWord = 'ERROR'
   %IF &WARNING %THEN %DO; or  FirstWord = 'WARNING'               %END;
   %IF &NOTES   %THEN %DO; or (FirstWord = 'NOTE'
                               and
                           (  index(Line,'uninitialized')
                           or index(Line,'values have been converted')
                           or index(Line,'Missing values were generated')
                           or index(Line,'Division by zero')
                           or index(Line,'Mathematical operations could
not')
                           or index(Line,'Invalid argument to function')
                           or index(Line,'No observations')
                           or index(Line,'There were 0 observations')
                           or (    index(Line,'The data set')
                               and index(Line,'has 0 observations')
                              )
                           )  )%*.. . . . . . . . . . . %IF NOTES; %END;
                            then do; file "&PATH.&PROGNAME..txt";
   do I = N-&PREVLINES to N;         put Prev(mod(I,
                                            %eval(&PREVLINES.+1))); end;
                                     put "- end ERROR/WARNING/NOTES "
                                        "+ &PREVLINES lines previous -";
   if not ErrWarn           then do; ErrWarn = 1;
                                     call symput('ERRWARN','1');    end;
                                     file LOG;
   %* . . . . . . . . . . . . . . . . . . . . . . . . if FirstWord; end;
%*. . . . . . . . . . . . . . . . . . . . . . . do until(EndoFile); end;
                                                                   stop;
run;%*PUT ERRWARN<&ERRWARN.>;
 
%IF &ERRWARN %THEN %DO;%*NOTE: uses %GLOBAL variables;
%*put EMAIL(RJF2,Error or Warning in &PROJECT. &SHIPYYMM. &PROGNAME.;
%*EMAIL(&SYSUSERID.
      ,Error or Warning in &PROJECT. &SHIPYYMM. &PROGNAME.
      ,see &PATH.&PROGNAME..log .txt);
%*EMAIL(RJF2
      ,Error or Warning in &PROJECT. &SHIPYYMM. &PROGNAME.
      ,see &PATH.&PROGNAME..log .txt);
%*. . . . . . . . . . . . . . . . . . . . . . . . . . %IF ERRWARN; %END;
%ELSE %DO;%*delete &PROGNAME..LOG & .TXT.;
/**********************************************************************/
filename            SYS_CMD pipe "del &PATH.&PROGNAME..LOG
                                  del &PATH.&PROGNAME..TXT";
data _NULL_; infile SYS_CMD;%*execute OpSys command(s);             run;
/**********************************************************************/
%*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . *ELSE; %END;
%*. . . . . . . . . . . . . . . . . . . . . . . . . %IF ACTION=ON; %END;
run; %* . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; %MEND;

Testing Program

/**********************************************************************
%**include SITEFILE(LOGSAVE);
%*ATITLES(EIA);%*returns %global PROGNAME;
%*LET PATH = C:\TEMP\;%*NOTE ending slash;
%LET PROJECT  = TESTING;
%LET SHIPYYMM = 200110;
%LET PROGNAME = ZTestLogSave;
OPTIONS MPRINT;
%LOGSAVE(ON);
 
DATA X;LENGTH Y $ 1 Z 4;X=1;Y =X;OUTPUT;STOP;RUN;
DATA Z;STOP;
PROC PRINT DATA = X(WHERE=(0));RUN;
 
%LOGSAVE(OFF);
%LOGSAVE(SCAN);
%*LOGSAVE(SCAN.WARNING=1);
%*LOGSAVE(SCAN.WARNING=1,NOTES=1);

References

--macro maven == the radical programmer 11:29, 23 October 2008 (EDT)