2008-12-12 14 views
23

Jestem nowy w log4net, więc mam nadzieję, że to naprawdę łatwe pytanie dla kogoś ?!Jak mogę uwzględnić SessionID w plikach dziennika przy użyciu log4net w ASP.NET?

Mam log4net współpracujący z RollingLogFileAppender dla mojej aplikacji internetowej. Korzystam z rejestrowania, aby sprawdzić, skąd pochodzą problemy z wydajnością. Aby to zrobić, warto dołączyć identyfikator sesji ASP.NET w wynikach dziennika, aby upewnić się, że szukam wpisów dziennika dla określonego użytkownika.

Czy mogę to zrobić w ustawieniu conversionPattern dla aplikanta? Czy mogę użyć ustawienia %property{??}?

AKTUALIZACJA: Na to pytanie wciąż nie ma odpowiedzi - czy ktoś ma jakieś pomysły?

+0

Mam ten sam problem: http://stackoverflow.com/questions/8985693/how-to-use-aspnet-session-pattern-layout – mynkow

+0

Mam odpowiedź poniżej. Jeśli to pomoże, uproś to. Ludzie, którzy nie rozumieją tej sytuacji, go zignorowali. http://stackoverflow.com/a/24048883/3481183 – Believe2014

+0

Nie należy rejestrować identyfikatorów sesji, ponieważ osoby mające dostęp do dzienników mogą przejąć sesje. Co najmniej hash identyfikator sesji przed zalogowaniem! – Kutzi

Odpowiedz

1

Można spróbować:

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

... w Twojej web.config, aw Global.asax.cs:

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

Hmm - to wydaje się działać, ale wygląda na to, że identyfikator sesji pojawia się tylko w przypadku zdarzeń, które wystąpiły w pierwszym odświeżeniu. Kolejne wyprawy z powrotem na serwer mają SessionID = null. Jakieś inne myśli? –

+0

Nie jestem pewna, że ​​się boję. Użyliśmy tego podejścia jakiś czas temu i podejrzewaliśmy, że to ustawienie ustawi właściwość SessionID dla _everyone_ przy użyciu aplikacji sieciowej w tym czasie (tj. Wartość propozycja ID użytkownika SessionID zostanie przesłonięta przez użytkownika 2). Przepraszam, nie mogę zaoferować więcej prawdziwego wglądu ... –

+1

Nie sądzę, że to zadziała. Session_Start jest wywoływane tylko przy pierwszym żądaniu, które ustanawia sesję. Właściwości przypisane do tego ThreadContext umrą, gdy wątek umrze. Kiedy nadchodzi następne żądanie, sesja jest już ustanowiona i żadna właściwość nie zostanie ustawiona w wątku. Aby to działało, powinieneś użyć zdarzenia Application_BeginRequest. –

14

UPDATE (12.06.2014): Począwszy od log4net 1.2.11 można użyć do tego celu wzoru konwersji %aspnet-request{ASP.NET_SessionId}.

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


Należy utworzyć Application_PostAcquireRequestState obsługi w Global.asax.cs (nazywa się to w każdym życzenie):

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

I dodać [% {właściwość SessionID}] do conversionPattern.

+1

Nie powiedzie się, jeśli żądanie zostanie podzielone na różne wątki. Jednym ze sposobów, aby tak się stało, jest to, że aplikacja używa asynchronicznych stron/programów obsługi/usług. Również wydaje się, że usługi WCF AJAX z jakiegoś powodu zmieniają wątki dla tego samego żądania po PostAcquireRequestState. – Stilgar

5

Ktoś mnie koryguje, jeśli się mylę, ale jeden wątek ASP.NET może obsłużyć wiele sesji, więc nie można używać Session_Start, ponieważ jest on wywoływany raz, gdy sesja się rozpoczyna. Oznacza to, że gdy tylko inny użytkownik uzyska dostęp do strony internetowej, twój log4net.ThreadContext może zostać nadpisany przez informacje nowego użytkownika.

Możesz umieścić poniższy kod w Application_AcquireRequestState lub utworzyć moduł HttpModule i zrobić to w metodzie AcquireRequestState. Funkcja AcquireRequestState jest wywoływana, gdy środowisko wykonawcze ASP.NET jest gotowe do pobrania stanu sesji bieżącego żądania HTTP. Jeśli chcesz uzyskać nazwę użytkownika, możesz to zrobić w AuthenticateRequest, który jest wywoływany, gdy środowisko wykonawcze ASP.NET jest gotowe do uwierzytelnienia tożsamości użytkownika (i przed AcquireRequestState).

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

Po tym można skonfigurować plik log4net.config (lub w pliku web.config) w następujący sposób.

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

Mam nadzieję, że to pomoże!

+0

Próbowałem tego dla aplikacji WCF i context.Session ma wartość null, co prowadzi do wyjątku odwołania zerowego. – Vaccano

20

Alexander K. jest prawie poprawny. Jedynym problemem jest to, że zdarzenie PostAcquireRequestState występuje również w przypadku żądań statycznych. Wezwanie do sesji w tej sytuacji spowoduje HttpException.

Dlatego słuszne rozwiązanie staje się:

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

IReadOnlySessionState faktycznie rozszerza IRequiresSessionState, więc okazuje się, że 'Context.Handler jest IRequiresSessionState' jest wystarczający. –

+0

Czy to nie odpowiadało na twoje pytanie? –

5

szukałem odpowiedzi na to zbyt i okazało się, że %aspnet-request{ASP.NET_SessionId} działa dobrze dla mnie.

+0

Powoduje to wyjątek w trakcie logowania do najnowszej wersji log4net, 1.2.11.0, jeśli sesja nie została uruchomiona podczas rejestrowania wiadomości. Błąd można zauważyć, widząc częściowo kompletną linię w pliku dziennika, ale bez nowego wiersza, aby oddzielić ją od innych wpisów w dzienniku. –

Powiązane problemy