Почему Serilog LogContext потерял свойства в течение жизненного цикла? - PullRequest
0 голосов
/ 29 марта 2019

В веб-приложении .NET Core MVC я интегрировал Serilog в качестве системы регистрации.В пользовательской мойке я регистрирую каждый уровень в API.Здесь мне нужны некоторые свойства, такие как имя пользователя.Потому что эти свойства не всегда доступны.Поэтому, когда открывается представление, происходит много журналов информации, и при нескольких событиях журнала свойства доступны, но они мне нужны при каждом событии журнала.

Я помещаю свойства в AsyncActionFilter, который добавляется в MvcOptions.Также попытался установить его в качестве атрибута на HomeController.В течение жизненного цикла они извлекались из LogContext.Я также использую LogContextMiddleware для передачи некоторых свойств, но, как описано ранее, я не могу разместить некоторые свойства в этом месте.

Конфигурация Serilog

 Log.Logger = new LoggerConfiguration()
            .WriteTo.PasSink(new SerLogServiceClient.SerLogServiceClient(new SerLogServiceClientOptions()))
            .Enrich.FromLogContext()
            .CreateLogger();

LogContextFilter

services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2).AddMvcOptions(mo =>
        {
            mo.Filters.Add(typeof(LogContextFilter));
        });

 public class LogContextFilterAttribute : TypeFilterAttribute
{
    /// <inheritdoc />
    public LogContextFilterAttribute() : base(typeof(LogContextFilter))
    {
    }
}

public class LogContextFilter : IAsyncActionFilter
{
    public LogContextFilter()
    {
    }

    #region Implementation of IAsyncActionFilter

    /// <inheritdoc />
    public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        LogContext.Push(
            new PropertyEnricher("UserCode",
                context.HttpContext.User.Claims.FirstOrDefault(s => s.ToString().StartsWith("UserCode"))?.Value),
            new PropertyEnricher("Test", "Will this go through?"));
        {
            await next.Invoke();
        }
    }

    #endregion
}

Serilog Sink

public void Emit(LogEvent logEvent)
    {
        var logMessage = logEvent.RenderMessage();
        //Console.WriteLine("Testing from PasSink. Whoop whoop! " + logMessage);

        try
        {
            if (logEvent.Level.ToString() == "Error")
            {
                var task = _serLogClient.Log.CreateLog(LogContent(logEvent.Properties.FirstOrDefault(p => p.Key == "UserCode").Value.AsString(),
                    logMessage, logEvent.Level.ToString(), logEvent.Properties.FirstOrDefault(p => p.Key == "TraceIdentifier").Value.AsString(), logEvent.Timestamp));

                //httpClient.PutAsync(_pasUrl, BuildJsonContent(logEvent.Properties.FirstOrDefault(p => p.Key == "UserName").Value.ToString(),
                //    logEvent.Level.ToString()));

                logContent.ttLog.Clear();
            }
        }
        catch (Exception e)
        {
            //httpClient = new HttpClient();
            logContent.ttLog.Clear();
        }
    }

Так что я хотел бы иметь все свойства во всех событиях журнала.Так что, возможно, фильтр mvc - это не то место, куда нужно перенести свойства в контекст.Но тогда что будет хорошим способом сделать это?

...