2008-12-12 15 views
23

Soy nuevo en log4net, así que espero que esta sea una pregunta realmente fácil para alguien ?!¿Cómo puedo incluir SessionID en archivos de registro usando log4net en ASP.NET?

Tengo log4net trabajando con RollingLogFileAppender para mi aplicación web. Estoy usando el registro para tratar de encontrar de dónde vienen algunos problemas de rendimiento. Para hacer esto, sería útil incluir el SessionID de ASP.NET en el resultado del registro para poder asegurarme de estar mirando las entradas de registro para un usuario específico.

¿Hay alguna manera de hacerlo a través de la configuración conversionPattern para el appender? ¿Hay una configuración %property{??} que pueda usar?

ACTUALIZACIÓN: Esta pregunta aún no ha sido respondida - ¿Alguien tiene alguna idea?

+0

Tengo el mismo problema: http://stackoverflow.com/questions/8985693/how-to-use-aspnet-session-pattern-layout – mynkow

+0

Tengo la respuesta a continuación. Si ayuda, vuélvela. Las personas que no entienden la situación lo han desvalorizado. http://stackoverflow.com/a/24048883/3481183 – Believe2014

+0

No debe registrar ID de sesión ya que las personas con acceso a los archivos de registro podrían secuestrar sesiones. ¡Al menos hash la ID de la sesión antes de iniciar sesión! – Kutzi

Respuesta

1

que puede probar:

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

... en su Web.config y en Global.asax.cs:

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

Hmm: parece que funciona, pero parece que la ID de sesión solo aparece para las cosas que suceden en la primera devolución de datos. Los viajes posteriores de regreso al servidor tienen SessionID = null. ¿Algún otro pensamiento? –

+0

No estoy seguro de tener miedo. Utilizamos este enfoque hace un tiempo y teníamos la sospecha de que esta configuración establecería una propiedad SessionID para _everyone_ utilizando la aplicación web en ese momento (es decir, el valor de propiedad de SessionID del usuario1 sería anulado por user2). Lo siento, no puedo ofrecer ninguna idea más real ... –

+1

No creo que esto funcione. Session_Start solo se invoca en la primera solicitud que establece una sesión. Las propiedades asignadas a ese ThreadContext morirán cuando el hilo muera. Por lo tanto, cuando llegue la siguiente solicitud, la sesión ya está establecida y no se establecerá ninguna propiedad en ThreadContext. Para que esto funcione, debe usar el evento Application_BeginRequest. –

14

ACTUALIZACIÓN (06/12/2014): A partir de log4net 1.2.11 puede usar %aspnet-request{ASP.NET_SessionId} en el patrón de conversión para este fin.

Referencias: https://issues.apache.org/jira/browse/LOG4NET-87 http://logging.apache.org/log4net/release/sdk/log4net.Layout.PatternLayout.html


Debe crear manejador Application_PostAcquireRequestState en Global.asax.cs (se le llama en cada petición):

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

Y añada [{propiedad% SessionID}] a conversionPattern.

+1

Esto fallará si la solicitud se divide en diferentes subprocesos. Una forma de que esto ocurra es si la aplicación utiliza páginas/controladores/servicios asíncronos. También parece que los servicios WCF AJAX por alguna razón cambian los hilos para la misma solicitud después de PostAcquireRequestState. – Stilgar

5

Alguien me corrige si me equivoco, pero un subproceso ASP.NET puede manejar varias sesiones, por lo que no puede usar Session_Start como se llama una vez cuando se inicia la sesión. Lo que significa es que tan pronto como un usuario diferente acceda al sitio web, su log4net.ThreadContext puede sobrescribirse con la nueva información del usuario.

Puede colocar el siguiente código en Application_AcquireRequestState, o crear un HttpModule y hacerlo en el método AcquireRequestState. Se llama a AcquireRequestState cuando el tiempo de ejecución de ASP.NET está listo para adquirir el estado de sesión de la solicitud HTTP actual. Si está interesado en obtener un nombre de usuario, puede hacerlo en AuthenticateRequest que se genera cuando el tiempo de ejecución de ASP.NET está listo para autenticar la identidad del usuario (y antes de AcquireRequestState).

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

Después de eso, puede configurar su log4net.config (o en web.config) de esta manera.

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

Hope this helps!

+0

Probé esto para una aplicación y contexto de WCF. La sesión es nula, lo que lleva a una excepción de referencia nula. – Vaccano

20

Alexander K. es casi correcto. El único problema es que el evento PostAcquireRequestState también se produce para solicitudes estáticas. Una llamada a Session en esta situación causará un HttpException.

Por lo tanto la solución correcta se convierte en:

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

IReadOnlySessionState realmente extiende IRequiresSessionState por lo que resulta que 'Context.Handler is IRequiresSessionState' es suficiente. –

+0

¿Esto no respondió a tu pregunta? –

5

que estaba buscando respuesta para esto también y descubrí que %aspnet-request{ASP.NET_SessionId} funciona bien para mí.

+0

Esto provoca una excepción en el medio de inicio de sesión en la última versión de log4net, 1.2.11.0, si no se inicia sesión cuando se registra un mensaje. Puede detectar el error al ver una línea parcialmente completa en su archivo de registro, pero sin línea nueva para separarla de otras entradas de registro. –

Cuestiones relacionadas