log گرفتن توسط کتابخانه log4net در ASP.NET

log گرفتن یکی از اجتناب ناپذیر ترین قسمت های هر برنامه توسعه داده شده توسط ما می باشد. در این مقاله با log گرفتن توسط فریم ورک log4net آشنا می شویم.

log گرفتن توسط کتابخانه log4net در ASP.NET

log گرفتن یکی از اجتناب ناپذیر ترین قسمت های هر برنامه توسعه داده شده توسط ما می باشد. هر برنامه توسعه یافته ای باید دارای یک فریم ورک log گیری مناسب باشد که توانایی log گرفتن از خطاها به صورت یک سورس(به منطور گرفتن اطلاعات بیشتر از خطاها برای اهدافی مانند دیباگ برنامه) را داشته باشد. پیغام های خطا می توانند در هر جا از برنامه ما وقوع یابند بنابراین فریم ورک های log گیری باید با دقت، برای جلوگیری از هر نوع تاثیر آنها روی برنامه، طراحی و توسعه یابند. با وجود اینکه نوشتن یک فریم ورک شخصی نیازمند تلاش زیادی است اما خوبی های خود را دارد. شرکت مایکروسافت دارای فریم وورک log گرفتن به عنوان بخشی از کتابخانه Enterprise خود می باشد. یک فریم وورک بسیار کار آمد و ساده دیگر برای log گرفتن فریم وورک log4net می باشد که منبع باز(open source) هم می باشد. در این مقاله راه و روش های استفاده از فریم وورک log گرفتن log4net در برنامه های ASP.NET آشنا می شویم.

پیش نیازها

برای یادگیری این مقاله یک سایت ASP.NET ایجاد کنید. آخرین نسخه log4net را از اینجا دانلود نمایید. سپس فایل زیپ را از حالت فشرده خارج کرده و dll را پیدا کنید. از طریق گزینه Add Reference فایل dll را اضافه نمایید. همچنین این کار را می توانید از طریق Nuget package manager انجام دهید.

قبل از اجرای واقعی بهتر است مفاهیم پایه برای استفاده بهتر از فریم وورک log4net را یاد بگبربد.

فریم وورک log4net

فریم وورک log4net شامل 3 کامپوننت اصلی می باشد : logger، appender و Layout.

logger قسمتی است که گزارش خطا را با کمک appender به مکان گزارش می برد. انواع مختلفی از appender ها برای سورس های مختلف موجود می باشند. برای مثال : log رویداد، جدول بانک اطلاعاتی، فایل متنی، ایمیل و غیره. کامپوننت Layout ساختار و فرمت دقیق پیام log که گزارش می شود را تعیین می نماید.

logger ها می توانند برای سطح های مختلف اختصاص پیدا کنند. سطح ها به ترتیب زیر دارای اولویت بندی می باشند.

1.      ALL

2.      DEBUG

3.      INFO

4.      WARN

5.      ERROR

6.      FATAL

7.      OFF

همه سطوح به غیر از ALL و OFF دارای روش گزارش log یکسان می باشند.

void Debug(object message);
void Info(object message);
void Warn(object message);
void Error(object message);
void Fatal(object message);

زمانی که logger را روی سطح اولویت ALL تنظیم می نمایید آنگاه آن همه پیام های مشخص شده توسط کد را بدون در نظر گرفتن سطوح دسترسی گزارش می دهد. همه پیام ها را در روش ها debug, info, warn, error, fatal گزارش می دهد. logger اگر روی سطح اولویت Error تنظیم شده باشد تنها پیام های مربوط به روش های Error و Fatal گزارش می شوند. به طور مشابه اگر logger روی سطح اولویت OFF قرار گیرد هیچ پیامی گزارش نمی شود. جدول زیر نحوه گزارش ها در سطوح اولویت مختلف را نمایش می دهد.

پیکربندی گزارش گیری

برای پیکربندی گزارش گیری توسط log4net در برنامه های ASP.NET شما در ابتدا نیازمند به پیکربندی یک Appender با  یک فرمت Layout و یک Logger در web.config می باشید.

به عنوان گام اول یک section با نام log4net در <configsections> درون web.config ایجاد نمایید.

  <configSections>

    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>

  </configSections>

با فرض اینکه ما نیازمند به گزارش گرفتن از استثناء ها در محل EventLog هستیم در نتیجه پیکربندی ما چنین خواهد شد :
 

<log4net>

  <appender name="EventLogAppender" type="log4net.Appender.EventLogAppender" >

      <layout type="log4net.Layout.PatternLayout">

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

      </layout>

    </appender>

 

    <root>

      <level value="ALL"/>     

      <appender-ref ref="EventLogAppender"/>

    </root>   

