[SASTechies] SAS Macros to Search and Report Errors and Warnings from your SA...

2 views
Skip to first unread message

LearnSAS

unread,
Oct 12, 2010, 7:18:42 AM10/12/10
to saste...@googlegroups.com
How many a times at work have you gone thru the logs looking for ERROR, WARNINGS, NOTES etc for more information about the generated problem?...I've been doing a lot like that lately for developing / debugging / lines of code for more information...I just wished I had a piece of code that would search and report me the location / line number and few more information about....luckily I found this macro in a SAS SUGI paper...here's the link....www2.sas.com/proceedings/sugi25/25/po/25p219.pdf

Then I had to customize it a little more to make the macro browse thru a folder of log files with a common runtime so that I can get all the errors into one report file...

Here's an example and the full code below....
I intentionally induced couple of errors highlighted in RED font locations in these datasteps below....

%let LogLoc=C:\SASDATA;
%let cyle_runtime=10OCT2010102001;

proc printto log="&LogLoc.\example1_&cyle_runtime..log"; run;

DATA example1;
INPUT ID $ 1 SBP 2-4 DBP 5-7 GENDER $ 8 AGE 9-10 WT 11-13;
DATALINES;
1120 80M15115
2130 70F25180
3140100M89170
4120 80F30150
5125 80F20110
;
RUN;
PROC MENS;
RUN;
proc printto; run;

proc printto log="&LogLoc.\example2_&cyle_runtime..log"; run;
DATA CDS2;
     INPUT @1 CATEGORY $9. @10 NUMBER 3.;
DATALINES;
JAZZ     252
POP       49
CLASSICAL 59
RAP       21
GOSPEL    44
JAZZ      21
;
run;
ODS RTF;
PROC FREQ DATA=CDS ORDER=FREQ; WEIGHT NUMBER;
  TITLE3 'READ IN SUMMARIZED DATA';
  TABLES CATEGORY;
RUN;
proc printto; run;

This code produces 2 log files at C:\SASDATA\ with timestamp on them...





Now running my SAS Macro %ReportErrorWarnings with the right parameters would result in a Error file at the same location...

%ReportErrorsWarnings(searchstr,searchloc,searchfiles,outfile,lines2display);






The macro from the SUGI paper was good...it created an arrow against the error / filename and linenumber...I customized the macro to browse thru a folder / location of logs etc... I agree it isn't pretty but it works for me....This error file gives me the exact location (for eg line 20 in example 1 file and 2 lines above and below....). The number of lines to display above and below is again customizable though as the last parameter...


Similarly one can search for "ERROR:","WARNING:", "NOTE:","not resolved", "uninitialized", "invalid data", "_ERROR_=1", "missing values", "lock held by" etc...any other usual errors that you might want to track.


%ReportErrorsWarnings(searchstr,searchloc,searchfiles,outfile,lines2display);


Here's the full code...with the repeatition of the above code again...for context...

You can get it from here as well...
http://snipplr.com/view/42133/sas-macros-to-search-and-report-errors-and-warnings-from-your-sas-logs/
or



%macro recsinds(table,macvar);                                       
/*----------------------------------------------------------------------
  this macro can be used to get the count of observations in a dataset 
  into a macrovariable that you give.                                  

  usage: %recsinds(sashelp.class,macvar);                              
                                                                        
  &macvar is the observation count of your dataset                     
 ----------------------------------------------------------------------*/                                                                      

     %global &macvar;                                                  
     %local handle rc;                                                 
     %let handle = %sysfunc(open(&table)); /* open the table */        
     %if &handle %then                                                  
         %do;                                                          
        /* get the observation count into the macvar macro variable */ 
            %let &macvar = %sysfunc(attrn(&handle, nlobs));            
             %let rc = %sysfunc(close(&handle)); /* close the dataset */
      %end;                                                            
     /* write the record count to the log */                           
      %put recsinds &table: &&&macvar.    &macvar=&&&macvar.;          
                                                                       
%mend recsinds;

%macro SearchErrorsWarnings(strg,loc,dsx,mm=1);
* mm=# of lines to display before and after target lines. mm=0,1,2 ...etc.;

filename dd "&loc.\&dsx.";
%global nnn;  *nnn=# of records in dsx;

