ארכיון

ארכיון של אוקטובר, 2009

log4net – המדריך למלגלג (חלק 2 – הגדרות וקוד)

28 אוקטובר, 2009 אין תגובות

הרעיון של הפוסט הזה הוא פשוט: מעין cookbook שמסביר איך להתחיל עם log4net מההתחלה, מתוך הנחה שכבר יש לכם Visual Studio 2005 ומעלה (או כל IDE אחר לפיתוח בדוט נט בגירסה 2.0 ומעלה)

אז מה יהיה לנו:

  • הורדה של log4net
  • דוגמה פשוטה של כתיבה ללוג באמצעות log4net ע"י שמירה לקובץ טקסט
  • כתיבה של exception
  • ומה עוד?

מת-חי-לים!

הורדה והתקנה של log4net

דבר ראשון – ההורדה של log4net – כדי להוריד את גירסה 1.2.10 אפשר פשוט ללחוץ כאן. לפרטים נוספים – כאן תמצאו את דף ההורדות של log4net ב Apache.

הורדתם? יופי. עכשיו לעשות unzip לתיקיה חביבה (שתשרת אתכם די הרבה). נניח C:\oss\log4net.

תוכנית ראשונה עם log4net

נמשיך:

ניצור פרוייקט פשוט ב VS, נניח Console Application, ונכתוב בו את ה hello world המפורסם:

static void Main(string[] args)
{
  Console.WriteLine("Hello world");
  Console.ReadLine();
}

עכשיו נכניס פנימה שירותי logging ע"י log4net:

1. נוסיף רפרנס ל log4net תוך שימוש בתיקיה ההיא, לנתיב bin\net\2.0\release\log4net.dll

2. כדי להגדיר את log4net דרך קובץ חיצוני (ולא דרך קוד):

א. נוסיף קובץ app.config (מה שנקרא "Application Configuration File")

ב. נערוך את ה app.config באופן הבא:

<configuration>
    <configSections>
        <section name="log4net" type="System.Configuration.IgnoreSectionHandler"/>
    </configSections>

    <log4net>

        <appender name="OhMyGodItsTheFileAppender" type="log4net.Appender.FileAppender">
            <file value="mylog.txt" />
            <appendToFile value="true" />
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] – %message%newline" />
            </layout>
        </appender>

        <root>
            <level value="DEBUG" />
            <appender-ref ref="OhMyGodItsTheFileAppender" />
        </root>
    </log4net>
</configuration>

3. כדי ש log4net יתחיל לעבוד ויצא מתרדמת החורף שלו, צריך איזה טריגר שיעיר אותו. אפשר לעשות את זה דרך הקוד, ואפשר בצורה קצת יותר שקופה, ע"י שימוש בקובץ די ביישן בשם AssemblyInfo.cs. זה קובץ שנמצא מתחת ל Properties. שם צריך להוסיף את השורה הבאה (אחרי כל ה using שיש שם, במיקום כלשהו):

[assembly: log4net.Config.XmlConfigurator(Watch = true)]

4. עכשיו, כדי לכתוב ללוג, אנחנו צריכים להשתמש באיזה אובייקט שיתן לנו את שירותי ה logging. את זה עושים, למשל, ע"י הוספת שדה סטטי ל class שלנו (ולכל class שבו נצטרך logging):

א. להוסיף בחלק של ה using את שני הבחורים הבאים (אם אינם):

using System.Reflection;
using log4net;

ב. להוסיף את השדה הסטטי עצמו:

private static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

זהו, עכשיו אפשר להשתמש ב logger שלנו. הפעולות 1-3 הנ"ל הן פעולות חד פעמיות לפרויקט שלנו. פעולה מספר 4 חוזרת על עצמה בכל class בפרויקט. הנה קצת תוספות לקוד:

static void Main(string[] args)
{
  Logger.Debug("starting up");
  Console.WriteLine("Hello world");
  Logger.Debug("done");
  Console.ReadLine();
}

נריץ את הפרויקט. ונראה את ה hello world הידוע לשמצה. ואיפה כל ההודעות שרשמנו ללוג? הן נמצאות בתוך הקובץ mylog.txt, שנמצא במיקום של ה exe של הפרוייקט שלנו: בד"כ בנתיב bin\debug או bin\release. אפשר לשנות את שם הקובץ mylog.txt לכל שם אחר. ויש עוד הרבה הגדרות, לא לדאוג…

