۱۳۸۸/۰۳/۰۸

معرفي ELMAH


عموما كاربران نمي‌توانند گزارش خطاي خوبي را ارائه بدهند و البته انتظاري هم از آنان نيست. تنها گزارشي كه از يك كاربر دريافت مي‌كنيد اين است: "برنامه كار نمي‌كنه!" و همين!
روش‌هاي متعددي براي لاگ كردن خطاهاي يك برنامه ASP.Net موجود است؛ چه خودتان آن‌ها را توسعه دهيد و يا از ASP.NET health monitoring استفاده كنيد.
روش ديگري كه اين روزها در وبلاگ‌هاي متعددي در مورد آن مطلب منتشر مي‌شود، استفاده از ELMAH است. (البته ELMAH به تازگي منتشر نشده ولي تا كيفيت محصولي به عموم ثابت شود مدتي زمان مي‌برد)

ELMAH يك ماژول رايگان و سورس باز لاگ كردن خطاهاي مديريت نشده برنامه‌هاي ASP.Net‌ است. براي استفاده از اين ماژول نيازي نيست تا تغييري در برنامه خود ايجاد كنيد يا حتي آن‌را كامپايل مجدد نمائيد. يك فايل dll‌ دارد به همراه كمي تغيير در web.config برنامه جهت معرفي آن و اين تمام كاري است كه براي برپايي آن لازم است صورت گيرد. اين ماژول تمامي خطاهاي مديريت نشده‌ي برنامه شما را لاگ كرده (در حافظه سرور، در يك فايل xml ، در يك ديتابيس اس كيوال سرور يا اوراكل ، در يك ديتابيس اكسس و يا در يك ديتابيس اس كيوال لايت) و براي مرور آن‌ها يك صفحه‌ي وب سفارشي يا فيدي مخصوص را نيز در اختيار شما قرار مي‌دهد. همچنين اين قابليت را هم دارد كه به محض بروز خطايي يك ايميل را نيز به شما ارسال نمايد.

با توجه به اين‌كه اين ماژول در Google code قرار گرفته احتمالا دسترسي به آن مشكل خواهد بود. سورس و فايل‌هاي كامپايل شده آن‌را از آدرس‌هاي زير نيز مي‌توان دريافت نمود:
( + و + و +)

نحوه استفاده از ELMAH :

براي استفاده از ELMAH دو كار را بايد انجام دهيد:
الف) كپي كردن فايل Elmah.dll در پوشه bin برنامه
ب) تنظيم وب كانفيگ برنامه

بهترين مرجع براي آشنايي با نحوه بكار گيري اين ماژول، مراجعه به فايل web.config موجود در پوشه samples آن است. بر اساس اين فايل نمونه:

- ابتدا بايد configSections آن را به وب كانفيگ خود اضافه كنيد.

- سپس تگ elmah بايد اضافه شود. در اين تگ موارد زير مشخص مي‌شوند:
الف) آيا خطاها توسط آدرس elmah.axd توسط كاربران راه دور قابل مشاهده شود يا خير.
ب) خطاها كجا ذخيره شوند؟ موارد زير پشتيباني مي‌شوند:
ديتابيس‌هاي اس كيوال سرور ، اوراكل ، حافظه سرور، فايل‌هاي xml ، ديتابيس SQLite ، ديتابيس اكسس و يا ديتابيسي از نوع VistaDB
ج) آيا خطاها ايميل هم بشوند؟ اگر بلي، تگ مربوطه را تنظيم كنيد.
د) آيا خطاها به اكانت twitter شما نيز ارسال شوند؟

- در ادامه تگ مربوط به معرفي اين httpModules بايد تنظيم شود.

- سپس httpHandlers ايي به نام elmah.axd كه جهت مرور خطاها مي‌توان از آن استفاده نمود معرفي مي‌گردد.

- از IIS7 استفاده مي‌كنيد؟ قسمت system.webServer را نيز بايد اضافه نمائيد.

- و در آخر نحوه‌ي دسترسي به elmah.axd مشخص مي‌شود. اگر اجازه دسترسي از راه دور را داده باشيد، به اين طريق مي‌شود دسترسي را فقط به كاربران مجاز و تعيين اعتبار شده، اعطاء كرد و يا به نقشي مشخص مانند ادمين و غيره.

