2012-03-14 23 views
9

ASP.NET web sitemizin günlük iletilerini günlüğe kaydetmek için log4net kullanıyorum ve son zamanlarda hatanın oluştuğu sayfa/işleyici hakkında bilgi eklemek istedim. Ben Global.asax aşağıdaki satırı ekleyin nedenle karar:Bir ASP.NET isteğine özgü log4net içerik özelliği nasıl ayarlanır?

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

ve benzeri akıllıca benim dönüşüm modeline %property{page} eklendi:

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

Bu tek istekleri için iyi çalıştı. Ancak, günlüklerimde sayfa özelliğinin bir ASP.NET isteği sırasında değişebileceğini farkettim. Bir ASHX işleyicisine giriş yaptım ve işlemenin ortasında sayfa özelliği, bir ASPX sayfasına işaret eden farklı bir değere dönüşecektir. ASP.NET'e gelen başka bir istek olduğunu ve BeginRequest'un çalıştırıldığını ve log4net.ThreadContext'daki statik sayfa özelliğinin başka bir değere değiştirildiğini belirttim.

Şimdi, istek başına sayfa özelliğini korumak istiyorum; böylece, oturum açma sayfası yolunu sürekli olarak günlüğe kaydedebilirim. Bir cevap bulmaya çalıştım ama hiçbir şeyle çıkmadım. Bu sorunu çözmek için önerilen yol nedir? Eminim bu, web sunucusu olay günlüğünün çok temel bir işlevselliğidir.

cevap

20

Tüm sayfa isteğinin aynı iş parçacığında işleneceğini ASP.NET does not guarantee'dan beri, yanıtı HttpContext.Current as log4net processes günlüğe kaydetme olayından almayı tercih ediyorum.

aşağıdaki GetCurrentPage sınıf log4net kılavuzu ToString yöntemini geçersiz kılarak bir "Active Property Value" adlandırdığı uygular:

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

Kayıt Log4net en GlobalContext Global.asax en Application_Start bu sınıf.

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

log4net mevcut istekte değerini arama olacaktır bizim GetCurrentPage sınıfının ToString yöntemini çağıracak hattının %property{page} bölümünü yazar.

+2

Bu bir dahidir. –

2

Bu makalede özetlenen Application_BeginRequest yerine Application_PostAcquireRequestState kullanmayı denediniz mi? How can I include SessionID in log files using log4net in ASP.NET?

Biz yöntem adı ile her sınıfta bizim logger beri tomrukçulukla sayfa eklemek için gereğini hissettim

:

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

ve böyle bir dönüşüm modeli vardır:

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

Sonuç olarak, sınıf isminin log çıktılarını görüyoruz. Bu, aynı zamanda, günlük sınıfının kendisinde miras aldığı bir taban sınıfına karşı, sayfa sınıfının kendisinde olup olmadığını ayırt etmenizi sağlar. Çözümünüz, kod temel sınıfta çalışırken bile sayfa adını gösterme avantajına sahip olacaktır. Kurulumumuzu {page} eklemeye bakacağımızı düşünüyorum.

+0

İlginçtir bu işleri fazla ayrıntı bulun. BeginRequest eşzamansız olarak yürütülür, ancak Application_PostAcquireRequestState bir sayfa isteğinin başlangıcında işlenir, sonra tüm diğer sayfa olayları eşzamanlı olarak tetiklenir ve ilk sayfa bitene kadar başka bir sayfa isteği beklemelidir. –

+0

@CraigA 'Yeni' operatörün 'özel statik yeni readonly log4net.ILog' kod satırınızda gerekli olduğunu sanmıyorum. SO, "Düzenlemeler en az 6 karakter olmalı" diyor :). –

0

Özellik değerini ASP'de depolayın.NET bağlam HttpContext.Current.Items.Add("yourProperty", value) Bu log4net düzeninden satışa sunulacak:

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

here.