08-26-2015 01:31 PM
I want to store the first error message encountered in the log into one macro variable. And i dont want to import the Log file into SAS and search for the error message.
i.e dynamically need to create macro variable with the entire ERROR message with in the same SAS code.
And I know we can use &syserrortext but it gives last error message encountered in the Log which is not my requirement.
08-26-2015 03:45 PM
My approach would be to write a short macro that I call after each data step or procedure that examines whether there was an error using the &SYSERR variable, and if so save the value of the error text. The macro should check the status of the desired macro variable and only execute when the value is blank.
But this might not get first error if you generate multiple errors in a single step.
08-27-2015 05:56 AM
Thank You. Actually this is what i thought initially. But if there are thousands of lines of code then adding this extra step after each step is tedious.
Actually my intention here is to apply this to my production jobs.
08-27-2015 06:07 AM
Two things, firstly I wouldn't recommend a macro variable to hold this information, you could end up with lots of warnings errors and the macro variable will be long. Secondly, why do you not want to use the log which is generated? The reason is this, firstly the log is generated automatically for the purpose of capturing this information, and it is very simple to have a text parser pull out the required information. Secondly, it more robust than something your would create yourself.
As far as I am aware the only option is to check &syserr after each step and process it, i.e. lots of code updating. This is because there is a generated log to handle this.
08-27-2015 06:34 AM
Thanks RW9 for the reply.
Yes you are correct. we can search for the errors in the logs generated on daily basis. But if there are 10 codes failed at a time and cheking for the errors in each of the log may be tedious. SO I am just looking for other option to get the first error message from log dynamically.
Actually my intention here is to Send out an email to the SAS Users with the first ERROR description by passing macro variable here. i.e Based on this email, Users should come to know that why that particular code has been failed at the first instance.
08-27-2015 06:47 AM
Then what you want is some software for automation of a task. The automation software would schedule, and at certain points run the program, the log of which can then be returned to the user via email if problems are encountered. Pretty much everyone has to do this type of task, and there are various ways of doing it. SAS has software which can do this type of thing:
There are other tools out there. PErsonally I would try to re-invent the wheel doing it yourself.
08-27-2015 08:46 AM
I agree with @RW9, there are lots of benefits to the log parsing approach. Once you parse the log, you have data. And as a SAS programmer, you can do a LOT with data. Why limit yourself to only the first error message, when you could have all of the error messages (and importantly, warnings and bad notes).
Tricia Aanderud has a very nice blog post on log scanning that includes emailing a log summary: http://bi-notes.com/2012/04/sas-eg-check-the-log/ .
My favorite paper on log scanning is: http://www.lexjansen.com/nesug/nesug01/cc/cc4008.pdf
Currently all of my nightly jobs end with a call to a %logcheck macro. If it finds any problems in the log it emails me a summary, with a link to the log itself. I also use it to check stored process logs, DM logs, etc etc.
08-27-2015 09:53 AM
I agree with the majority
* post-processing --- log-saving and reading/scraping --- is much easier
* do not add trivial code to every step,
* stick with "Keep it Simple"
Got Cleverness? keep it in the Bricolage folder!
08-27-2015 11:43 AM
Here's another approach that might be closer to your original objective.
Define a macro %RUNN and use it to replace all RUN; statements in the program.
The %RUNN macro would contain (1) a RUN; statement, (2) a %GLOBAL statement to create a global macro variable if it didn't already exist, and (3) logic to examine &SYSERR and &SYSERRORTEXT and, if appropriate, replace your global macro variable.
At the end of each program, %PUT could write out your global macro variable.
Given that text editors could pretty easily convert RUN; statements to %RUNN statements, the changeover effort would be small.
08-29-2015 06:17 AM
I am trying to use checktheLog macro to fulfill my requirement.
Actually when I try to import the .LOG file (present on server) using SAS EG, it is working fine and sending errors' details via email.
But if i run same CheckTheLog macro on Linux Server through IBM Process Flow Manager (is a scheduler where all the production codes have been scheduled via Management Console), it could not able to import the .log file.
Can you please let me know if there is any reason why I could not able to import into SAS when I am running on Linux through Scheduler whereas SAS EG could able to import.
Here I am using INFILE statement to import this .LOG files.
08-29-2015 06:57 AM
The importing the .LOG file is working from Linux too now.
The problem here is, As I used this checktheLog marco at the bottom of my entire main code, the importing got successful if there are no ERRORS at the top of the MAIN code's LOG and Unsuccessfull when there are several errors present in the top of the Log.
When we run the erroneous code on SAS EG, it is importing the .LOG file successfully and sending emails irrespective of the errors in the log.
So, is there any way to execute/process the bottom code(i.e checktheLOG Macro) successfully on Linux server through Scheduler irrespective of the errors in the log??
08-29-2015 08:12 AM
Glad you figured it out. I don't use that exact macro, so I can't make promises. Would suggest adding something to the beginning of the macro that is:
%if %sysfunc(getoption(obs)) = 0 %then %do;
options obs=max nosyntaxcheck;
When your SAS code executes ins a batch job (as when it's scheduled), if there is an error, SAS may enter syntaxcheck mode. When that happens, it writes a note to the log that SAS set obs=0, and will continue checking syntax of remaining code, but not actually execute it. I use the code above at the start of my %logcheck macro to recover from syntaxcheck mode, so that my log checking code still executes.
08-26-2015 03:49 PM
because it involves inserting your error-text-capture into all your programs.
attrib step length = 4
date_time length = 8
sys_error_text length = $128;
step = &step;
datetime = datetime();
sys_error_text = "&syserrortext";
PROC append base = list_sys_errors
data = &syslast;
As you can see, the task is to replace all your run statements
with the macro call
Someone will suggest adding a global macro variable
that the macro increments.
So then figure out in which step the error occurs based on a global macro variable value.
08-27-2015 06:27 AM
Thank You Ron.
But in this case, do you means, do I need to call the macro - %run_capture(step=1 or 2 or 3 and so on) multiple times after each Data/Proc Step presented in the 1000 lines of my code?