Подтвердить что ты не робот

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

Я новичок в log4net, так что, надеюсь, это действительно простой вопрос для кого-то?!

У меня есть log4net, работающий с RollingLogFileAppender для моего веб-приложения. Я использую протоколирование, чтобы попытаться найти, откуда возникают некоторые проблемы с производительностью. Для этого было бы полезно включить ASPID SessionID в выход журнала, чтобы я мог убедиться, что я ищу записи журнала для конкретного пользователя.

Есть ли способ сделать это с помощью параметра conversionPattern для приложения? Есть ли параметр %property{??}, который я могу использовать?

ОБНОВЛЕНИЕ: этот вопрос до сих пор не получил ответа - у кого-нибудь есть идеи?

4b9b3361

Ответ 1

Александр Константинович почти прав. Единственная проблема заключается в том, что событие PostAcquireRequestState также встречается для статических запросов. Вызов сеанса в этой ситуации вызовет HttpException .

Следовательно, правильное решение будет:

protected void Application_PostAcquireRequestState(object sender, EventArgs e)
{
    if (Context.Handler is IRequiresSessionState)
    {
        log4net.ThreadContext.Properties["SessionId"] = Session.SessionID;
    }
}

Ответ 2

UPDATE (2014-06-12): Начиная с log4net 1.2.11 вы можете использовать %aspnet-request{ASP.NET_SessionId} в шаблоне преобразования для этой цели.

Литература: https://issues.apache.org/jira/browse/LOG4NET-87 http://logging.apache.org/log4net/release/sdk/log4net.Layout.PatternLayout.html


Вы должны создать обработчик Application_PostAcquireRequestState в Global.asax.cs(он вызывается в каждом запросе):

protected void Application_PostAcquireRequestState(object sender, EventArgs e)
{
    log4net.ThreadContext.Properties["SessionID"] = Session.SessionID;
}

И добавьте [% property {SessionID}] в conversionPattern.

Ответ 3

Кто-то исправляет меня, если я ошибаюсь, но один поток ASP.NET может обрабатывать несколько сеансов, поэтому вы не можете использовать Session_Start, поскольку он вызывается один раз при запуске сеанса. Это означает, что, как только другой пользователь получит доступ к веб-сайту, ваш журнал log4net.ThreadContext может быть перезаписан новой информацией пользователя.

Вы можете поместить указанный ниже код в Application_AcquireRequestState или создать HttpModule и сделать это в методе AcquireRequestState. AcquireRequestState вызывается, когда среда выполнения ASP.NET готова к получению состояния сеанса текущего HTTP-запроса. Если вы заинтересованы в получении имени пользователя, вы можете сделать это в AuthenticateRequest, который возникает, когда среда выполнения ASP.NET готова аутентифицировать личность пользователя (и до AcquireRequestState).

    private void AcquireRequestState(Object source, EventArgs e)
    {
        HttpApplication application = (HttpApplication)source;
        HttpContext context = application.Context;
        log4net.ThreadContext.Properties["SessionId"] = context.Session.SessionID;
     }

После этого вы можете настроить свой файл log4net.config(или в web.config) следующим образом.

<appender name="rollingFile"
      type="log4net.Appender.RollingFileAppender,log4net" >
  <param name="AppendToFile" value="false" />
  <param name="RollingStyle" value="Date" />
  <param name="DatePattern" value="yyyy.MM.dd" />
  <param name="StaticLogFileName" value="true" />

  <param name="File" value="log.txt" />
  <layout type="log4net.Layout.PatternLayout,log4net">
    <param name="ConversionPattern"
      value="%property{SessionId} %d [%t] %-5p %c - %m%n" />
  </layout>
</appender>

Надеюсь, это поможет!

Ответ 4

Я тоже искал ответ и выяснил, что %aspnet-request{ASP.NET_SessionId} отлично работает для меня.

Ответ 5

Вы можете попробовать:

<conversionPattern
    value="%date %-5level %logger ${COMPUTERNAME} [%property{SessionID}] - %message%newline" />

... в вашем Web.config и в Global.asax.cs:

protected void Session_Start(object sender, EventArgs e)
{
    log4net.ThreadContext.Properties["SessionID"] = Session.SessionID;
    log4net.Config.XmlConfigurator.Configure();
}