Hi there,
I am trying to use the macro %checklogs as provided in paper below, but could not make it work, can anyone please help me out?
Refer to https://support.sas.com/resources/papers/proceedings17/1173-2017.pdf
I have created some dummy logs with error messages and saved on the server.
After running the macro, there is no error message being picked up from the logs saved on the server.
Everything looks fine to me, just the column called line is empty for all obs where it supposed to pick up the lines from each log files.
i will attach a copy of the code together with the screenshot.
Thanks for help in advance!
You should almost never be using the older MISSOVER option instead of the new TRUNCOVER option which was introduced only about 20 to 30 years ago. Although since you also added the PAD option it probably doesn't matter. But PAD only pads to the LRECL (logical record length) so it that was less than 1,000 bytes then the MISSOVER would still force everything to missing because you tried to read more bytes than existed on the line.
The $ informat removes leading spaces. The $VARYING informat does not. You could have more easily used the $CHAR informat instead. Then you wouldn't need to know how long the line was.
infile "&loc.&slash.&lg..log" truncover;
input line $char1000.;
Hi @Suzy_Cat,
Not sure if I'm missing something, but the code you've posted has the line:
/* index(upcase(line), "ERROR:") or*/
which is clearly commented out. Have you tried the code without this line commented out and make it something like:
if index(upcase(line), "ERROR:");
Kind regards,
Amir.
Just to expend @Amir 's answer:
Pay attention to the bold line - code taken from the macro:
data logck&x;
infile "&loc.&slash.&lg..log" missover pad;
input line $1000.;
/* keep only the records that had an undesirable message */
/* if index(upcase(line), "WARNING") or*/
/* index(upcase(line), "ERROR:") or*/
/* index(upcase(line), "UNINITIALIZED") or*/
/* index(upcase(line), "NOTE: MERGE") or*/
@Amir wrote:
Hi @Suzy_Cat,
Not sure if I'm missing something, but the code you've posted has the line:
/* index(upcase(line), "ERROR:") or*/
which is clearly commented out. Have you tried the code without this line commented out and make it something like:
if index(upcase(line), "ERROR:");
Kind regards,
Amir.
Note that test will NOT work right.
It will NOT find all of the ERROR lines in a SAS log. SAS will sometimes place an error number between the word ERROR and the colon.
ERROR 76-322: Syntax error, statement will be ignored
Also that test will get false positives when lines of code happen to have the text ERROR: in them
if missing(age) then put 'ERROR: Age is missing.';
SAS will always put the ERROR/WARNING/NOTE in the first column of the line.
So a better test is:
if line =: 'ERROR' and index(line,':') ....
I agree with @Tom on the issue about user written code using "ERROR:" and "WARNING:" elements. I have some projects where I have to constantly check data supplied by my sources for content and have such code in many programs that read external data. I use the keywords that way for the same reason the SAS designers do: I can find the problem bits in the log with the highlighted text.
Hi Amir,
Thanks for helping.
I have commented it out to check what is in the input file and have discovered the reason the error message not being picked by running the macro is due to input lines are all empty, i.e. no log lines are input into the file to do the check.
Cheers
Hi,
Thank you all for the kind help:)
I have manipulated the data and can confirm the macro works the way it suppose to be.
The issue lined up with the input code where there is no text from any log being read to data logck&x;
Example:
data LOGCK3_1 reads all lines from the log which contains an error message "ERROR ..." for testing, but all obs read in are showing missing value.
I then used below code to test next part and confirmed LOGCK3_1A is functional with the code "if index(upcase(line), 'ERROR 76-322:') or".
data LOGCK3_1;
set LOGCK3(obs=5);
line="ERROR 76-322: Syntax error, statement will be ignored";
run;
data LOGCK3_1A;
set LOGCK3_1;
if index(upcase(line), 'ERROR 76-322:') or
index(upcase(line), '') then delete;
run;
When i insert a line with the error message, data logck&x._2 will be
hope some ideas on how to read in the log info into the data logck&x properly :_)
Hi All,
Thanks for all your help.
Now i have changed the code
from:
data logck&x;
infile "&loc.&slash.&lg..log" missover pad;
input line $1000.;
to:
data logck&x;
infile "&loc.&slash.&lg..log" missover pad length=len;
input @1 line & $varying200. len;
it works perfectly fine --- log file lines are now properly read in to file logck&x.
Although I don't understand why the previous code not working (all lines are empty) and why the new code works(reads the logs into the file).
Would appreciate if anyone can explain in details.
You should almost never be using the older MISSOVER option instead of the new TRUNCOVER option which was introduced only about 20 to 30 years ago. Although since you also added the PAD option it probably doesn't matter. But PAD only pads to the LRECL (logical record length) so it that was less than 1,000 bytes then the MISSOVER would still force everything to missing because you tried to read more bytes than existed on the line.
The $ informat removes leading spaces. The $VARYING informat does not. You could have more easily used the $CHAR informat instead. Then you wouldn't need to know how long the line was.
infile "&loc.&slash.&lg..log" truncover;
input line $char1000.;
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.