Основываясь на подробностях этой записи в блоге Николаса Блюмхардта (я знаю, ей несколько лет назад, но я не могу найти ничего более актуального), я ожидаю, что смогу использовать следующее (минимальное ) и автоматически добавляю область в мое событие журнала, однако я ничего не получаю от поставщика консоли по умолчанию. В идеале это будет просто ключ=значение в строке журнала, но может подойти и json-объект {"key":"value".
Версия ASP.NET Core: 3.1
Версия Serilog: 2.10.0
Версия Serilog.AspNetCore: 3.4.0
Program.cs
public class Program
{
public static int Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.WriteTo.Console()
.CreateLogger();
try
{
Log.Information("Starting web host");
CreateHostBuilder(args).Build().Run();
return 0;
}
catch (Exception ex)
{
Log.Fatal(ex, "Host terminated unexpectedly");
return 1;
}
finally
{
Log.CloseAndFlush();
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSerilog()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
});
}
Startup.cs
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
WeatherForecastController.cs
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] _summaries = { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" };
private readonly ILogger _logger;
public WeatherForecastController(ILogger logger)
{
_logger = logger;
}
[HttpGet]
public IEnumerable Get()
{
var scopeProps = new Dictionary { ["dude"] = "123" };
using (_logger.BeginScope(scopeProps))
{
_logger.LogInformation("Hello world!");
}
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = _summaries[rng.Next(_summaries.Length)]
})
.ToArray();
}
}
Журналы (обратите внимание на строку «Hello World», в которой нет слов «чувак» или «123»)
[15:47:09 INF] Starting web host
[15:47:11 INF] Now listening on: https://localhost:5001
[15:47:11 INF] Now listening on: http://localhost:5000
[15:47:11 INF] Application started. Press Ctrl+C to shut down.
[15:47:11 INF] Hosting environment: Development
[15:47:11 INF] Content root path: C:\Users\a806228\source\repos\WebApplication10\WebApplication10
[15:47:13 INF] Request starting HTTP/2 GET https://localhost:5001/weatherforecast
[15:47:13 INF] Executing endpoint 'WebApplication10.Controllers.WeatherForecastController.Get (WebApplication10)'
[15:47:13 INF] Route matched with {action = "Get", controller = "WeatherForecast"}. Executing controller action with signature System.Collections.Generic.IEnumerable`1[WebApplication10.WeatherForecast] Get() on controller WebApplication10.Controllers.WeatherForecastController (WebApplication10).
[15:47:13 INF] Hello world!
[15:47:13 INF] Executing ObjectResult, writing value of type 'WebApplication10.WeatherForecast[]'.
[15:47:13 INF] Executed action WebApplication10.Controllers.WeatherForecastController.Get (WebApplication10) in 197.2872ms
[15:47:13 INF] Executed endpoint 'WebApplication10.Controllers.WeatherForecastController.Get (WebApplication10)'
[15:47:13 INF] Request finished in 533.989ms 200 application/json; charset=utf-8
Я также пробовал добавить RenderedCompactJsonFormatter, но это тоже не дало того, что я ожидаю (судя по вышеупомянутому сообщению в блоге).Журналы RenderedCompactJsonFormatter (обратите внимание, что свойства области вложены в свойство «Область», а не на верхний уровень объекта json).
{"@t":"2021-02-24T23:56:08.5102552Z","@m":"Content root path: \"C:\\Users\\a806228\\source\\repos\\WebApplication10\\WebApplication10\"","@i":"b5d60022","contentRoot":"C:\\Users\\a806228\\source\\repos\\WebApplication10\\WebApplication10","SourceContext":"Microsoft.Hosting.Lifetime"}
{"@t":"2021-02-24T23:56:10.2879619Z","@m":"Request starting HTTP/2 GET https://localhost:5001/weatherforecast ","@i":"ca22a1cb","Protocol":"HTTP/2","Method":"GET","ContentType":null,"ContentLength":null,"Scheme":"https","Host":"localhost:5001","PathBase":"","Path":"/weatherforecast","QueryString":"","HostingRequestStartingLog":"Request starting HTTP/2 GET https://localhost:5001/weatherforecast ","EventId":{"Id":1},"SourceContext":"Microsoft.AspNetCore.Hosting.Diagnostics","RequestId":"0HM6P3V0MULJ3:00000001","RequestPath":"/weatherforecast","SpanId":"|705afff2-40607f543d36f77d.","TraceId":"705afff2-40607f543d36f77d","ParentId":""}
{"@t":"2021-02-24T23:56:10.3924937Z","@m":"Executing endpoint '\"WebApplication10.Controllers.WeatherForecastController.Get (WebApplication10)\"'","@i":"500cc934","EndpointName":"WebApplication10.Controllers.WeatherForecastController.Get (WebApplication10)","EventId":{"Name":"ExecutingEndpoint"},"SourceContext":"Microsoft.AspNetCore.Routing.EndpointMiddleware","RequestId":"0HM6P3V0MULJ3:00000001","RequestPath":"/weatherforecast","SpanId":"|705afff2-40607f543d36f77d.","TraceId":"705afff2-40607f543d36f77d","ParentId":""}
{"@t":"2021-02-24T23:56:10.5410912Z","@m":"Route matched with \"{action = \\\"Get\\\", controller = \\\"WeatherForecast\\\"}\". Executing controller action with signature \"System.Collections.Generic.IEnumerable`1[WebApplication10.WeatherForecast] Get()\" on controller \"WebApplication10.Controllers.WeatherForecastController\" (\"WebApplication10\").","@i":"122b2fdf","RouteData":"{action = \"Get\", controller = \"WeatherForecast\"}","MethodInfo":"System.Collections.Generic.IEnumerable`1[WebApplication10.WeatherForecast] Get()","Controller":"WebApplication10.Controllers.WeatherForecastController","AssemblyName":"WebApplication10","EventId":{"Id":3,"Name":"ControllerActionExecuting"},"SourceContext":"Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker","ActionId":"e2ddfe67-f10f-4720-b5f3-d7219eac02de","ActionName":"WebApplication10.Controllers.WeatherForecastController.Get (WebApplication10)","RequestId":"0HM6P3V0MULJ3:00000001","RequestPath":"/weatherforecast","SpanId":"|705afff2-40607f543d36f77d.","TraceId":"705afff2-40607f543d36f77d","ParentId":""}
{"@t":"2021-02-24T23:56:10.5548872Z","@m":"Hello world!","@i":"cc6ac8ad","SourceContext":"WebApplication10.Controllers.WeatherForecastController","ActionId":"e2ddfe67-f10f-4720-b5f3-d7219eac02de","ActionName":"WebApplication10.Controllers.WeatherForecastController.Get (WebApplication10)","RequestId":"0HM6P3V0MULJ3:00000001","RequestPath":"/weatherforecast","SpanId":"|705afff2-40607f543d36f77d.","TraceId":"705afff2-40607f543d36f77d","ParentId":"","Scope":[{"dude":"123"}]}
{"@t":"2021-02-24T23:56:10.6437907Z","@m":"Executing ObjectResult, writing value of type '\"WebApplication10.WeatherForecast[]\"'.","@i":"8a1b66c8","Type":"WebApplication10.WeatherForecast[]","EventId":{"Id":1,"Name":"ObjectResultExecuting"},"SourceContext":"Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor","ActionId":"e2ddfe67-f10f-4720-b5f3-d7219eac02de","ActionName":"WebApplication10.Controllers.WeatherForecastController.Get (WebApplication10)","RequestId":"0HM6P3V0MULJ3:00000001","RequestPath":"/weatherforecast","SpanId":"|705afff2-40607f543d36f77d.","TraceId":"705afff2-40607f543d36f77d","ParentId":""}
{"@t":"2021-02-24T23:56:10.7730179Z","@m":"Executed action \"WebApplication10.Controllers.WeatherForecastController.Get (WebApplication10)\" in 181.1047ms","@i":"afa2e885","ActionName":"WebApplication10.Controllers.WeatherForecastController.Get (WebApplication10)","ElapsedMilliseconds":181.1047,"EventId":{"Id":2,"Name":"ActionExecuted"},"SourceContext":"Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker","ActionId":"e2ddfe67-f10f-4720-b5f3-d7219eac02de","RequestId":"0HM6P3V0MULJ3:00000001","RequestPath":"/weatherforecast","SpanId":"|705afff2-40607f543d36f77d.","TraceId":"705afff2-40607f543d36f77d","ParentId":""}
{"@t":"2021-02-24T23:56:10.8005134Z","@m":"Executed endpoint '\"WebApplication10.Controllers.WeatherForecastController.Get (WebApplication10)\"'","@i":"99874f2b","EndpointName":"WebApplication10.Controllers.WeatherForecastController.Get (WebApplication10)","EventId":{"Id":1,"Name":"ExecutedEndpoint"},"SourceContext":"Microsoft.AspNetCore.Routing.EndpointMiddleware","RequestId":"0HM6P3V0MULJ3:00000001","RequestPath":"/weatherforecast","SpanId":"|705afff2-40607f543d36f77d.","TraceId":"705afff2-40607f543d36f77d","ParentId":""}
{"@t":"2021-02-24T23:56:10.8202960Z","@m":"Request finished in 538.2013ms 200 application/json; charset=utf-8","@i":"791a596a","ElapsedMilliseconds":538.2013,"StatusCode":200,"ContentType":"application/json; charset=utf-8","HostingRequestFinishedLog":"Request finished in 538.2013ms 200 application/json; charset=utf-8","EventId":{"Id":2},"SourceContext":"Microsoft.AspNetCore.Hosting.Diagnostics","RequestId":"0HM6P3V0MULJ3:00000001","RequestPath":"/weatherforecast","SpanId":"|705afff2-40607f543d36f77d.","TraceId":"705afff2-40607f543d36f77d","ParentId":""}
Кроме того, я знаю, что могу специально использовать методы LogContext.PushProperty из Serilog, но как специалист по сопровождению библиотеки мне бы очень хотелось избежать этого и позволить моим вызывающим объектам использовать интерфейс Microsoft ILogger (и область действия) для взаимодействия с журналированием в ASP.NET Core, поскольку это дает мне больше гибкости в долгосрочной перспективе.
Изменить: меня особенно интересует Microsoft ILogger интерфейс, НИЧЕГО, СВЯЗАННОГО конкретно с Serilog. На самом деле меня не волнует «контекст», потому что я хочу стандартизировать «область действия» — концепцию .NET (а не концепцию Serilog). Меня не волнуют все остальные «свойства», потому что это концепция «Serilog», а не концепция «Microsoft».
Добавление «Свойства» в «outputTemplate» не является то, о чем я прошу. Это можно сделать с помощью следующего кода:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSerilog(
(context, configuration) =>
{
configuration.WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} Properties={Properties:j}{NewLine}{Exception}");
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
});
Создает подобную строку журнала (обратите внимание, что область действия по-прежнему вложена в свойства как конкретное свойство).
[17:39:39 INF] Hello world! Properties={"SourceContext": "WebApplication10.Controllers.WeatherForecastController", "ActionId": "09a79aaf-7b21-46d2-b142-70d17fa41213", "ActionName": "WebApplication10.Controllers.WeatherForecastController.Get (WebApplication10)", "RequestId": "0HM6P5OR3IC2K:00000001", "RequestPath": "/weatherforecast", "SpanId": "|1c7f1f94-446bb6d3ebf05f96.", "TraceId": "1c7f1f94-446bb6d3ebf05f96", "ParentId": "", "Scope": [{"dude": "123"}]}
Я хочу, чтобы область ведения журнала отображалась таким образом, который соответствует тому, как отображается контекст.
Вот способ Serilog сделать это .
// Program.cs
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSerilog(
(context, configuration) =>
{
// add properties
configuration
.Enrich.FromLogContext()
.WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} {Properties:j}{NewLine}{Exception}");
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
});
// WeatherForecastController.cs
[HttpGet]
public IEnumerable Get()
{
// use Serilog's LogContext instead of _logger.BeginScope()
using (LogContext.PushProperty("dude", 123))
{
_logger.LogInformation("Hello world!");
}
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = _summaries[rng.Next(_summaries.Length)]
})
.ToArray();
}
Он должен создавать ту же самую строку журнала, что и при непосредственном добавлении в область действия (однако область действия вложена в свойства, а не является элементом свойств верхнего уровня, как свойство контекста, которое я добавляю). )
[17:51:35 INF] Hello world! {"SourceContext": "WebApplication10.Controllers.WeatherForecastController", "ActionId": "e0997db9-b301-495d-9cfc-7f2d2113f6f2", "ActionName": "WebApplication10.Controllers.WeatherForecastController.Get (WebApplication10)", "RequestId": "0HM6P5VGQ0U9J:00000001", "RequestPath": "/weatherforecast", "SpanId": "|1134d47e-49ed237c257f2857.", "TraceId": "1134d47e-49ed237c257f2857", "ParentId": "", "dude": 123}
Подробнее здесь: https://stackoverflow.com/questions/663 ... fts-ilogge
Как включить область действия в консольный приемник Serilog при использовании Microsoft ILogger? ⇐ C#
Место общения программистов C#
1712901351
Anonymous
Основываясь на подробностях этой записи в блоге Николаса Блюмхардта (я знаю, ей несколько лет назад, но я не могу найти ничего более актуального), я ожидаю, что смогу использовать следующее (минимальное ) и автоматически добавляю область в мое событие журнала, однако я ничего не получаю от поставщика консоли по умолчанию. В идеале это будет просто ключ=значение в строке журнала, но может подойти и json-объект {"key":"value".
Версия ASP.NET Core: 3.1
Версия Serilog: 2.10.0
Версия Serilog.AspNetCore: 3.4.0
Program.cs
public class Program
{
public static int Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.WriteTo.Console()
.CreateLogger();
try
{
Log.Information("Starting web host");
CreateHostBuilder(args).Build().Run();
return 0;
}
catch (Exception ex)
{
Log.Fatal(ex, "Host terminated unexpectedly");
return 1;
}
finally
{
Log.CloseAndFlush();
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSerilog()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
});
}
Startup.cs
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
WeatherForecastController.cs
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] _summaries = { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" };
private readonly ILogger _logger;
public WeatherForecastController(ILogger logger)
{
_logger = logger;
}
[HttpGet]
public IEnumerable Get()
{
var scopeProps = new Dictionary { ["dude"] = "123" };
using (_logger.BeginScope(scopeProps))
{
_logger.LogInformation("Hello world!");
}
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = _summaries[rng.Next(_summaries.Length)]
})
.ToArray();
}
}
Журналы (обратите внимание на строку «Hello World», в которой нет слов «чувак» или «123»)
[15:47:09 INF] Starting web host
[15:47:11 INF] Now listening on: https://localhost:5001
[15:47:11 INF] Now listening on: http://localhost:5000
[15:47:11 INF] Application started. Press Ctrl+C to shut down.
[15:47:11 INF] Hosting environment: Development
[15:47:11 INF] Content root path: C:\Users\a806228\source\repos\WebApplication10\WebApplication10
[15:47:13 INF] Request starting HTTP/2 GET https://localhost:5001/weatherforecast
[15:47:13 INF] Executing endpoint 'WebApplication10.Controllers.WeatherForecastController.Get (WebApplication10)'
[15:47:13 INF] Route matched with {action = "Get", controller = "WeatherForecast"}. Executing controller action with signature System.Collections.Generic.IEnumerable`1[WebApplication10.WeatherForecast] Get() on controller WebApplication10.Controllers.WeatherForecastController (WebApplication10).
[15:47:13 INF] Hello world!
[15:47:13 INF] Executing ObjectResult, writing value of type 'WebApplication10.WeatherForecast[]'.
[15:47:13 INF] Executed action WebApplication10.Controllers.WeatherForecastController.Get (WebApplication10) in 197.2872ms
[15:47:13 INF] Executed endpoint 'WebApplication10.Controllers.WeatherForecastController.Get (WebApplication10)'
[15:47:13 INF] Request finished in 533.989ms 200 application/json; charset=utf-8
Я также пробовал добавить RenderedCompactJsonFormatter, но это тоже не дало того, что я ожидаю (судя по вышеупомянутому сообщению в блоге).Журналы RenderedCompactJsonFormatter (обратите внимание, что свойства области вложены в свойство «Область», а не на верхний уровень объекта json).
{"@t":"2021-02-24T23:56:08.5102552Z","@m":"Content root path: \"C:\\Users\\a806228\\source\\repos\\WebApplication10\\WebApplication10\"","@i":"b5d60022","contentRoot":"C:\\Users\\a806228\\source\\repos\\WebApplication10\\WebApplication10","SourceContext":"Microsoft.Hosting.Lifetime"}
{"@t":"2021-02-24T23:56:10.2879619Z","@m":"Request starting HTTP/2 GET https://localhost:5001/weatherforecast ","@i":"ca22a1cb","Protocol":"HTTP/2","Method":"GET","ContentType":null,"ContentLength":null,"Scheme":"https","Host":"localhost:5001","PathBase":"","Path":"/weatherforecast","QueryString":"","HostingRequestStartingLog":"Request starting HTTP/2 GET https://localhost:5001/weatherforecast ","EventId":{"Id":1},"SourceContext":"Microsoft.AspNetCore.Hosting.Diagnostics","RequestId":"0HM6P3V0MULJ3:00000001","RequestPath":"/weatherforecast","SpanId":"|705afff2-40607f543d36f77d.","TraceId":"705afff2-40607f543d36f77d","ParentId":""}
{"@t":"2021-02-24T23:56:10.3924937Z","@m":"Executing endpoint '\"WebApplication10.Controllers.WeatherForecastController.Get (WebApplication10)\"'","@i":"500cc934","EndpointName":"WebApplication10.Controllers.WeatherForecastController.Get (WebApplication10)","EventId":{"Name":"ExecutingEndpoint"},"SourceContext":"Microsoft.AspNetCore.Routing.EndpointMiddleware","RequestId":"0HM6P3V0MULJ3:00000001","RequestPath":"/weatherforecast","SpanId":"|705afff2-40607f543d36f77d.","TraceId":"705afff2-40607f543d36f77d","ParentId":""}
{"@t":"2021-02-24T23:56:10.5410912Z","@m":"Route matched with \"{action = \\\"Get\\\", controller = \\\"WeatherForecast\\\"}\". Executing controller action with signature \"System.Collections.Generic.IEnumerable`1[WebApplication10.WeatherForecast] Get()\" on controller \"WebApplication10.Controllers.WeatherForecastController\" (\"WebApplication10\").","@i":"122b2fdf","RouteData":"{action = \"Get\", controller = \"WeatherForecast\"}","MethodInfo":"System.Collections.Generic.IEnumerable`1[WebApplication10.WeatherForecast] Get()","Controller":"WebApplication10.Controllers.WeatherForecastController","AssemblyName":"WebApplication10","EventId":{"Id":3,"Name":"ControllerActionExecuting"},"SourceContext":"Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker","ActionId":"e2ddfe67-f10f-4720-b5f3-d7219eac02de","ActionName":"WebApplication10.Controllers.WeatherForecastController.Get (WebApplication10)","RequestId":"0HM6P3V0MULJ3:00000001","RequestPath":"/weatherforecast","SpanId":"|705afff2-40607f543d36f77d.","TraceId":"705afff2-40607f543d36f77d","ParentId":""}
{"@t":"2021-02-24T23:56:10.5548872Z","@m":"Hello world!","@i":"cc6ac8ad","SourceContext":"WebApplication10.Controllers.WeatherForecastController","ActionId":"e2ddfe67-f10f-4720-b5f3-d7219eac02de","ActionName":"WebApplication10.Controllers.WeatherForecastController.Get (WebApplication10)","RequestId":"0HM6P3V0MULJ3:00000001","RequestPath":"/weatherforecast","SpanId":"|705afff2-40607f543d36f77d.","TraceId":"705afff2-40607f543d36f77d","ParentId":"","Scope":[{"dude":"123"}]}
{"@t":"2021-02-24T23:56:10.6437907Z","@m":"Executing ObjectResult, writing value of type '\"WebApplication10.WeatherForecast[]\"'.","@i":"8a1b66c8","Type":"WebApplication10.WeatherForecast[]","EventId":{"Id":1,"Name":"ObjectResultExecuting"},"SourceContext":"Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor","ActionId":"e2ddfe67-f10f-4720-b5f3-d7219eac02de","ActionName":"WebApplication10.Controllers.WeatherForecastController.Get (WebApplication10)","RequestId":"0HM6P3V0MULJ3:00000001","RequestPath":"/weatherforecast","SpanId":"|705afff2-40607f543d36f77d.","TraceId":"705afff2-40607f543d36f77d","ParentId":""}
{"@t":"2021-02-24T23:56:10.7730179Z","@m":"Executed action \"WebApplication10.Controllers.WeatherForecastController.Get (WebApplication10)\" in 181.1047ms","@i":"afa2e885","ActionName":"WebApplication10.Controllers.WeatherForecastController.Get (WebApplication10)","ElapsedMilliseconds":181.1047,"EventId":{"Id":2,"Name":"ActionExecuted"},"SourceContext":"Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker","ActionId":"e2ddfe67-f10f-4720-b5f3-d7219eac02de","RequestId":"0HM6P3V0MULJ3:00000001","RequestPath":"/weatherforecast","SpanId":"|705afff2-40607f543d36f77d.","TraceId":"705afff2-40607f543d36f77d","ParentId":""}
{"@t":"2021-02-24T23:56:10.8005134Z","@m":"Executed endpoint '\"WebApplication10.Controllers.WeatherForecastController.Get (WebApplication10)\"'","@i":"99874f2b","EndpointName":"WebApplication10.Controllers.WeatherForecastController.Get (WebApplication10)","EventId":{"Id":1,"Name":"ExecutedEndpoint"},"SourceContext":"Microsoft.AspNetCore.Routing.EndpointMiddleware","RequestId":"0HM6P3V0MULJ3:00000001","RequestPath":"/weatherforecast","SpanId":"|705afff2-40607f543d36f77d.","TraceId":"705afff2-40607f543d36f77d","ParentId":""}
{"@t":"2021-02-24T23:56:10.8202960Z","@m":"Request finished in 538.2013ms 200 application/json; charset=utf-8","@i":"791a596a","ElapsedMilliseconds":538.2013,"StatusCode":200,"ContentType":"application/json; charset=utf-8","HostingRequestFinishedLog":"Request finished in 538.2013ms 200 application/json; charset=utf-8","EventId":{"Id":2},"SourceContext":"Microsoft.AspNetCore.Hosting.Diagnostics","RequestId":"0HM6P3V0MULJ3:00000001","RequestPath":"/weatherforecast","SpanId":"|705afff2-40607f543d36f77d.","TraceId":"705afff2-40607f543d36f77d","ParentId":""}
Кроме того, я знаю, что могу специально использовать методы LogContext.PushProperty из Serilog, но как специалист по сопровождению библиотеки мне бы очень хотелось избежать этого и позволить моим вызывающим объектам использовать интерфейс Microsoft ILogger (и область действия) для взаимодействия с журналированием в ASP.NET Core, поскольку это дает мне больше гибкости в долгосрочной перспективе.
Изменить: меня особенно интересует Microsoft ILogger интерфейс, НИЧЕГО, СВЯЗАННОГО конкретно с Serilog. На самом деле меня не волнует «контекст», потому что я хочу стандартизировать «область действия» — концепцию .NET (а не концепцию Serilog). Меня не волнуют все остальные «свойства», потому что это концепция «Serilog», а не концепция «Microsoft».
Добавление «Свойства» в «outputTemplate» не является то, о чем я прошу. Это можно сделать с помощью следующего кода:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSerilog(
(context, configuration) =>
{
configuration.WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} Properties={Properties:j}{NewLine}{Exception}");
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
});
Создает подобную строку журнала (обратите внимание, что область действия по-прежнему вложена в свойства как конкретное свойство).
[17:39:39 INF] Hello world! Properties={"SourceContext": "WebApplication10.Controllers.WeatherForecastController", "ActionId": "09a79aaf-7b21-46d2-b142-70d17fa41213", "ActionName": "WebApplication10.Controllers.WeatherForecastController.Get (WebApplication10)", "RequestId": "0HM6P5OR3IC2K:00000001", "RequestPath": "/weatherforecast", "SpanId": "|1c7f1f94-446bb6d3ebf05f96.", "TraceId": "1c7f1f94-446bb6d3ebf05f96", "ParentId": "", "Scope": [{"dude": "123"}]}
Я хочу, чтобы область ведения журнала отображалась таким образом, который соответствует тому, как отображается контекст.
Вот способ Serilog сделать это .
// Program.cs
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSerilog(
(context, configuration) =>
{
// add properties
configuration
.Enrich.FromLogContext()
.WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} {Properties:j}{NewLine}{Exception}");
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
});
// WeatherForecastController.cs
[HttpGet]
public IEnumerable Get()
{
// use Serilog's LogContext instead of _logger.BeginScope()
using (LogContext.PushProperty("dude", 123))
{
_logger.LogInformation("Hello world!");
}
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = _summaries[rng.Next(_summaries.Length)]
})
.ToArray();
}
Он должен создавать ту же самую строку журнала, что и при непосредственном добавлении в область действия (однако область действия вложена в свойства, а не является элементом свойств верхнего уровня, как свойство контекста, которое я добавляю). )
[17:51:35 INF] Hello world! {"SourceContext": "WebApplication10.Controllers.WeatherForecastController", "ActionId": "e0997db9-b301-495d-9cfc-7f2d2113f6f2", "ActionName": "WebApplication10.Controllers.WeatherForecastController.Get (WebApplication10)", "RequestId": "0HM6P5VGQ0U9J:00000001", "RequestPath": "/weatherforecast", "SpanId": "|1134d47e-49ed237c257f2857.", "TraceId": "1134d47e-49ed237c257f2857", "ParentId": "", "dude": 123}
Подробнее здесь: [url]https://stackoverflow.com/questions/66360594/how-do-i-include-scope-with-serilogs-console-sink-when-using-microsofts-ilogge[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия