‫مشاهده لاگ NHibernate در Visual Studio

اگر پنجره Output را در ویژوال استودیو به هنگام Debug باز کرده و Show output from را برابر Debug قرار داده باشید می‌بینید که ویژوال استودیو خیلی از فعالیت‌های داخلی برنامه را از جمله Load اسمبلی‌ها یا Exceptionهای برنامه را مدام در آنجا فهرست می‌کند. همین کار را در مورد فعالیت‌های داخلی NHibernate هم می‌توان انجام داد.

NHibernate به طور داخلی از log4net برای log فعالیت‌های داخلی خودش استفاده می‌کند. NHibernate تقریباً تمام کارهایش را log می‌کند. به همین دلیل با دنبال کردن این logها هم می‌توان به بسیاری از اشکالات و ایرادات برنامه‌های مختلف پی برد و هم می‌توان مقدار زیادی از مکانیزم داخلی NHibernate را یاد گرفت. روال معمول برای مشاهده این log ریختن آن در یک فایل text و بررسی آن می‌باشد. اما راه ساده‌تر و موثرتری هم وجود دارد. آن هم این است که به log4net بگوییم خروجی log را به جای فایل text به پنجره Output ویژوال استودیو کپی کند.

برای انجام این کار کافی است بعد از معرفی log4net در web.config یا app.config، خطوط زیر را هم اضافه کنید:



type="log4net.Appender.TraceAppender, log4net">











بعد از انجام این کار بایستی در ابتدای شروع به کار برنامه، log4net را هم با عبارت log4net.Config.XmlConfigurator.Configure();‎ مقدار دهی (initialize) کنید.

البته غیر از این یک راه دیگر هم وجود دارد. در راه دوم یک فایل مستقل برای log4net در نظر گرفته می‌شود به اسم log4net.config. خطوط بالا در این فایل کپی شده (خط اول فایل‌های xml فراموش نشود) و سپس برای راه اندازی اولیه log4net به جای روش قبلی از XmlConfigurator.Configure(new FileInfo(“log4net.config”));‎ استفاده می‌شود.

منبع:
فصل دوم کتاب NHibernate 3.0 Cookbook

log4net: logging NHibernate and my own domain

I was used to use entlib for logging. But as I’m in favour of open source and because I am using NHibernate and Castle ActiveRecord in my applications, decided to use log4net instead. So found a good article about it, and enabled it for my application. But the problem was a very huge log file was producing because of verbose logs from NHibernate.

I’ve been heard that log4net uses hierarchical loggers but did not have a good understanding of it. I was thinking that using hierarchical loggers I can omit NHibernate’s logs and instead show my application’s logs. My bad assumption about hierarchical loggers was that they should be defined in app.config/web.config as nested. Obviously this assumption was wrong. Hierarchical logger in log4net means that you define a root and define all loggers inside it directly. Hierarchy then is understood of “name” attribute of “logger” node. This just acts a C# namespaces. For example you can have “NHibernate” and “NHibernate.SQL”. The second one is a child of the first.

Following guides in this, this, this, this and this link helped me to build my own config that works greatly in my application:

  













type="log4net.Appender.FileAppender">







value="%d [%t] %-5p %c [%x] - %m%n" />
type="log4net.Appender.FileAppender"/>







value="%d [%t] %-5p %c [%x] - %m%n" />












Confusing problem with log4net

I’m using log4net for logging in my ASP.NET application. This web site is based on .Net framework 3.5 and is installed on IIS 7.5 and Windows Server 2008 R2 in a 64 bit machine. Logging was working greatly when I was running application from Visual Studio 2010’s internal web server, but was not working at all when run from IIS.

First thing that I thought about was permission. So I grant full access to network service with the folder containing application: “c:inetpubwwwrootmyapp”. But this didn’t work and no log file generated. As I’m new to Windows Server 2008, I tried to grant full permission to all users that I knew: IUSR, local service, aspnet, IIS_IUSRS, Everyone, etc. But still nothing was working. A question in SO caused me to think this is because of trust level, so I set my application’s trust level to full. But still nothing was working. Another question in serverfault.com caused me to think the problem root is that Windows Server 2008 is using a new user for IIS. So I tried to use icacls to add ApplicationPoolIdentity to permission list. After it, I tried to change Identity of DefaultAppPool to Network Service. But none of this two solutions solved my problem.

Some people have been recommending to enabling internal logging of log4net to detect original problem. And yes, this showed me what was the problem:

log4net: XmlConfigurator: config file [C:inetpubwwwrootlog4net.config] not found. Configuration unchanged.

After some investigations, root cause was detected. It was due to incorrect use of Server.MapPath. I was forgotten to add a tilde mark in beginning of log4net.config’s path. When I used Server.MapPath as follow, all headaches have suddenly disappeared and my log file appeared and get working as I was desiring:

XmlConfigurator.Configure(new FileInfo(Server.MapPath("~/log4net.config")));

A wrong path has been causing log4net to search c:inetpubwwwroot for log4net.config not my application’s path at c:inetpubwwwrootmyapp. All this nightmare was because of my own mistake not Windows, IIS or .Net!