Как установить свойство контекста log4net для запроса ASP.NET? - PullRequest
9 голосов
/ 14 марта 2012

Я использую log4net для регистрации сообщений журнала нашего веб-сайта ASP.NET, и в последнее время я хотел добавить информацию о странице / обработчике, где произошла ошибка. Поэтому я решил добавить следующую строку в Global.asax:

void Application_BeginRequest(object sender, EventArgs e)
{
    log4net.ThreadContext.Properties["page"] = HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath;
}

и, соответственно, я добавил %property{page} в свой шаблон преобразования:

<conversionPattern value="%newline%date %-5level %property{page} - %message%newline%newline%newline" />

Это работало нормально для единичных запросов. Но затем я заметил в своих журналах, что свойство страницы может измениться во время запроса ASP.NET. У меня есть вход в один обработчик ASHX, и в процессе его обработки свойство страницы будет меняться на другое значение, которое указывает на страницу ASPX. Я пришел к выводу, что в ASP.NET поступает еще один запрос, и выполняется BeginRequest, а свойство статической страницы в log4net.ThreadContext изменяется на другое значение.

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

Ответы [ 3 ]

20 голосов
/ 20 марта 2012

Поскольку ASP.NET не гарантирует , что весь запрос страницы будет обработан в одном потоке, я предпочитаю получать ответ от HttpContext.Current , так как log4net обрабатывает событие регистрации .

Следующий класс GetCurrentPage реализует то, что руководство log4net называет «Значение активного свойства» , переопределяя его ToString метод:

public class GetCurrentPage
{
  public override string ToString()
  {
      if (null != HttpContext.Current)
      {
          return HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath;
      }
      return string.Empty; // or "[No Page]" if you prefer
  }
}

Зарегистрируйте этот класс в Application_Start Global.asax в GlobalContext log4net.

protected void Application_Start(object sender, EventArgs e)
{
    XmlConfigurator.Configure();
    GlobalContext.Properties["page"] = new GetCurrentPage();
}

Когда log4net записывает часть строки %property{page}, он вызывает метод ToString нашего класса GetCurrentPage, который будет искать значение в текущем запросе.

2 голосов
/ 14 марта 2012

Вы пытались использовать Application_PostAcquireRequestState вместо Application_BeginRequest, как описано в этой статье? Как я могу включить SessionID в файлы журналов, используя log4net в ASP.NET?

Мы никогда не чувствовали необходимости добавлять страницу в журнал, так как мы создаем наш регистратор в каждом классе симя метода:

private static new readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

и имеет шаблон преобразования, подобный этому:

<conversionPattern value="%date %P{user} %P{addr} [%property{SessionID}] %level %logger - %message%newline" />

Таким образом, мы в конечном итоге видим имя класса в выводе журнала.Это также позволяет вам различать, происходило ли ведение журнала в самом файле класса страницы, по сравнению с базовым классом, от которого он наследуется.Ваше решение будет иметь преимущество в показе имени страницы, даже когда код выполняется в базовом классе.Я думаю, что мы посмотрим на добавление {page} в нашу настройку.

0 голосов
/ 14 февраля 2018

Сохранить значение свойства в контексте ASP.NET HttpContext.Current.Items.Add("yourProperty", value) Будет доступно из макета log4net:

<layout type="log4net.Layout.PatternLayout">
   <conversionPattern value="%aspnet-context{yourProperty}" />
</layout>

Подробнее см. здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...