Could you provide an example?

If you decouple the things being logged from the actual logged string, you can do stuff like have different log sinks format things differently, or even filter what appears in the log line as needed.

For example, you could have a setup with logging going to two separate files.  One used for auditing, which only contains the bare timestamp and log message, and the other for debugging that contains all the things verbosely.  Or filter the output to any log sink based on circumstances (prod vs. dev, etc).  You write your code to give all the context to the logger, and let the logging figure out what belongs where.  This can be especially important when the log output has to conform to existing systems, and you don't want to change every logging call.

Basically, limiting to string format logging limits to thinking of logging as purely strings.  Using an API of 'list of items' decouples it to the more abstract 'logging stuff', with the actual string only mattering for final output.


Logically, I look at the formatting version as a convenience version of a one-argument call to the non-formatting version.  So:

logf("some %s other %s", foo, bar)

is like

log(format("some %s other %s", foo, bar), <other stuff>)

where the 'other stuff' may be formatted as required by logging configuration, and is not possible with the logf version.

logf(string msg, ...stuff to put in message)
log(string msg, ...stuff to log with message)