Some notes on the differences between these two concepts.
[]Logs are read by administrators and maybe even users, while tracing output is strictly for developers and maintainers. Thus localisation is relevant for logging but not for tracing.
[]For enterprise class applications it is probably desirable to be able to change logging levels without forcing a restart. For tracing on the other hand being able to change trace level with a mere configuration file change and a restart is manna compared with the recompiles required by C/C++ etc.
[*]Log events are relatively short notifications of an event. In tracing however it may be desirable to include a lot of information on the current state of some object(s). In my case this extra data can run to hundreds of lines for a single ‘event’ The result would be unreadable if every line carried the sort of prefix found in Java logging.
In both cases if you have to minimise the cost you need to do something like
private static final boolean TRACE = ...;
...
if (TRACE)
tracelog.println(...);
or (for logging)
if (logger.isLoggable(Level.FINE))
logger.log(...);
Only in rare cases would the difference between these two be significant. The ability to remove the trace code altogether might allow the JIT to uncover further optimisations which would not be found in the logging case (where the code remains even if not executed). We have always had to do something to mark out our trace code in cases where performance matters, the if tests here are similar in size to the code we have always used. We can even do something like this:
private static final boolean LOG_FINEST = Logger.getLogger("myname").isLoggable(Level.FINEST)
Any code which depends on LOG_FINEST will only be executed if that condition was true at the time the code was loaded, which is not entirely in the spirit of the logging api, but so what!
I’ll add some more thoughts to this thread later.