</log4net>

کدهای بالا خارج از المنت <system.web> پیکر بندی می شوند. تنظیمات فوق یک Logger پیش فرض که root Logger نام دارد پیکر بندی می کند که آن کلیه پیام های گزارش برخاسته از کد را ضبط می نماید. Logger پیش فرض روی سطح ALL تنظیم شود یعنی Logger کلیه پیام های برخاسته از برنامه را گزارش می دهد.

در زیر یک logger از log4net برای نشان دادن خطای تقسیم بر صفر(divide by zero) را مشاهده می نمایید.

public partial class _Default : System.Web.UI.Page

{

    private static readonly ILog log = LogManager.GetLogger(typeof(_Default));

 

    protected void Page_Load(object sender, EventArgs e)

    {

        int n1 = 10;

        int n2 = 0;

      

        double result2 = n1 / n2;

 

        Response.Write(result2.ToString());

    }

    public void Page_Error(object sender, EventArgs e)

    {      

        Exception objErr = Server.GetLastError().GetBaseException();

        log.Fatal(objErr.Message, objErr);

    }

}

با اجرای کد بالا یک استثناء (exception) را به رویداد گزارش (event log) مانند شکل زیر گزارش داده می شود.

درون کد ما می توانیم توسط متد GetLogger در کلاس LogManager یک شی Logger ایجاد نماییم. در اینجا log4net یک Logger با نام Default_ (در codebehind) در زمان صدا زدن LogManager.GetLogger ساخته می شود. نام Logger ها معمولا در پیام گزارش اضافه می شوند تا به ما در شناسایی محل وقوع استثناء کمک نماید. برای مثال Default_ در شکل بالا محل وقوع استثناء در شیء Default_ را نشان می دهد. اگر استثناء در کلاس های دیگر اتفاق بیفتد، نام کلاس به عنوان نام Logger وقوع یافته در پیام گزارش مشخص می شود که این باعث می شود که محل استثناء مشخص شود.

گزارش به صورت یک فایل فلت

پیکربندی زیر استثناء ها را به صورت یک فایل متنی گزارش می دهد.

<log4net>

  <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">

      <file value="D:\Technicals\Log4Net\Logs\example.log"/>

      <appendToFile value="true"/>

      <maximumFileSize value="100KB"/>

      <maxSizeRollBackups value="2"/>

      <layout type="log4net.Layout.PatternLayout">

        <conversionPattern value="%level %thread %logger - %message%newline"/>

      </layout>

    </appender>

 

    <root>

      <level value="ALL"/>     

      <appender-ref ref="RollingFile"/>

    </root>   

</log4net>

گزارش گیری به صورت جدول SQL Server

پیکربندی زیر استثناء ها را به صورت یک جدول SQL Server گزارش می دهد.

<log4net>

<appender name="AdoNetAppender_SqlServer" type="log4net.Appender.AdoNetAppender">

      <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />

      <connectionString value="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True" />

      <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message]) VALUES (@log_date, @thread, @log_level, @logger, @message)" />

      <parameter>

        <parameterName value="@log_date" />

        <dbType value="DateTime" />

        <layout type="log4net.Layout.PatternLayout" value="%date{yyyy'-'MM'-'dd HH':'mm':'ss'.'fff}" />

      </parameter>

      <parameter>

        <parameterName value="@thread" />

        <dbType value="String" />

        <size value="255" />

        <layout type="log4net.Layout.PatternLayout" value="%thread" />

      </parameter>

      <parameter>

        <parameterName value="@log_level" />

        <dbType value="String" />

        <size value="50" />

        <layout type="log4net.Layout.PatternLayout" value="%level" />

      </parameter>

      <parameter>

        <parameterName value="@logger" />

        <dbType value="String" />

        <size value="255" />

        <layout type="log4net.Layout.PatternLayout" value="%logger" />

      </parameter>

      <parameter>

        <parameterName value="@message" />

        <dbType value="String" />

        <size value="4000" />

        <layout type="log4net.Layout.PatternLayout" value="%message" />

      </parameter>

    </appender>

 

    <root>

      <level value="ALL"/>     

      <appender-ref ref="AdoNetAppender_SqlServer"/>

    </root>   

</log4net>

نتیجه گیری

از آنجایی که توسعه فریم وورک گزارش گیری لازمه زمان و کارهای پیچیده می باشد استفاده از یک فریم وورک تست شده که دارای قابلیت های مورد نیاز ما است می تواند بهتر باشد.