If you are using c# 7.0 or later, you could use the simplified tuple syntax to pass in a params
array of name/value tuples for formatting via serialization and subsequent logging.
Since you have tagged your question log4net, you could define extension methods on ILog
like so:
public static partial class LogExtensions
{
public static void DebugProperties(this ILog log, params (string Name, object Value) [] parameters)
// TODO: handle duplicate Name keys in some graceful manner.
=> log.Debug(JsonConvert.SerializeObject(parameters.ToDictionary(p => p.Name, p => p.Value), Formatting.Indented));
public static void InfoProperties(this ILog log, params (string Name, object Value) [] parameters)
=> log.Info(JsonConvert.SerializeObject(parameters.ToDictionary(p => p.Name, p => p.Value), Formatting.Indented));
}
And then call them like:
log.DebugProperties(("Prop1", "Val1"), ("Prop2", "Val2"));
log.InfoProperties(("Prop3", new SomeClass { SomeValue = "hello" }));
And get the output:
2021-01-21 21:12:36,215 DEBUG: {
"Prop1": "Val1",
"Prop2": "Val2"
}
2021-01-21 21:12:36,230 INFO : {
"Prop3": {
"SomeValue": "hello"
}
}
If you are using c# 9.0 or later, you could also add a logging method taking a Dictionary<string, object>
and, when calling the method, use the abbreviated new ()
syntax which omits the type when already known:
public static partial class LogExtensions
{
public static void DebugDictionary(this ILog log, Dictionary<string, object> parameters)
=> log.Debug(JsonConvert.SerializeObject(parameters, Formatting.Indented));
}
And then later:
log.DebugDictionary(new () { {"Prop1", "Val1"}, {"Prop2", "Val2" } } );
Of course, if you prefer you could wrap your ILog log
in a Utility
class with methods whose inputs are like those of the extension methods above, but it isn't necessary if you use extension methods.
Demo fiddle here.