带有IIS站点绑定的Blazor中的Serilog LogContext

czq61nw1  于 2022-11-12  发布在  其他
关注(0)|答案(1)|浏览(153)

我在Blazor Server端应用程序中使用Serilog,该应用程序使用站点绑定x1c 0d1x部署在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");

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*?

hgb9j2n6

hgb9j2n61#

下面是逻辑调用上下文如何与异步代码一起工作。逻辑调用上下文数据与ExecutionContext一起流动。这意味着它不受ConfigureAwait(continueOnCapturedContext:错误);您不能“选择退出”逻辑调用上下文。因此,异步方法开始时的逻辑调用上下文将始终流向它的后续。当异步方法启动时,它会通知其逻辑调用上下文激活写入时复制行为。这意味着当前逻辑调用上下文实际上并没有改变,但它被标记为如果您的代码确实调用了CallContext.LogicalSetData,逻辑调用上下文数据在被改变之前被复制到新的当前逻辑调用上下文中。逻辑调用程序上下文写时复制行为仅在.NET4.5上可用。
Read more about AsyncLocal here
请注意以下几点:因此,异步方法开头的逻辑调用上下文(AsyncLocal)始终流向其延续(在您的示例中,这是当前中间件之后的所有中间件)。
因此,在您的情况下,每个请求都将有自己的逻辑调用上下文,因此您可以确保来自www.example.com的消息test-t1.com永远不会写入\logs\test-t2.com?

相关问题