Reputation: 23
I'm trying to write additional properties to the log using {Properties} (which are not in the message template):
Used (FileSink) template:
"[{Level}] {Message}{NewLine}{Properties}{NewLine}{Exception}"
Log operation (simplified, normally the object array is given by a method parameter):
Log.Information("Start logging",
new object[]{
new { Version = "VersionString"},
new { StartDate = DateTime.Now },
new { Id = Guid.NewGuid() }
});
I also tired:
Log.Information("Start logging",
new object[]{
"VersionString",
DateTime.Now,
Guid.NewGuid()
});
I had a look on LogEventPropertyCapturingTests and this PR, but I couldn't get it working...
Update I use wrapper functions like this:
public static void Information(string messageTemplate, object[] propertyValues, bool show = false, [CallerMemberName] string callerMethodeName = "", [CallerFilePath] string callerFilePath = "", [CallerLineNumber] int callerLineNumer = -1)
{
using (LogContext.PushProperty("CallingContext", new { callerMethodeName, callerFilePath, callerLineNumer }))
{
_MainLog.Information(messageTemplate, propertyValues);
}
if(show)
{
// Code to show a the event to the user
}
}
Update2 Found a way but it's not very nice, as the template-property-matching rudimentary.
public static void Information(string messageTemplate, object[] propertyValues, bool show = false, [CallerMemberName] string callerMethodeName = "", [CallerFilePath] string callerFilePath = "", [CallerLineNumber] int callerLineNumer = -1)
{
using (LogContext.PushProperty("CallingContext", new { callerMethodeName, callerFilePath, callerLineNumer }))
{
Regex matchProperties = new Regex("{[^}]+}");
int usedPropertiesCount = matchProperties.Matches(messageTemplate).Cast<Match>().Select(m => m.Value).Distinct().Count();
if (propertyValues.Length > usedPropertiesCount)
{
using (LogContext.PushProperty("AdditionalData", propertyValues.Skip(usedPropertiesCount)))
{
_MainLog.Information(messageTemplate, propertyValues);
}
}
else
{
_MainLog.Information(messageTemplate, propertyValues);
}
}
if(show)
{
// Code to show a the event to the user
}
}
Upvotes: 1
Views: 1474
Reputation: 31877
The ForContext()
method will do this:
Log.ForContext("Version", "VersionString")
.ForContext("Id", Guid.NewGuid())
.Information("Start logging");
(I've omitted StartDate
because all Serilog events are already timestamped.)
This blog post series includes some posts on message templates plus context and correlation that cover this plus other alternatives.
Upvotes: 2