2008-12-12 4 views
23

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

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

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

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

+0

У меня такая же проблема: http://stackoverflow.com/questions/8985693/how-to-use-aspnet-session-pattern-layout – mynkow 2012-05-28 11:29:46

+0

У меня есть ответ ниже. Если это поможет, пожалуйста, поддержите его. Люди, которые не понимают ситуацию, ее нивелируют. http://stackoverflow.com/a/24048883/3481183 – Believe2014 2014-06-05 03:51:04

+0

Вам не следует регистрировать идентификаторы сеансов, так как люди, имеющие доступ к лог-файлам, могут захватывать сеансы. По крайней мере, hash идентификатор сеанса, прежде чем регистрировать его! – Kutzi 2015-11-27 16:25:15

ответ

1

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

<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(); 
} 
+0

Хм - похоже, это работает, но похоже, что идентификатор сеанса появляется только для вещей, которые происходят в первой обратной передаче. Последующие поездки обратно на сервер имеют SessionID = null. Любые другие мысли? – 2008-12-12 12:10:04

+0

Не уверен, что я боюсь. Мы использовали этот подход некоторое время назад и подозревали, что этот параметр установит свойство SessionID для _everyone_, используя веб-приложение в это время (то есть значение userID для SessionID будет переопределено пользователем2). Извините, я не могу предложить больше реальной информации ... – 2008-12-12 14:43:36

+1

Я не думаю, что это сработает. Session_Start вызывается только при первом запросе, который устанавливает сеанс. Свойства, назначенные этому ThreadContext, будут умирать, когда поток погибнет. Поэтому, когда приходит следующий запрос, сеанс уже установлен, и в ThreadContext не будет установлено свойство. Для этого вам следует использовать событие Application_BeginRequest. – 2009-05-17 20:19:49

14

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; 
} 

И добавить [% свойство { SessionID}] на conversionPattern.

5

Кто-то исправляет меня, если я ошибаюсь, но один поток 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> 

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

20

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

Поэтому правильное решение становится:

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

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

Смежные вопросы