براي نمونه، اگر بخواهيد از ديتابيس SQLite جهت ذخيره سازي خطاهاي حاصل شده استفاده نمائيد و نيز از ارسال ايميل صرفنظر كنيد، وب كانفيگ برنامه شما بايد به شكل زير تغيير يابد:
<?xml version="1.0"?>

<configuration>
<configSections>
<sectionGroup name="elmah">
<section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah"/>
<section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
<section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" />
<section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah"/>
<section name="errorTweet" requirePermission="false" type="Elmah.ErrorTweetSectionHandler, Elmah"/>
</sectionGroup>
</configSections>

<elmah>
<security allowRemoteAccess="1" />
<errorLog type="Elmah.SQLiteErrorLog, Elmah" connectionStringName="cn1" />
</elmah>


<appSettings/>

<connectionStrings>
<add name="cn1" connectionString="data source=~/ErrorsLog/Errors.db" />
</connectionStrings>

<system.web>
<httpModules>
<add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah"/>
</httpModules>

<httpHandlers>
<add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
</httpHandlers>

<compilation debug="true"/>

<authentication mode="Windows" />
</system.web>

</configuration>
در اينجا يك پوشه جديد به نام ErrorsLog را بايد به ريشه سايت خود اضافه كنيد (يا هر نام دلخواه ديگري كه در قسمت connectionStrings بايد تنظيم شود). فايل Errors.db به صورت خودكار ايجاد خواهد شد. بديهي است كاربر ASP.net بايد دسترسي write بر روي اين پوشه داشته باشد تا عمليات ثبت خطاها با موفقيت صورت گيرد. همچنين فايل System.Data.SQLite.DLL نيز بايد در پوشه bin برنامه شما كپي شود.
ساده‌ترين تنظيم اين ماژول استفاده از حالت xml است كه به ازاي هر خطا يك فايل xml را توليد كرده و نياز به اسمبلي ديگري بجز ماژول مربوطه نخواهد داشت.

تذكر:
از لحاظ امنيتي مثال فوق توصيه نمي‌شود زيرا allowRemoteAccess آن 1 است و قسمت authorization ذكر نشده است. اين مثال فقط جهت راه اندازي و آزمايش اوليه ارائه گرديده است. (همچنين بهتر است اين نام پيش فرض را به نامي ديگر مثلا myloggermdl.axd تغيير داده و در قسمت httpHandlers تنظيم نمائيد. سپس اين نام را به تگ location نيز اضافه كنيد)

اكنون براي مشاهده خروجي اين ماژول به انتهاي آدرس سايت خود، elmah.axd را اضافه كرده و سپس enter كنيد:



همانطور كه در تصوير مشخص است، تمامي خطاهاي لاگ شده گزارش داده شده‌اند. همچنين دو نوع فيد به همراه امكان دريافت خطاها به صورت CSV نيز موجود است. با كليك بر روي لينك details ، صفحه‌ي بسيار ارزنده‌اي ارائه مي‌شود كه تقريبا نحوه‌ي وقوع ماجرا را بازسازي مي‌كند.
نكته‌ي مهمي كه در صفحه‌ي جزئيات ارائه مي‌شود (علاوه بر stack trace‌ و مشخصات كاربر)، مقادير تمامي فيلدهاي يك صفحه هنگام بروز خطا است (قسمت Raw/Source data in XML or in JSON در اين صفحه) :



به اين صورت ديگر نيازي نيست از كاربر بپرسيد چه چيزي را وارد كرده بوديد كه خطا حاصل شد. دقيقا مقادير فيلدهاي همان صفحه‌ي زمان بروز خطا نيز براي شما لاگ مي‌گردد.


نكته:
ماژول SQLite ايي كه به همراه مجموعه ELMAH ارائه مي‌شود 32 بيتي كامپايل شده (64 بيتي آن نيز موجود است كه بايد از آن در صورت لزوم استفاده شود). بنابراين براي اينكه در يك سرور 64 بيتي به مشكل برنخوريد و خطاي BadImageFormat را دريافت نكنيد نياز است تا به اين نكته دقت داشت.

براي مطالعه بيشتر:

Error Logging Modules And Handlers
Sending ELMAH Errors Via GMail
Exception-Driven Development
Using HTTP Modules and Handlers to Create Pluggable ASP.NET Components