data aa (keep= filen arrow linum xx);
      infile dd length=ln end=last;
      length llprted pthru 8 arrow $3 xx $120 filen $400;
      retain llprted pthru 0;
      *LLPRTed:line # of Last Line Printed; * PThru: to be line # of the last of: * the 2mm+1 lines to be displayed;
      length %do jj=1 %to &mm; x&jj %end; XT $ 120;
      retain filen XT ' ' %do jj=1 %to &mm; x&jj %end;;;

      filen="&dsx.";

      * These store the mm lines that are; * to be printed prior to a Find; * Next save these mm lines;
      %do jj=%eval(&mm-1) %to 1 %by -1;
            x%eval(&jj+1)=x&jj;;
      %end;

      x1=XT;
      input XT $varying120. ln;
      XT=upcase(XT);
      if index (XT,"THE SAS SYSTEM")>0 then delete;
      if index (XT,upcase("&strg"))>0 then
    do;
            filen="========================================";linum=.; arrow='====='; xx='========================================================================================';
            output;
            filen="&dsx."; arrow='';

            * Found one!;     * Insert a blank line between finds;      * provided the scopes of two finds ;    * do not overlap;
            if (_n_ > pthru + &mm + 1) & pthru > 0
            then
             do;
                  filen="========================================";linum=.; arrow='====='; xx='========================================================================================';
                  output;
                  filen="&dsx."; arrow='';
             end;
            *Output mm lines preceding the find;
            %do jj=&mm %to 1 %by -1;
                  if &jj<_n_ - pthru then
                do;
                        xx=x&jj;
                        linum=_n_ - &jj;
                        output;
                  end;
            %end;
            linum=_n_;
            xx=XT;
            if &mm > 0 then arrow="-->";
            llprted=_n_;
            output; * Output the Found line;         

            * Compute pthru, the line # of the ;            * last line of the scope so that the;        * next mm lines can be printed;
            pthru=_n_+&mm;
            arrow=' ';
      end;
else
      do;
            if _n_<=pthru then
            do;
                  linum=_n_;
                  xx=XT;
                  output;
                  * Outputting the next mm lines;
            end;
      end;
if last then call symput('nnn',left(put(_n_,5.)));
run;

proc append base=allout data=aa; run;
%mend SearchErrorsWarnings;

%macro ReportErrorsWarnings(searchstr,searchloc,searchfiles,outfile,lines2display);

proc sql;
drop table allout;
drop table aa;
drop table new;
quit;

%let dircmd0=%nrbquote(%str(dir /b /s %")%str(&searchloc.\&searchfiles.)%str(%"));
FILENAME rootloc pipe "&dircmd0";  

/*data _null_; run;*/
data new;
length file $ 1000;
infile rootloc;
input file;
cnt=count(file,"\");
file=translate(file,' ','\');
file=scan(file,cnt+1,' ');
call symput(compress('filen'||_N_),file);
run;

%recsinds(new,nobs);
%if &nobs gt 0 %then %do;
      %do k=1 %to &nobs;
      %SearchErrorsWarnings(&searchstr.,&searchloc.,&&filen&k.,mm=&lines2display.);
      %end;

      data allout;
      retain filen linum arrow xx;
      set allout;
      run;

      data _null_;
      file "&outfile." lrecl=32767;
      set allout;
      if _n_ =1 then
      do;
            put "FILENAME" '09'x "LINE #" '09'x "ARROW" '09'x "MESSAGE";
            put "*****************************************************************************************************";
      end;
      put filen '09'x linum '09'x arrow '09'x xx '09'x;
      run;
%end;
%else
%do;
      %put ==================;
      %put NO LOGS TO PROCESS;
      %put ==================;
%end;

%mend ReportErrorsWarnings;


%let LogLoc=C:\SASDATA;
%let cyle_runtime=10OCT2010102001;

proc printto log="&LogLoc.\example1_&cyle_runtime..log"; run;

DATA example1;
INPUT ID $ 1 SBP 2-4 DBP 5-7 GENDER $ 8 AGE 9-10 WT 11-13;
DATALINES;
1120 80M15115
2130 70F25180
3140100M89170
4120 80F30150
5125 80F20110
;
RUN;
PROC MENS;
RUN;
proc printto; run;

proc printto log="&LogLoc.\example2_&cyle_runtime..log"; run;
DATA CDS2;
     INPUT @1 CATEGORY $9. @10 NUMBER 3.;
DATALINES;
JAZZ     252
POP       49
CLASSICAL 59
RAP       21
GOSPEL    44
JAZZ      21
;
run;
ODS RTF;
PROC FREQ DATA=CDS ORDER=FREQ; WEIGHT NUMBER;
  TITLE3 'READ IN SUMMARIZED DATA';
  TABLES CATEGORY;
RUN;
proc printto; run;

%ReportErrorsWarnings(ERROR:,&LogLoc.,*_&cyle_runtime..log,&LogLoc.\error_&cyle_runtime..txt,2);


--
Posted By LearnSAS to SASTechies at 10/12/2010 07:18:00 AM
Reply all
Reply to author
Forward
0 new messages