防止在未处理的异常发生时从日志记录Microsoft日志

问题描述 投票:0回答:1

我有ASP.NET Core 3.0网站。我在项目上安装了NLog,这是配置

public static void Main(string[] args)
{
    var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
    BuildWebHost(args).Run();
}

public static IWebHost BuildWebHost(string[] args)
{
    return WebHost.CreateDefaultBuilder(args)
        .ConfigureLogging(logging =>
        {
            logging.ClearProviders();
            logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
        })
        .UseNLog()
        .UseStartup<Startup>()
        .UseUrls("http://*:8080")
        .Build();
}



public class Startup
{
    // some constructors

    public void ConfigureServices(IServiceCollection services)
    {
        var serviceProvider = services.BuildServiceProvider();
        var logger = serviceProvider.GetService<ILogger<object>>();
        services.AddSingleton<ILogger>(logger);
    }
}

nlog.config文件是

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="false"
      throwExceptions="true"
      internalLogLevel="Off">

  <extensions>
    <add assembly="NLog.Web.AspNetCore"/>
  </extensions>

  <variable name="sperator" value="-----------------------------------" />

  <targets>
    <target name="allfile"
            xsi:type="File"
            fileName="${basedir}/Logs/${date:format=yyyy-MM-dd}.log"
            archiveEvery="Day"
            archiveFileName="${basedir}/Logs/Log${shortdate}-{#}.log"
            archiveNumbering="Sequence"
            layout="eventId : ${event-properties:item=EventId_Name}${newline}${message} ${newline} ${sperator} ${newline}" />

  </targets>

  <!-- rules to map from logger name to target -->
  <rules>
    <logger name="*" minlevel="Trace" writeTo="allfile" />
  </rules>
</nlog>

appsettings.config

"Logging": {
    "LogLevel": {
      "Default": "Trace",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },

最后我有一个中间件来处理从应用程序中各处抛出的所有异常

public class ExceptionMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger _logger;

    public ExceptionMiddleware(RequestDelegate next, ILogger logger)
    {
        _next = next;
        _logger = logger;
    }

    public async Task Invoke(HttpContext context)
    {
        context.Response.Clear();
        context.Response.ContentType = "application/json";

        var contextFeature = context.Features.Get<IExceptionHandlerFeature>();
        if (contextFeature == null)
            return;

        string jsonResult = "";

        context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;

        EventId eventId = new EventId(0, Guid.NewGuid().ToString());
        _logger.LogError(eventId, message: $"Date : {DateTime.Now.ToString()} \nPath : {context.Request.Path} \nStackTrace: {contextFeature.Error.ToString()}");

        jsonResult = JsonConvert.SerializeObject(new
        {
           ErrorMessage = contextFeature.Error.Message,
           StackTrace = contextFeature.Error.StackTrace
        });

        await context.Response.WriteAsync(jsonResult);
    }
}

问题是

当我引发异常时,我在日志文件中得到两个日志(即使我只记录一次)现在我确信第一个是由Asp.NET CORE自动完成的,因为该异常被视为未处理的异常(即使存在处理该异常的中间件)

这是我得到的日志

eventId : UnhandledException
An unhandled exception has occurred while executing the request. 
 ----------------------------------- 

eventId : 88e05695-fc66-4d99-8537-aba8f0fa211b
Date : 1/1/2020 5:09:17 PM 
Path : /api/AppParameter/ThrowException 
StackTrace: System.Exception: this exception has been throw for testing the NLog
   at BT_IQM.Services.WebApi.Controllers.AppParameterController.ThrowException() in C:\Users\BitegPC\Source\Repos\BT_Backend_Architecture\BT_IQM.Services.WebApi\Controllers\AppParameterController.cs:line 80
   at lambda_method(Closure , Object , Object[] )
   at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at BT_IQM.Services.WebApi.Utility.LanguageMiddleware.Invoke(HttpContext context) in C:\Users\BitegPC\Source\Repos\BT_Backend_Architecture\BT_IQM.Services.WebApi\Utility\LanguageMiddlewareExtensions.cs:line 27
   at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task) 
 ----------------------------------- 

第二个日志正是我在中间件中记录的内容,但是我的问题出在第一个日志中(我根本不想显示),第二个日志对我来说足够了]]

我认为我的问题出在日志记录的配置中(尤其是在appsettings.config文件中)

更新

这里是注册异常中间件的扩展方法

public static class ExceptionMiddlewareExtensions
{
    public static void ConfigureExceptionHandler(this IApplicationBuilder app, ILogger logger)
    {
        app.UseExceptionHandler(appError => appError.UseMiddleware<ExceptionMiddleware>());
    }
}

这是整个Configure方法

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger logger
{
    app.ConfigureExceptionHandler(logger);
    app.ConfigureLanguageMiddleware();

    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();

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

    app.UseSwagger();
    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
    });
}

我有ASP.NET Core 3.0网站。我在项目上安装了NLog,这是配置public static void Main(string [] args){var logger = NLogBuilder.ConfigureNLog(“ nlog.config”)....

c# asp.net-core nlog
1个回答
0
投票
app.UseExceptionHandler(appError => appError.UseMiddleware<ExceptionMiddleware>());
© www.soinside.com 2019 - 2024. All rights reserved.