簡體   English   中英

Blazor 中的 Serilog LogContext 與 IIS 站點綁定

[英]Serilog LogContext in Blazor with IIS Site Bindings

我在我的Blazor 服務器端應用程序中使用Serilog ,它使用站點綁定部署在IISIIS 站點綁定

而且我想確保這些站點上的日志(未處理的異常和我的自定義日志信息)按主機名寫入不同的文件夾。

我的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");

Program.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嗎?

以下是邏輯調用上下文如何與異步代碼一起使用。 邏輯調用上下文數據與 ExecutionContext 一起流動。 這意味着它不受 ConfigureAwait(continueOnCapturedContext: false); 的影響。 您不能“選擇退出”邏輯調用上下文。 因此,異步方法開頭的邏輯調用上下文將始終流向其延續。 當異步方法啟動時,它會通知其邏輯調用上下文以激活寫時復制行為。 這意味着當前的邏輯調用上下文實際上並沒有改變,但是它被標記,這樣如果你的代碼確實調用了 CallContext.LogicalSetData,邏輯調用上下文數據在它被改變之前被復制到一個新的當前邏輯調用上下文中。 注意:邏輯調用上下文的寫時復制行為僅在 .NET 4.5 上可用。

在此處閱讀有關 AsyncLocal 的更多信息

請注意這些:因此,異步方法開頭的邏輯調用上下文(AsyncLocal)始終流向其延續(在您的示例中,這是當前中間件之后的所有中間件)。

因此,在您的情況下,每個請求都有自己的邏輯調用上下文,因此您可以確定來自 test-t1.com 的消息永遠不會寫入 \logs\test-t2.com?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM