I'll create a markdown doc with notes about best practice for logging seeing as it turned out to be more nuanced than we originally expected.
Some details in this comment: https://github.com/krzychu124/Cities-Skylines-Traffic-Manager-President-Edition/issues/349#issuecomment-512650775
@kvakvs Can you comment with some notes on the Format method(s) you added to the Log class? Which situations is it best to use those?
I'll do a draft of the doc and send a PR for review.
Log.Trace, Log.Debug, Log.Info, Log.Warning, Log.Error -- these format the message in place,if (booleanValue) { ... }$"string {interpolations}" are used (like breaking into multiple lines)Log.DebugFormat, Log.InfoFormat, ... - these format message later, when logging. Good for very-very long format strings with multiple complex arguments.string.Format as opposed to multiline $"string {interpolations}"if (boolValue)if () conditionLog.DebugIf, Log.WarningIf, ... - these first check a condition, and then call a lambda, which provides a formatted string.Log.DebugIf is optimized away if not in Debug modeout and ref valuesLog.NotImpl logs an error if something is not implemented and only in debug modeeach captured value is copied into lambda
This is not true. A lambda captures a variable, not a value.
A pointer.
Does not matter when the log is executed right away and everything is still equal to their expected values, but this might be important when the log is deferred to logging thread and the string value is produced later.
A pointer.
Well... Not a pointer. Semantically - a variable. It's better to think this way. For a reference type, this will be a reference. For a value type, this will be a struct copy indeed. (Which might cause unexpected behavior, but it's off-topic for this issue.)
Most helpful comment
Log.Trace, Log.Debug, Log.Info, Log.Warning, Log.Error-- these format the message in place,if (booleanValue) { ... }$"string {interpolations}"are used (like breaking into multiple lines)Log.DebugFormat, Log.InfoFormat, ...- these format message later, when logging. Good for very-very long format strings with multiple complex arguments.string.Formatas opposed to multiline$"string {interpolations}"if (boolValue)if ()conditionLog.DebugIf, Log.WarningIf, ...- these first check a condition, and then call a lambda, which provides a formatted string.Log.DebugIfis optimized away if not in Debug modeoutandrefvaluesLog.NotImpllogs an error if something is not implemented and only in debug mode