Serilog: реализация идентификатора запроса
В последнее время я настроил Serilog для хорошей игры с приложением ASP.NET Core 2 MVC, и следующая задача - отслеживать входящий запрос к веб-приложению на каждом уровне системы. Итак, в основном, мы хотим распространять некоторые токены (например, RequestId
генерируется Serilog для нижних уровней приложения).
"Serilog": {
"Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.RollingFile" ],
"MinimumLevel": {
"Default": "Debug",
"Override": {
"Microsoft": "Warning"
}
},
"WriteTo": [
{
"Name": "RollingFile",
"Args": {
"pathFormat": "log-{Hour}.txt",
"fileSizeLimitBytes": "",
"retainedFileCountLimit": "",
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Application}] [{Level}] [{RequestId}] - {Message}{NewLine}{Exception}"
}
}
],
"Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ],
"Properties": {
"Application": "MultilayerApp"
}
},
В журналах у нас есть хороший ввод, как
2018-01-19 14:06:01.165 +00:00 [App] [Warning] [0HLAV6PIMA9M0:00000001] - Accessing expired session, Key:"6e7f3ab5-db62-335d-1bc7-6824e5b918f5"
Но мой вопрос, где в Serilog это реализация RequestId
обогатитель? Честно говоря, я не могу его найти.
1 ответ
В ASP.NET Core RequestId
что выставляется некоторыми регистраторами является значением TraceIdentifier
на HttpContext
, Это свойство может использоваться во всем приложении для идентификации текущего запроса.
Для целей ведения журнала, возвращаясь к HttpContext
это не путь, чтобы пойти все же. Microsoft.Extensions.Logging
абстракции поддерживают области регистрации, что является способом предоставления дополнительной информации регистраторам, которые применяются в этой области.
Есть две области регистрации, которые открываются ASP.NET Core по умолчанию. Одним из них является HostingLogScope
он открывается в начале каждого запроса (если включено хотя бы критическое ведение журнала).
Регистраторы могут получить доступ к информации путем реализации BeginScope
метод, который получает HostingLogScope
объект передается ему в начале каждого запроса и просто перебирает объект, пока не найдет свойство:
string requestId = null;
if (state is IEnumerable<KeyValuePair<string, object>> properties)
{
foreach (var property in properties)
{
if (property.Key == "RequestId")
{
requestId = property.Value as string;
}
}
}
Serilog делает то же самое, но сохраняет все свойства в журнале событий. Вот почему вы не найдете явную ссылку на RequestId
но он все еще там, когда вы указываете формат строки журнала, чтобы включить его.