You're saying to delete commented-out code once the new code works. Put your code in version control instead. Logging is to once-off printfs as version control is to commented-out code.
Don’t be primitive about it. :-)
The serious answer is: use a good logging framework. In particular, I’d suggest something that can log at selective levels of information for different parts of your system.
If your project’s culture is to instrument your code like this routinely, it can be a very useful asset, and it’s no more disruptive in practice than say adding comments or writing tests. In each case, with experience you get better at judging where to focus your efforts and how much detail is worth including by default, and if that turns out not to be enough you can always add more while you’re working in that area.
With modern tools for recording and analysing logs, there is relatively little useful information that you can easily find using a debugger but can’t easily find from good log output. On the other hand, logging has some big advantages: you can capture how your system changes over time, you can record and review concurrent behaviour cleanly, you can capture information from different parts of distributed systems that might be written in different programming languages or running on different devices.
Just plain "debug log statements" I have yet to hear a good use case for. Every time people have put them in, it's because some bug called for their inclusion, then the bug got fixed, then the statements got left around after the bug was fixed. Or the bug didn't get fixed and it's a matter of "why don't you fix the bug?"
There's rare cases where there's an ongoing issue with a known bug that you don't know the fix for yet, so you drop debug statements in production code hoping to catch it. But this is supposed to be a rare, rare case.
You're using a primitive debugger, you just don't know it.
You can dump statements through a function and see it's progression when run without having to interact with it.
Throw in something like FirePHP (which allows dumping pretty much anything out as a viewable/collapsible trace, other languages have similiar) and the use case for a lot of using a full blown debugger is removed (it's still incredibly powerful when needed).
So I use both.
For medium/large programs I'll often prefer a debugger because I can easily and quickly try to diagnose the problem without having to wait for a new build to complete with the added traces.