Firstly, Sahil seems to have misunderstood the smell. It's not seeing the output (which is what his 'neat' trick avoids) it's having the log statements in the code in the first place.
As Jeremy points out; "Those trace statements are in there because the code is prone to breaking and hard to understand".
It seems that Sahil is well on the way to building a complex tracing system, hmm, didn't I say that's always what people in love with tracing tend to do in these situations? It wont work, you're solving the wrong problem and building complexity for the sake of it! Stop it! ;)
Jeremy nails most of the reasons that excessive logging is a bad smell but there's one other potential issue. The Heisenberg uncertainty principle; the act of logging can change the way the program works. This is especially true in multi-threaded programs where writing to a log often causes a synchronisation point between threads which often changes how the threads in the system are sheduled (threads writing to a shared log may block on locking devices designed to protect the log). This can often mean that adding, or turning on, logging to show up a threading problem can cause the problem to go away (or arrive!).
I'd say that there are NO valid situations where trace logging should be left in production code. There are much better ways to achieve the same ends. Please note my distinction between trace logging and application logs...
Oh, and the 'neat' trick is awful. In fact I'm quite amazed that the .Net designers managed to come up with a conditional compilation trick that's even worse than a C/C++ preprocessor