1

Hello I have issue with serilog logging exceptions to graylog. It does not log only exceptions to graylog, but everything else is logged in graylog and everything is logged in console just fine

Problem occurs on: Asp .Net core 7

I have created extension class for logging:

public static class SerilogStartupExtensions
{
private static Serilog.Core.Logger _loggerConfiguration = null;

public static IHostBuilder AddUsageSerilog(this IHostBuilder builder, IConfiguration configuration)
{
    if (_loggerConfiguration == null)
    {
        _loggerConfiguration = BuildLoggerConfiguration(configuration);
    }

    return builder.UseSerilog(_loggerConfiguration);
}

public static ILoggingBuilder AddSerilog(this ILoggingBuilder builder)
{
    return builder.AddSerilog(_loggerConfiguration);
}

public static IApplicationBuilder UseSerilogRequestLogging(this IApplicationBuilder app)
{
    return app.UseSerilogRequestLogging(options =>
    {
        //options.MessageTemplate = "[{Timestamp:HH:mm:ss} {SourceContext} [{Level}] [{RemoteIpAddress}] {Message}{NewLine}{Exception}";
        options.EnrichDiagnosticContext = (diagnosticContext, httpContext) =>
        {
            diagnosticContext.Set("RemoteIpAddress", httpContext.Connection.RemoteIpAddress);
        };
    });
}

private static Serilog.Core.Logger BuildLoggerConfiguration(IConfiguration configuration)
{
    return new LoggerConfiguration()
        .ReadFrom.Configuration(configuration)
        .Enrich.FromLogContext()
        .MinimumLevel.Is(LogEventLevel.Information)
        .MinimumLevel.Override("System", LogEventLevel.Warning)
        .MinimumLevel.Override("Microsoft", LogEventLevel.Error)
        .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning)
        .WriteTo.Console()
        .WriteTo.Graylog(new GraylogSinkOptions
        {
            HostnameOrAddress = "nice_server_ip",
            Port = 12201,
            TransportType = TransportType.Udp,
            MinimumLogEventLevel = LogEventLevel.Verbose,
            Facility = "my.facility",
            MessageGeneratorType = MessageIdGeneratorType.Timestamp,
        })
        .CreateLogger();
    }
 }

And the usage: Program.cs

builder.Host
.AddUsageSerilog(configuration)
.UseSystemd();

 builder.Logging.AddSerilog();

 builder.Services
.AddHttpLogging(logging =>
{
    logging.LoggingFields = HttpLoggingFields.All;
    logging.RequestHeaders.Add(HeaderNames.Accept);
    logging.RequestHeaders.Add(HeaderNames.ContentType);
    logging.RequestHeaders.Add(HeaderNames.ContentDisposition);
    logging.RequestHeaders.Add(HeaderNames.ContentEncoding);
    logging.RequestHeaders.Add(HeaderNames.ContentLength);

    logging.MediaTypeOptions.AddText("application/json");
    logging.MediaTypeOptions.AddText("multipart/form-data");
    logging.MediaTypeOptions.AddText("application/problem+json");

    logging.RequestBodyLogLimit = 1024;
    logging.ResponseBodyLogLimit = 1024;
})

 builder.Configuration
     .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
     .AddJsonFile($"appsettings.{enviroment}.json", optional: true, reloadOnChange: true)
     .AddEnvironmentVariables();

 app
    .UseHttpLogging()
    .UseSerilogRequestLogging();

Appsettings.json

"Serilog": {
"Using": [
  "Serilog",
  "Serilog.Sinks.Console"
],
"MinimumLevel": {
  "Default": "Information",
  "Override": {
    "Microsoft.EntityFrameworkCore": "Warning",
    "Microsoft.Hosting.Lifetime": "Information",
    "Microsoft.AspNetCore": "Warning",
    "Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware": "Information",
    "HangFire": "Warning"
  }
},
"Properties": {
  "Application": "server.good"
}
},

Attribute who logs all exceptions:

public class ApiExceptionFilterAttribute : ExceptionFilterAttribute
{
public override void OnException(ExceptionContext context)
{
    var serviceProvider = context.HttpContext.RequestServices;

    serviceProvider
        .GetRequiredService<ILogger<ApiExceptionFilterAttribute>>()
        .LogError(context.Exception, "Api action failure.");

    var problem = context.Exception switch
    {
        AccessViolationException _ => ProblemDetailsEx.CreateUnauthorizedErrorResponse(
            ErrorCode.ActionNotAllowed),
        _ => ProblemDetailsEx.CreateInternalServerErrorResponse(),
    };

    context.Result = new ObjectResult(problem)
    {
        StatusCode = problem.Status
    };
}
}

Implementation

[ApiExceptionFilter]
public abstract class ApiControllerBase : ControllerBase
{
}

Usage

public class HomeController : ApiControllerBase
{
    //controller actions
}

Who causing this issue to not log exceptions in graylog?

Update #1 After playing with .Log overload I found that if I put exception in string it does logged in gray log

    try
    {
        throw new Exception();
    }
    catch (Exception ex)
    {
        _logger.Log(LogLevel.Error, ex.ToString());
        throw;
    }
speed258
  • 65
  • 1
  • 1
  • 10
  • Can you post here the line of code where you're logging the exception? Exceptions are printed on the console even though you do not log them with logging tools like `serilog`. We cannot take that whatever is being printed on the console will go to Graylog. @speed258 – Venkatesh Dharavath Jun 09 '23 at 14:48
  • I updated post with implementation – speed258 Jun 09 '23 at 15:12
  • builder.Logging.AddSerilog() method comes from SerilogStartupExtensions, also if did then nothing would be logged into graylog, but now feels like only logging httprequest part – speed258 Jun 09 '23 at 15:49
  • It's not the problem of Graylog, it's serilog's. Try logging the exception with one of the overloads of this question. https://stackoverflow.com/q/25323607/8340027 – Venkatesh Dharavath Jun 09 '23 at 17:58

0 Answers0