Mr Perfect
Mr Perfect

Reputation: 685

How to log exception to appinsights using serilog?

Net core application. I am trying to log exceptions but this is not working as expected. Below is my configuration

Program.cs

 public static void Main(string[] args)
        {
        Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(configuration).CreateLogger();
        }
 public static IHostBuilder CreateHostBuilder(string[] args) =>
                Host.CreateDefaultBuilder(args)
                 .UseSerilog((hostContext, loggerConfiguration) =>
                 {
                     loggerConfiguration.ReadFrom.Configuration(hostContext.Configuration);
    
                 })
                .ConfigureWebHostDefaults(webBuilder =>
                 {
                     webBuilder.UseStartup<Startup>();
                 });

Startup.cs

 public class Startup
    {
    public void ConfigureServices(IServiceCollection services)
    {
    services.AddApplicationInsightsTelemetry(Configuration["APPINSIGHTS_CONNECTIONSTRING"]);
    services.AddApplicationInsightsTelemetry();
    }
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
    app.UseMiddleware<ExceptionMiddleware>();
    app.UseSerilogRequestLogging();
    }
    }

ExceptionMiddleware.cs

 public class ExceptionMiddleware
    {
        private readonly RequestDelegate _next;
        //private readonly ILogger _logger;
        private readonly ILogger _logger = Serilog.Log.ForContext<ExceptionMiddleware>();

        public ExceptionMiddleware(RequestDelegate next, ILogger logger)
        {
            _logger = logger;
            _next = next;
        }
        public async Task InvokeAsync(HttpContext httpContext)
        {
            try
            {
                await _next(httpContext);
            }
            catch (Exception ex)
            {

                // _logger.Error($"Something went wrong: {ex}");
                _logger.Error(ex.Message, $"Something went wrong:");
                await HandleExceptionAsync(httpContext, ex);
            }

        }
        private async Task HandleExceptionAsync(HttpContext context, Exception exception)
        {
            var user = string.Empty;

            if (context.User.Claims.Any())
                user = context.User.Claims?.FirstOrDefault(cl => cl.Type.Contains("preferred_username"))?.Value ?? "Anonymous User";
            context.Response.ContentType = "application/json";
            context.Response.StatusCode = ConfigurateExceptionTypes(exception);
            await context.Response.WriteAsync(new Models.ErrorDetails()
            {
                UserName = user,
                StatusCode = context.Response.StatusCode,
                Message = exception.Message
            }.ToString());
        }

        private static int ConfigurateExceptionTypes(Exception exception)
        {
            int httpStatusCode;

            switch (exception)
            {
                case var _ when exception is ValidationException:
                    httpStatusCode = (int)HttpStatusCode.BadRequest;
                    break;
                default:
                    httpStatusCode = (int)HttpStatusCode.InternalServerError;
                    break;
            }

            return httpStatusCode;
        }
    }

AppSettings.json

 "Serilog": {
    "Using": [],
    "MinimumLevel": {
      "Default": "Information",
      "Override": {
        "Microsoft": "Warning",
        "System": "Warning"
      }
    },
    "WriteTo": [
      {
        "Name": "Console"
      },
      {
        "Name": "ApplicationInsights",
        "Args": {
          "instrumentationKey": "",
          "restrictedToMinimumLevel": "Information",
          "telemetryConverter": "Serilog.Sinks.ApplicationInsights.Sinks.ApplicationInsights.TelemetryConverters.TraceTelemetryConverter, Serilog.Sinks.ApplicationInsights"
        }
      }
    ],
    "Enrich": [
      "FromLogContext",
      "WithMachineName",
      "WithProcessId",
      "WithThreadId"
    ]
  }

This is not logging exceptions as expected. I can see status code 500 in app insights but I want to see exception message logged as well. Can someone help me to understand what could be I am missing here. Any help would be appreciated. Thanks

Upvotes: 0

Views: 1775

Answers (2)

komluk
komluk

Reputation: 599

Just try to configure Logger in Startup.cs

var log = new LoggerConfiguration()
.WriteTo
.ApplicationInsights(serviceProvider.GetRequiredService<TelemetryConfiguration>(), TelemetryConverter.Traces)
.CreateLogger();

Whether you choose Events or Traces, if the LogEvent contains any exceptions it will always be sent as ExceptionTelemetry.

In Application Insights you can configure whether the exceptions appear as Exceptions vs Traces See here

Upvotes: 0

Rahil B
Rahil B

Reputation: 1

Try adding this values in your appsettings.json:

"Serilog":
{
    "Using":
        ["Serilog",
        "Serilog.Sinks.ApplicationInsights",
        "Serilog.Sinks.Console"],
    ...
}

Upvotes: 0

Related Questions