【问题标题】:Serilog LogContext in Blazor with IIS Site Bindings带有 IIS 站点绑定的 Blazor 中的 Serilog LogContext
【发布时间】:2022-09-26 17:01:23
【问题描述】:

我用Serilog在我的Blazor 服务器侧应用程序,部署在IIS使用站点绑定

我想确保将这些站点上的日志(未处理的异常和我的自定义日志信息)写入不同的文件夹由主机名.

我的Serilog 配置

public static class HostBuilderExtension
{
  public static IHostBuilder AddSerilog(this IHostBuilder hostBuilder)
  {
    return hostBuilder.UseSerilog((hostingContext, loggerConfiguration) =>
    {
      var appSettings = hostingContext.Configuration.Get<AppSettings>();
      loggerConfiguration
      .ReadFrom.Configuration(hostingContext.Configuration)
      .Enrich.FromLogContext()
      .WriteTo.Map(\"Hostname\", \"ms-hosting\", (hostname, wr) =>
        wr.Async(to =>
        to.File(appSettings.GeneralLogsPath(hostname), rollingInterval: RollingInterval.Day, shared: true)));
    });
  }
}

一般日志路径

public string GeneralLogsPath(string hostname) => Path.Combine(AppLogsRoot, hostname, \"General\", \"log.log\");

登记在程序.cs

builder.Host.AddSerilog();

还有我的习惯中间件将当前主机名推送到 LogContext:

using Serilog.Context;
using System.Collections.Generic;

namespace Herbst.Acc2.CustomerWebUI.Classes;

public class ScopedLoggingMiddleware
{
  private readonly RequestDelegate _next;
  private readonly ILogger<ScopedLoggingMiddleware> _logger;
  public ScopedLoggingMiddleware(RequestDelegate next, ILogger<ScopedLoggingMiddleware> logger)
  {
    _next = next ?? throw new ArgumentNullException(nameof(next));
    _logger = logger ?? throw new ArgumentNullException(nameof(logger));
  }

  public async Task Invoke(HttpContext context)
  {
    if (context == null) throw new ArgumentNullException(nameof(context));

    var hostname = context.Request.Host.Host;

    try
    {
      using (LogContext.PushProperty(\"Hostname\", hostname))
      {
        await _next(context);
      }
    }
    //To make sure that we don\'t loose the scope in case of an unexpected error
    catch (Exception ex) when (LogOnUnexpectedError(ex))
    {
      return;
    }
  }

  private bool LogOnUnexpectedError(Exception ex)
  {
    _logger.LogError(ex, \"An unexpected exception occured!\");
    return true;
  }
}

public static class ScopedLoggingMiddlewareExtensions
{
  public static IApplicationBuilder UseScopedLogging(this IApplicationBuilder builder)
  {
    return builder.UseMiddleware<ScopedLoggingMiddleware>();
  }
}

在 Program.cs 中

app.UseScopedLogging();

我可以确定来自test-t1.com 永远不会写\\logs\\test-t2.com?

  • 你测试过你的代码吗?你有遇到什么不寻常的情况吗?
  • @samwu,这段代码运行良好(至少在我的测试中)。特别是,我想了解为什么如果我从 test-t1.com 中间件推送主机名并在 test-t2.com 上突然出现未处理的异常(未处理中间件中的请求),它将被记录在 \\logs\\测试-t2.com。
  • 您可以分享有关未处理异常的详细信息吗?是否可以使用 try catch 调试代码以查看异常原因?
  • @samwu,我自己抛出这个异常,看看如果我将 LogContext 属性推送到另一个 url 中它会写在哪里
  • 我在您的帖子中没有看到异常,或者您可以尝试通过以下方式打开案例:support.microsoft.com

标签: c# logging iis blazor serilog-aspnetcore


【解决方案1】:

以下是逻辑调用上下文如何与异步代码一起使用。 逻辑调用上下文数据与 ExecutionContext 一起流动。这意味着它不受 ConfigureAwait(continueOnCapturedContext: false); 的影响。您不能“选择退出”逻辑调用上下文。因此,异步方法开头的逻辑调用上下文将始终流向其延续。 当异步方法启动时,它会通知其逻辑调用上下文以激活写时复制行为。这意味着当前的逻辑调用上下文实际上并没有改变,但是它被标记以便如果你的代码确实调用了 CallContext.LogicalSetData,逻辑调用上下文数据在它被改变之前被复制到一个新的当前逻辑调用上下文中。注意:逻辑调用上下文的写时复制行为仅在 .NET 4.5 上可用。

Read more about AsyncLocal here

注意这些: 所以逻辑调用上下文(AsyncLocal)在一个开始异步方法将要总是流向其延续(在您的示例中,这是当前中间件之后的所有中间件)。

因此,在您的情况下,每个请求都有自己的逻辑调用上下文,所以您可以确定来自 test-t1.com 的消息永远不会写入 \logs\test-t2.com?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-26
    • 1970-01-01
    • 1970-01-01
    • 2018-04-27
    • 1970-01-01
    • 2010-09-18
    相关资源
    最近更新 更多