Properties added to LogContext are gone when logging in Middleware

561 views Asked by At

In my application I use serilog to log to DB with some custom columns.

      {
        "Name": "MSSqlServer",
        "Args": {
          "connectionString": "ApplicationDbContext",
          "tableName": "Logs",
          "autoCreateSqlTable": false,
          "columnOptionsSection": {
            "batchPostingLimit": 10,
            "period": "0.00:00:02",
            "additionalColumns": [
              //custom cols
            ],
            "timeStamp": {
              "columnName": "TimeStamp",
              "convertToUtc": true
            },
            "level": {
              "columnName": "Level",
              "storeAsEnum": true
            }
          }
        }
      }
    ],
    "Enrich": [ "FromLogContext" ]

I add the custom properties to the log context in my controllers (I can't add these informations in the middleware because I need some data/logic from the controllers).

[HttpPost("dosomething")]
        public IActionResult Compile(string catalog)
        {
            Serilog.Context.LogContext.PushProperty(Log.OPERATION_NAME_KEY, Convert.ToInt16(OperationTypes.DoSomething));
            //do something
            return Ok();
        }

In addition I use a middleware to log exceptions

public async Task InvokeAsync(HttpContext httpContext)
        {
            try
            {
                await _next(httpContext);
            }
            catch (NotFoundException ex) when (LogExeception(ex))
            {
                await HandleNotFoundExceptionAsync(httpContext, ex);
            }
            catch (Exception ex) when (LogExeception(ex))
            {
                await HandleExceptionAsync(httpContext, ex);
            }
        }

but when I log from the middleware all the properties added to the LogContext are gone (while the logs from main program contains all the needed properties). I tried the "when trick" as suggested here but nothing has changed.

How can I solve this problem?

1

There are 1 answers

0
Stephen Cleary On

Unfortunately, the "when trick" does not work with asynchronous code.

Instead, the only reliable solution I've found is to handle the event that's raised when an exception is thrown, capture the logging contexts at that time, attach them to the exception object, and then extract them in your logger. It's rather awkward, but it works.

I've written a general-purpose ILogger solution; there's also a Serilog-specific solution that is easier to use.