בשלב זה יש לנו תוכנית עם logger, שמבצעת כתיבות ללוג, שלמעשה נשמרות לקובץ. זה הבסיס ל-log4net. זה המתכון, אם תרצו, להוספת log4net לפרוייקט שלכם בצורה יחסית פשוטה ופורטבילית.

כתיבת exception ללוג

לכתוב exception ללוג זה לא סיפור גדול: זה כמעט אותו הדבר כמו כתיבה רגילה, רק משתמשים בחתימה שכוללת אובייקט מסוג Exception. מן הסתם, זה יהיה בתוך try/catch. הנה דוגמה קטנה:

static void Main(string[] args)
{
  Logger.Debug("starting up");
  string fileName = "file-does-not-exist.txt";
  try
  {
    string contents = System.IO.File.ReadAllText(fileName);
  }            
  catch (Exception ex)
  {
    Logger.Error("cannot read contents of file " + fileName, ex);
    Console.WriteLine("oops, an error occured. see log for details");
  }

  Logger.Debug("done");
  Console.ReadLine();
}

מומלץ מאוד להשתמש במתודות עם חתימת ה Exception, כי ה exception נשמר קצת אחרת, וזה מאפשר לבצע חתכים אחרים ולתצוגה שונה דרך ה viewer (בפוסט הבא).

לאן ממשיכים מכאן

אפשר לכתוב ל-EventLog. שימו לב שזה דורש הרשאות גבוהות יחסית.

אפשר לכתוב ל-Trace ולעקוב אחריו עם כלים חיצוניים כמו DebugView של SysInternals. זה שקול ל-System.Diagnostics.Trace.WriteLine

ואפשר עוד הרבה דברים, כמו לכתוב ל DB, לכתוב ל TCP, ל UDP, לשלוח מייל ועוד. גשו לדף הדוגמאות ב Apache ותהנו.

אגב, לפי ההגדרות שבפוסט הזה, אפשר לשנות בזמן ריצה את ההגדרות של ה log4net – וההתנהגות של ה logging תשתנה בהתאם. מאגניביישן.

לסיכום, זה פוסט שכל המטרה שלו היא לתת מתכון פשוט לשימוש ב log4net. בפוסט הבא נראה איך אפשר לנתח את הלוגים, ע"י viewer כמו Chainsaw.

לגלגו ותהנו 🙂

פרויקט דוגמה

קטגוריות:תכנות תגיות:

log4net – המדריך למלגלג (חלק 1 – מבוא)

23 אוקטובר, 2009 אין תגובות

בפוסט הזה:

  • מבוא
  • למה בכלל לכתוב ללוג?
  • סוגי הודעות לפי רמות חוּמרה
  • מה כותבים ללוג

מבוא

