7.4 Identifying Logic Errors with the PUTLOG Statement
Key Takeaways
- PUTLOG always writes to the SAS log, even when a FILE statement has redirected PUT output to an external file, which is why it is the exam's designated debugging statement.
- PUTLOG variable= uses named output, printing the variable name, an equal sign, and the current PDV value.
- PUTLOG _ALL_ dumps every PDV variable including the automatic _N_ and _ERROR_ values.
- Wrapping PUTLOG in conditional logic such as if _ERROR_ then keeps the log readable on large data sets.
- Prefixing the text with WARNING: or ERROR: makes SAS colour the line in the log, so custom diagnostics stand out.
7.4 Identifying Logic Errors with the PUTLOG Statement
Quick Answer:
PUTLOGwrites text and variable values to the SAS log, and it does so unconditionally — even when aFILEstatement has redirected ordinaryPUToutput somewhere else. The A00-231 content guide names it in three of the four expanded objectives under "Identify and resolve programming logic errors": usePUTLOGto help identify logic errors, usePUTLOGto write the value of a variable, formatted values, or all variables, and usePUTLOGwith conditional logic.
A logic error is a program that runs cleanly and produces the wrong answer. No ERROR: appears, no WARNING: appears, and the observation count looks plausible. The only way to find one is to make the DATA step tell you what it is holding at the moment it goes wrong, and PUTLOG is the statement built for that job.
1. Why PUTLOG and Not PUT?
Both statements can write to the log. They diverge the moment the DATA step also writes an external file.
data _null_;
set work.transactions;
file "C:\output\extract.txt"; /* PUT output is now redirected */
put ClientID Amount; /* goes to extract.txt */
putlog "Row " _n_ " ClientID=" ClientID; /* still goes to the LOG */
run;
| Statement | Destination |
|---|---|
PUT | The SAS log only if no FILE statement is active; otherwise the external file |
PUTLOG | Always the SAS log, regardless of any FILE statement |
That guarantee is the whole point. In a step that writes a flat file, a plain PUT diagnostic silently pollutes the output file instead of appearing in the log — a debugging statement that corrupts the deliverable.
2. Writing Variable Values: Named Output
Appending an equal sign to a variable name produces named output: the variable name, an equal sign, and the current value.
data work.audit;
set work.claims;
Ratio = Payout / ClaimAmount;
putlog ClaimID= ClaimAmount= Payout= Ratio=;
run;
SAS Log Output:
ClaimID=A1043 ClaimAmount=12000 Payout=9000 Ratio=0.75
ClaimID=A1044 ClaimAmount=8000 Payout=8600 Ratio=1.075
Named output beats bare putlog Ratio; because the label travels with the value. When ten variables scroll past, Ratio=1.075 is self-describing while a naked 1.075 is not.
Formatted Values
Place a format after the variable to control how the value prints in the log.
data work.formatted_log;
set work.orders;
putlog "Order " OrderID= " placed " OrderDate date9.
" for " Amount dollar12.2;
run;
SAS Log Output:
Order OrderID=88213 placed 31OCT2026 for $1,250.75
This matters when debugging dates: an unformatted SAS date prints as 24775, which tells you nothing about whether the date logic is right.
3. Dumping the Whole PDV: PUTLOG ALL
data work.debug_all;
set work.sales_raw;
Bonus = Sales * 0.05;
if _n_ = 1 then putlog "=== PDV AT FIRST OBSERVATION ===" / _ALL_;
run;
SAS Log Output:
=== PDV AT FIRST OBSERVATION ===
RepID=101 Region=East Sales=5000 Bonus=250 _ERROR_=0 _N_=1
_ALL_ prints every variable currently in the PDV, including the automatic _N_ and _ERROR_, and including variables that a DROP statement will remove before the row is written. That last detail makes it the fastest way to inspect intermediate values you deliberately excluded from the output data set.
Exam Tip: the forward slash (
/) in aPUTorPUTLOGstatement is a line-pointer control that moves output to the next line of the log. It is how a single statement produces a heading followed by a dump.
4. PUTLOG with Conditional Logic
An unconditional PUTLOG on a ten-million-row data set produces ten million log lines. Real debugging is conditional.
data work.processed_claims;
set work.medical_claims;
Ratio = Payout / ClaimAmount;
/* Fire only when something is actually wrong */
if _ERROR_ = 1 or Ratio > 1 or missing(ClaimAmount) then do;
putlog "WARNING: Suspect claim at observation " _n_;
putlog ClaimID= ClaimAmount= Payout= Ratio= _ERROR_=;
end;
run;
Three conditional patterns cover almost every debugging need:
| Pattern | Code | Use |
|---|---|---|
| First n rows | if _n_ <= 5 then putlog _all_; | Confirm the shape of the data before trusting the logic |
| Error rows only | if _ERROR_ then putlog _all_; | Catch invalid data and failed conversions |
| Business-rule breach | if Ratio > 1 then putlog ClaimID= Ratio=; | Find rows that pass syntax but violate the rule |
Colouring Your Messages
The SAS log colours any line beginning with WARNING: or ERROR:. Because PUTLOG writes raw text, starting the message with one of those tokens makes a custom diagnostic as visually prominent as a SAS-generated one.
putlog "ERROR: Payout exceeds claim amount for " ClaimID=; /* red in the log */
putlog "WARNING: Missing claim amount at obs " _n_; /* highlighted in the log */
putlog "NOTE: Row processed normally"; /* ordinary note styling */
This does not set _ERROR_, halt the step, or change the return code. It only changes how the line is rendered — useful for a human reading a 5,000-line batch log, and a favourite exam distractor for candidates who assume the prefix has functional meaning.
5. A Complete Debugging Workflow
data work.commission;
set work.sales;
/* 1. Confirm the incoming values on the first few rows */
if _n_ <= 3 then putlog "INPUT >> " _all_;
/* 2. The suspect calculation */
if Units > 0 then Rate = Revenue / Units;
else Rate = 0;
Commission = Rate * 0.08;
/* 3. Trace the branch that was actually taken */
if Units <= 0 then
putlog "WARNING: Non-positive Units, Rate forced to 0 at obs " _n_ " " RepID=;
/* 4. Flag results that violate the business rule */
if Commission > 10000 then
putlog "ERROR: Implausible commission " Commission dollar12.2 " for " RepID=;
run;
The sequence is always the same: verify the input, expose the branch, then test the output against a rule you can state in one sentence. PUTLOG is what makes each of those three steps visible.
A DATA step contains a FILE statement that redirects output to an external text file. Which statement still writes diagnostic messages to the SAS log?
Region holds 'North' and Revenue holds 45000. What does putlog Region= Revenue=; write to the log?
What is the effect of beginning a PUTLOG message with the text 'ERROR:'?
A program must dump the full PDV, including the automatic variables, only for rows where a runtime error occurred. Which statement does this?