I work with "SAS Base" (meaning SAS Windowing Environment).
I have to review the code of another team.
The code inclues a very long macro-program which writes thousand of lines into the log. The log becomes full, a warning window appears (something like : “The log is full, do you want to save it or clean it ?”) and the rest of the macro-program won’t execute until I make a choice.
The problem is, this message appears 15 times for each macro-execution, and I have to execute this macro 12 times in a row. This forces me to manually answer the pop-up message, more than 150 times…
Is there a way out of this nightmare ? In terms of process, splitting the said giant macro-program in 15 tiny macro-programs is a no-go (as much as possible, I have to reperform their code "as is").
Thanks everyone !
PS : the window that pop-ups display the following message :
"log WINDOW FULL"
"The window is full and must be emptied. Select :
F for File
P for Print
S for Saving or
C for cleaning the window without saving"
I would be very happy with hitting "S" or "C" each time, but not manually... I would like to launch the code, automatically save/clean the log when needed, and forget about it until the final result is produced.
Since you say you are looping and calling a macro 12 times you could add code to redirect each call to a separate file. For example say your loop is using a macro variable named I as the loop counter. You might make a different log file for each value of I;
proc printto log="somename.&i..log"; run;
%macrocall(....)
proc printto log=log; run;
Also make sure you have options NOMLOGIC and NOSYMBOLGEN if your macro code make extensive use of macro logic and/or macro variables. Those options can produce tons of output. I have had to resort to writing SAS code to strip those lines for SAS logs when trying to help users debug their code because otherwise it was impossible to find the actual code that was run and the NOTES from all of the clutter generated by MLOGIC and SYMBOLGEN. Those options are really only needed when you have to debug your macro logic.
Make sure your code is not generating lots of notes about type conversion or inability to convert text to numbers. Especially if your datasets have a lot of variables those message will produce a LOT of output.
This code sends the log to a text file which can be as large as you need it to be.
proc printto log="abc.log"; run;
%yourmacro /* Your macro call goes in between the two PROC PRINTTO statements */
proc printto; run;
Hello @makemo,
Routing the SAS log to a file, as PaigeMiller suggested, is probably the best solution if you want to avoid that annoying pop-up message entirely.
In addition, you can reduce the size of the log by choosing appropriate system option settings (which might be overridden by OPTION statements in your code, though). For example, if you're not interested in performance statistics (such as cpu time), you can switch off the STIMER system option
options nostimer;
and similarly the even more verbose FULLSTIMER system option. As you are talking about a "macro-program", you may want to avoid system options such as MPRINT, MLOGIC or SYMBOLGEN as well (of course unless you need the additional information provided by these options). Using the MSGLEVEL=N and in particular the NONOTES option would likely suppress too much valuable information, although the log size reduction could be substantial.
If you want to see the log in the log window and you have been using the default setting of the DMSLOGSIZE= system option, you can reduce the frequency of the log window getting full (by a factor of about 10) by setting that option to MAX at SAS invocation.
Do you by any chance have to SAS option MPRINT switched on? If so switching it off should significantly reduce log sizes. Just add this to the start of your program:
options nomprint;
Besides of writing the log to an external file and using options that create less log, you could also try OPTIONS DMSLOGSIZE=MAX;
DMSLOGSIZE=n | nK | hexX | MIN | MAX
Since you say you are looping and calling a macro 12 times you could add code to redirect each call to a separate file. For example say your loop is using a macro variable named I as the loop counter. You might make a different log file for each value of I;
proc printto log="somename.&i..log"; run;
%macrocall(....)
proc printto log=log; run;
Also make sure you have options NOMLOGIC and NOSYMBOLGEN if your macro code make extensive use of macro logic and/or macro variables. Those options can produce tons of output. I have had to resort to writing SAS code to strip those lines for SAS logs when trying to help users debug their code because otherwise it was impossible to find the actual code that was run and the NOTES from all of the clutter generated by MLOGIC and SYMBOLGEN. Those options are really only needed when you have to debug your macro logic.
Make sure your code is not generating lots of notes about type conversion or inability to convert text to numbers. Especially if your datasets have a lot of variables those message will produce a LOT of output.
Thank you all for the valuable inputs !
I think OPTIONS DMSLOGSIZE=MAX; won’t cut it since the program writes in fact more than 2 millions lines of log and the maximum size for DMSLOGSIZE is 999 999... But that's indeed a workable trick for possible other codes that produce less log.
As of now I have resorted to settle with redirecting the log to a text file through proc printto log="abc.txt". But I will give a try to solutions like options nomprint… and options nonotes… in order to control how much log precisely is produced by the code. Some of it is totally unecessary, but some of it will help me debug other possible issues.
Having logs of over 2 million rows sounds excessive. Right now you appear to be fixing the symptom rather than the disease. BTW, if you ran your SAS application as a batch job (sas.exe -sysin MySASPgm.sas) you wouldn't need to use DMSLOGSIZE OR PROC PRINTTO.
Sorry for long time since last post !
In the end I have resorted to use
proc printto log="abc.log"; run;
%macro
proc printto; run;
like suggested by @PaigeMiller and @Tom because none of other solutions will work.
Not even the following (cumulation of all options suggested) will work :
options nosource nosource2 nonotes nomprint nosymbolgen nomlogic nostimer nofullstimer ;
It's very possible that these options do not work because the macro-program is executed inside a rsubmit bloc (I work with data bases located on a Unix server). The code looks like :
rsubmit ;
%macro macro_name (arguments=) ;
...
%mend ;
%macro_name(arguments=value) ;
endrsubmit ;
Does it make any difference ?
Anyway "proc printo" is doing the trick, so I will stick to that for this one time.
Thanks everybody for the many interesting suggestions !
@makemo wrote:
In the end I have resorted to use
proc printto log="abc.log"; run; %macro proc printto; run;
like suggested by @PaigeMiller
@makemo then please mark my suggestion as correct
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.