חלק בלתי נפרד מאפליקציה רצינית הוא הלוג – שירות שמאפשר כתיבת הודעות.
בזמן שהאפליקציה חיה ונושמת היא יכולה לכתוב הודעות שונות ללוג. ההודעות יכולות להיות בסגנון "עכשיו מתבצע כך וכך" או "יש כאן שגיאה לא צפויה".
הלוג עצמו יכול להישמר כקובץ, או קבצים, או כרשומות ב DB.
או שהלוג יכול לא להישמר כלל, אלא רק סוג של Console.WriteLine או Debug.WriteLine או Trace.WriteLine.
או שהלוג שולח את ההודעות באמצעות TCP או UDP למקום אחר.
או שהלוג שולח מייל למישהו…
בקיצור, יש את העניין של לכתוב ללוג ("יש כאן שגיאה לא צפויה"), ויש את העניין של מה תהיה התוצאה של הכתיבה ללוג (ההודעות נשמרות/מוצגות וכד').
בנוסף לכל זה, גם אם כתבנו ללוג והכל טוב ויפה, נרצה אח"כ גם לצפות בתוצאה, ולעשות חיתוכים שונים. במילים אחרות, נרצה איזה Viewer – תוכנה נורמלית עם UI חביב שתאפשר לנו את התצוגה והחיתוכים.
אה, ועוד משהו. נרצה גם לוג מספיק חכם כך שאם נרצה לשנות את ההגדרות שלו לא נצטרך להוריד את האפליקציה ולטעון אותה מחדש.

אז מה היה לנו: הודעות ללוג ואיך הן "נכתבות", תוכנת viewer, טעינה חכמה אחרי שינוי ההגדרות.
כל זה ניתן למימוש בקלות עם log4net – תשתית מוכחת ועובדת ללוג, שהיא open source. אבל לפני הכל, עוד קצת מבוא.

למה בכלל לכתוב ללוג?

שאלה טובה.

לא חייבים.

אבל הנסיון שלי מראה שכתיבה מושכלת ללוג מאפשרת למפתחים להבין באגים (ולפתור אותם) מהר יותר, בהשפעה אפסית על הביצועים.

בנוסף, קהל היעד של הלוג הוא לא רק מפתחים. גם אנשי IT או אנשים שמתחזקים את האפליקציה יכולים להעזר בו.

בשורה התחתונה, כתיבה ללוג היא גם כדי לוודא שהאפליקציה עובדת כמצופה וגם כדי לתעד מצבים לא תקינים ואת אפשרויות הטיפול בהם.

סוגי הודעות לפי רמות חוּמרה

רגע לפני שמתחילים, כמה מילים על ההודעות השונות שאנחנו מכניסים ללוג.

ב log4net, ולא רק שם, ההודעות ללוג מתחלקות לסוגים הבאים:

  • Debug
  • Info
  • Warn
  • Error
  • Fatal

נרחיב קצת…

הודעות Debug (ורק הן) מיועדות למפתחים עצמם, ואפשר להשתולל איתן כמה שרוצים. כפי שנראה מאוחר יותר, אפשר לשנות את ההגדרות כך ש log4net יתעלם מהן לחלוטין. בד"כ כותבים ל Debug הודעות כמו "עכשיו לפני פתיחת חיבור ל DB" ו"התחברתי בהצלחה ל DB" וכו'. בקיצור, אבני דרך למפתחים עצמם.

הודעות Info מכילות מידע מתומצת על המצב של האפליקציה, שהוא בחזקת "טוב לדעת". לדוגמה, כמעט כל service (או console שמדמה service) שכתבתי בדוט נט קורא את הקונפיגורציה ומיד אח"כ כותב הודעת info ללוג בנוסח "שירות xyz עלה בהצלחה עם ההגדרות הבאות: …".

הודעות Warn מתייחסות למקרים שבהם האפליקציה נתקלה ב exception או במצב לא תקין, אבל היא יודעת להתאושש ממנו. למשל, המערכת שלנו לא מצליחה להוציא מייל כרגע. לא נורא, היא תנסה שוב עוד דקה.

הודעות Error מתייחסות למקרים שבהם האפליקציה נתקלת ב exception או במצב לא תקין והיא לא יודעת להתאושש ממנו. זה יכול להשפיע רק על המשתמש הנוכחי (נניח אם זו אפליקציית web) וזה יכול להיות משהו יותר תשתיתי.

הודעות Fatal מתייחסות למקרי קצה שבהן האפליקציה שלנו לא יכולה להתאושש ממשהו לא תקין וכדאי שמישהו יסדר את זה בהקדם האפשרי. כלומר יש כאן גם הנחיה לגבי ניתוח הלוג וטיפול בשגיאות. הודעות Fatal צריכות להיות בודדות כדי לא ליצור מצב של "זאב-זאב".

מה כותבים ללוג

אם אתם לוקחים אתכם משהו מהפוסט הזה – קחו את זה: לא רק כותבים ללוג "היתה כאן שגיאה" ומצרפים את האובייקט של ה exception. כותבים את כל הקונטקסט הרלוונטי כדי שאח"כ נוכל להבין טוב יותר מה קרה. למשל "לא הצלחתי לקרוא את התוכן של הקובץ X כאשר הבקשה היתה Y" בצירוף ה exception. כן, זה לוקח עוד דקה, אבל זה כל כך שווה את זה.

אלא שלפעמים, מטעמי security או privacy לא כדאי לכתוב ממש הכל. למשל, "לא הצלחתי להתחבר ל SQL Server שנמצא בכתובת X עם שם משתמש U וסיסמה P" נשמע לי רעיון לא טוב, כי זה חושף את פרטי ההתחברות ל DB כולל הסיסמה. אפשר אולי במקום לכתוב את הסיסמה לכתוב את ה hash שלה לפי הדוט נט (GetHashCode), או לפי סטנדרט חזק יותר כמו MD5, כאשר כותבים את ערך ה hash ב base64 (וגם אז, אפשר לכתוב רק את N התוים הראשונים מטעמי חסכון ונוחות קריאה).

זהו, עד כאן המבוא. בפוסטים הבאים – איך משתמשים ב log4net כדי לכתוב ללוג, איזה viewer-ים קיימים ועוד.

קטגוריות:תכנות תגיות:
Quantcast