c# - 无法在 .NET 6 项目上使用 Serilog 中间件

标签 c# serilog .net-6.0 botnet serilog-exceptions

我正在构建一个 .NET 6 项目并尝试让 Serilog 在其上正常工作。

一切似乎都工作正常,但是当我尝试为请求添加 SerilogMiddlware 时,我收到此异常: 尝试激活“Serilog.AspNetCore.RequestLoggingMiddleware”时无法解析类型“Serilog.Extensions.Hosting.DiagnosticContext”的服务。

当我在启动文件中添加 app.UseSerilogRequestLogging() 时,在 Configure 方法上,我收到了我提到的异常。

我找不到如何在 .NET 6 上实现 Serilog 的正确示例,仅在 .NET 5 上,而且我也找不到与我有相同问题的人。

我只是不知道出了什么问题,这里有我的 Program.csStartup.cs 文件。

下面的Program.cs:

using {ProjectUsing};
using {ProjectUsing};
using Serilog;

SerilogConfiguration.ConfigureSerilog();

try
{
    var builder = WebApplication.CreateBuilder(args)
        .UseStartup<Startup>();
    
    builder.Host.UseSerilog((context, services, configuration) => configuration
        .WriteTo.Console()
        .ReadFrom.Configuration(context.Configuration)
        .ReadFrom.Services(services)
        .Enrich.FromLogContext()
        .Enrich.WithEnvironmentName()
        .Enrich.WithMachineName()
        .WriteTo.Console(
            outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} {Properties:j}{NewLine}{Exception}"));
}
catch (Exception ex)
{
    Log.Fatal(ex, "Error during initialization");
}
finally
{
    Log.Information("App finished");
    Log.CloseAndFlush();
}

下面的Startup.cs:

using {ProjectUsing};
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using Serilog;
using Serilog.Events;
using Serilog.Configuration;
using Serilog.Events;
using ILogger = Microsoft.Extensions.Logging.ILogger;

namespace {ProjectUsing}
{
    public class Startup : IStartup
    {
        public IConfiguration Configuration { get; }

        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public void ConfigureServices(IServiceCollection services)
        {
            // Add services to the container.
            services.AddControllers();

            // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
            services.AddEndpointsApiExplorer();
            services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "Project", Version = "v1" }); });

            // Other Configurations
            services.ConfigureDbContext(Configuration);
            services.ConfigureProjectRepositories();
        }

        public void Configure(WebApplication app, IWebHostEnvironment environment)
        {
            // Configure the HTTP request pipeline.
            if (app.Environment.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseSwagger();
                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Project - v1"));
            }

            
            // I get the exception I mentioned when I add the following line:
            app.UseSerilogRequestLogging();

            app.UseHttpsRedirection();
            
            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
        }
    }

    public interface IStartup
    {
        IConfiguration Configuration { get; }
        void Configure(WebApplication app, IWebHostEnvironment environment);
        void ConfigureServices(IServiceCollection services);
    }

    public static class StartupExtensions
    {
        public static WebApplicationBuilder UseStartup<TStartup>(this WebApplicationBuilder WebAppBuilder) where TStartup: IStartup
        {
            var startup = Activator.CreateInstance(typeof(TStartup), WebAppBuilder.Configuration) as IStartup;
            if (startup == null) throw new ArgumentException("Invalid Startup.cs");

            startup.ConfigureServices(WebAppBuilder.Services);

            var app = WebAppBuilder.Build();
            startup.Configure(app, app.Environment);

            app.Run();

            return WebAppBuilder;
        }
    }
}

最佳答案

我不太确定为什么它不适用于您的特定场景,但是当您添加 app.UseSerilogRequestLogging() 时,需要使用 UseSerilog()。这是您代码中的一个案例。但是,Startup 的调用顺序可能是问题,因为 UseSerilogRequestLogging 将在 UseSerilog

之前调用

在 .Net 6 中,当您没有 Startup 和 Main 类时,可以在 program.cs 中使用它,例如:

try
{
    var builder = WebApplication.CreateBuilder(args);
    var logger = new LoggerConfiguration()
                        .ReadFrom.Configuration(builder.Configuration)
                        .Enrich.FromLogContext()
                        .CreateLogger();
    builder.Host.UseSerilog(logger);

    // more configuration

    var app = builder.Build();
    app.UseSerilogRequestLogging();

    // more configs
    app.Run();
}
catch (Exception ex)
{
    Log.Fatal(ex, "Unhandled exception");
}
finally
{
    Log.Information("Shut down complete");
    Log.CloseAndFlush();
} 

关于c# - 无法在 .NET 6 项目上使用 Serilog 中间件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70483282/

相关文章:

c# - 将包含不同类型的两个集合相交

c# - Swig:将 std::vector<unsigned char> 传递给从 c++ 生成的 c# 函数

c# - Serilog 只记录数组的第一个元素

.net-core - 从环境变量设置 Serilog 最低级别

c# - 使用 OpenAPI 启动 HttpTrigger 时主机尚未启动

c# - MS Logger 工厂和 Serilog 将日志消息写入文件时出现问题

c# - 不同的编程语言有哪些优点?

c# - 使用 C# 验证 CSS 语法

c# - 使用 serilog 解构开放泛型

c# - .Net6 WPF 应用程序的 PublishReadyToRun 问题