SAS Email If Errors Occur

2019-07-03 22:03发布

is there any code/macro I can incorporate into my sas program that will email me as soon as an error occurs in my sas code while it is running?

Also is it possible for this email to contain the error that happened?

标签: sas
2条回答
来,给爷笑一个
2楼-- · 2019-07-03 22:24

Yes.... and no...

This is possible - but there's no nice way to do it. You would have to check after each procedure to see if an error occurred. Basically you would insert a line of code to perform the test dozens (or hundreds) of times throughout your code.

I often find that it's sufficient to perform a test after the entire program has run. If an error did occur halfway through then SAS will usually enter syntax check mode anyway so it won't execute any code after the error.

This approach also comes with it's own separate set of problems. To start with the SYS macro variables that contain information about errors only store info for the most recent error. We could check the log, but the problem with this is that the log is still in use by the program we are currently running and to examine which prevents us from using SAS to open it to read from it.

The way I get around this is to call SAS twice. The first time to run the program and save the log to a specified file. The second time to run a program that will check the logfile that was just created and to send an email if specific criteria are met (such as the line begins with ERROR:.

Some details... when you launch sas the 2nd time, you can use the SYSPARM parameter to pass in the name of the logfile you want to check. You can parse the logfile with code something like this (I suggest you customize the conditions to your own situation):

**
** READ IN LOGFILE. CHECK FOR PROBLEMS
*;

data problems log;
  length line $1000;

  infile "&logfile";
  input;

  logfile = "&logfile";
  line_no = _n_;
  line    = _infile_;
  problem = 0;

  if 
  (
     line =: "ERROR:"
  or line =: "WARNING:"
  or line =: "NOTE: Numeric values have been converted to character values"
  or line =: "NOTE: Character values have been converted to numeric values"
  or line =: "NOTE: Missing values were generated as a result of performing an operation on missing values"
  or line =: "NOTE: MERGE statement has more than one data set with repeats of BY values"
  or line =: "NOTE: Invalid (or missing) arguments to the INTNX function have caused the function to return"
  or line =: "INFO: Character variables have defaulted to a length of 200"
  or line =: "NOTE: Invalid"
  )
  and not
  (
      line =: "WARNING: Your system is scheduled to expire"
  or  line =: "WARNING: The Base Product product with which Session Manager is associated"
  or  line =: "WARNING: will be expiring soon, and is currently in warning mode to indicate"
  or  line =: "WARNING: this upcoming expiration. Please run PROC SETINIT to obtain more"
  or  line =: "WARNING: information on your warning period."
  or  line =: "WARNING: This CREATE TABLE statement recursively references the target table. A consequence"
  or  line =: "WARNING: Unable to copy SASUSER registry to WORK registry. Because of this, you will not see registry customizations during this"
  or  line =: "WARNING: Estimates did not improve after a ridge was encountered in the objective function."
  or  line =: "WARNING: Estimates may not have converged."
  or  line =: "ERROR: A lock is not available for"
  or  line =: "ERROR: Errors printed on page"
  or (line =: "WARNING: Apparent symbolic reference TODT not resolved." and "%upcase(&jobname)" eq "DIAL800.REPORTING_API")
  )
  then do;
    problem = 1;
    output problems;
  end;
  output log;
run;

filename mymail email content_type="text/html"
                      to=( test@test.test )
                      from=("myemail@test.test")
                      subject="mysubject"
                      attach="&logfile";

data _null_;
  length divider $200;

  file mymail;

  set problems end=eof;

  divider = repeat('=',80);

  if _n_ eq 1 then do;
    put '<font style="font-family:courier new;font-size:9pt"><br>';
    put divider "<br>";
    put "SUMMARY OF PROBLEMS: &logfile <br>";
    put divider "<br><br>";
  end;

  put line_no 5. ": " line "<br>";

  if eof then do;
    put divider "<br>";
    put "END OF SUMMARY     <br>";
    put divider "<br><br>";
  end;

run;

It's not clear from your question whether you know how to send an email in SAS, but if not I suggest googling it first and if you still can't get it working then come back and post a separate question.

EDITS: You can specify where SAS should save the logfile to by using the -LOG "myfile.log" parameter when you call SAS.

查看更多
唯我独甜
3楼-- · 2019-07-03 22:24

This concise article gives simple SAS code which shows how to check for errors and send an email in an error condition. As Rob already mentioned, you should check for error codes after each procedure.

https://heuristically.wordpress.com/2012/02/09/return-codes-errors-sas/

This code doesn't send the log, but you could send a general error by defining a macro variable with a brief description like "failed to query the SQL database." At our organization we run about 50-100 (?) SAS programs in batch jobs, and we save each log with a date stamp like 2012-03-05 13:05 daily job.log

查看更多
登录 后发表回答