ארכיון

רשומות עם התג ‘log4net’

log4net – המדריך למלגלג (חלק 3 – למצוא viewer נורמלי)

12 דצמבר, 2009 10 תגובות

בפוסט הזה:

  • למה צריך viewer ללוג
  • קריטריונים ל viewer נורמלי
  • איזה viewerים קיימים
  • Chainsaw – ה viewer המועדף עלי (מאיפה מורידים, איך מגדירים וכו')

למה צריך Viewer ללוג

אז עשית try/catch (ואולי גם finally), וכתבת ללוג את ה exception. נפלא.
עכשיו מה?
הרי עכשיו, אם אתה יודע שיש איזו שגיאה אי שם בלוג, צריך להתחיל לבדוק מה הסיפור שלה, מה גרם לה להתרחש, מה ומה ומה.
לכל error יש סיפור מאחוריו, עלילה שלמה. בשביל זה צריך viewer – תוכנה שבעזרתה ניתן לראות את הלוג ולנסות להבין את הסיפור.

Log Viewer זו תוכנה די יבשה, שמציגה שורות על גבי שורות, כל שורה היא הודעה ללוג.
הנה כמה תמונות מסך מ viewers שונים:

log4view Kiwi Log Viewer Chainsaw

קריטריונים ל Viewer

כל viewer חייב מערת סינון (filter), כך שמתוך כל ההודעות בלוג יוצגו רק אלו שעונות לתנאי/ם מסויימ/ים.
יהיה נחמד אם ב viewer תהיה גם אפשרות "לקפוץ" להודעה הבאה שמקיימת תנאי מסויים (כמו Find או Search בעורכי טקסט)
יהיה מאוד נחמד לקבל צביעת שורות לפי תנאים מסויימים (לאו דווקא אותם תנאים של הסינון)
אז בואו נפרסם הודעת "דרושים" ל-viewer האידיאלי
לפרויקט עם log4net דרוש viewer לצפיה בלוג:
יודע לקרוא קבצי לוג, גם סגורים וגם פתוחים
יודע לתת חתכי "וגם" (and) – חובה
יודע לתת חתכי "או" (or) – חובה
יודע לתת חתכי טקסט חלקי (like) – חובה
יודע לבצע חיפוש (קפיצות) ע"פ הקריטריונים הנ"ל – יתרון
צביעת שורות על פי תנאים – יתרון
תיעוד טוב – יתרון

אז מה כבר קיים בשוק?

קודם כל, אפשר לכתוב הודעות לוג ל DB. נכון שזה חתיכת overhead לרשום הודעות לוג ל DB, אבל זה אפשרי ב live, ואפשר גם לקחת קובץ לוג, לקרוא אותו, ו"לשפוך" את ההודעות ל DB. מה זה נותן לנו? הרבה כוח לבצע חיתוכים כמה ואיך שאנחנו רוצים. כל מי שהתעסק פעם עם SQL יודע שאפשר ליצור שאילתות פשוטות בזמן קצר. ואפשר להעזר בכל designer כדי לכתוב שאילתות מורכבות יותר. גם ה SQL Management Studio שבא יחד עם MS-SQL-Server עובד יפה.
במילים פשוטות, אם רוצים, אז אפשר לבנות שאילתות מול DB ובאמצעותן לקבל כמעט את כל מה שרוצים. אמנם לא בצבעים יפים, אבל תכלס זה אפשרי ופרקטי.

כמו שסבתא שלי היתה אומרת: נו, וחוץ מזה?

או, אז באמת יש כמה דברים:

אתם מוזמנים לבדוק כל כלי בנפרד. אני בדקתי, ולמרות שמצאתי פיצ'רים חביבים פה ושם, רק Chainsaw עונה על הקריטריון הכי משמעותי מבחינתי: ביצוע חתכי "או". לדוגמה: אני מעוניין לצפות בכל הודעות הלוג שמופיעה בהן המילה "session" ו/או בהודעות הלוג שהגיעו מ class שנקרא "MailSender". כמה טריויאלי, כמה נחוץ, וכמה לא קיים כמעט בשום מקום.

שום מקום חוץ מ Chainsaw, כאמור. הפרויקט הזה, Chainsaw, הוא בכלל ב Java ולמען לוגים בפורמט של log4j. כן, כמו הרבה דברים שקשורים בדוט נט, גם כאן זה התחיל ב Java. אלא מה, הפעם אין שום מקבילה ראויה ל Chainsaw בדוט נט. כך שה look and feel אמנם קצת צולע, אבל הי, חכו תראו איזה מנוע שאילתות מגיע עם הקביים!

Chainsaw – ה Viewer המועדף עלי

הורדות והתקנות

1. הורדות: כדי להריץ את ה Chainsaw הלז צריך שיהיה לכם מותקן על המחשב JRE. וכמובן, צריך להוריד את המסור מהאתר הרשמי של Apache. אני ממליץ להוריד את גרסת ה Unix/Dos Standalone. ה Chainsaw חינמי ברשיון Apache גירסה 2.
2. הורדתם? יופי. עכשיו תתקינו. פשוט לעשות Unzip של גירסת ה Standalone לתיקיה מספיק נוחה לגישה בהארד דיסק. תסלחו לי על הנאיביות, אבל אצלי זה מותקן ב C:\chainsaw-bundle. פשוט ככה, כמו בימי DOS העליזים, כששיחקנו Doom ושאר משחיתי-נוער.
3. התקנתם? יופי, עכשיו תפעילו (פשוט תריצו את הקובץ chainsaw.bat) ומיד תקבלו ניג'וס ראשון "זאת הפעלה ראשונה שלך, בלה-בלה, לא מוגדרים receiver-ים". לא נורא, נגדיר ידנית (ראו תמונה).

ויש עוד ניג'וס כללי: החלון של ה bat – פשוט נמצא שם, מכוער במלוא תפארתו. לא חייבים להשלים עם המונומנט המכוער, אפשר להוריד Launcher ל Java ולעטוף הכל יפה יפה. אני ממליץ על jsmooth (עוד על זה בפוסט נפרד).

הגדרות ב log4net

זה נחמד שמותקן ה Chainsaw, אבל לא מספיק. כמו שציינתי, במקור ה Chainsaw מגיע מעולם ה Java, וזה אומר שהוא מצפה לקרוא את ההודעות בפורמט של log4j. אז כדי שה log4net יוציא הודעות כאלו, צריך לשנות קצת את ההגדרות. אם נתייחס לדוגמה מהפוסט הקודם, אז נשנה את קובץ ה config באופן הבא:

<log4net>
  <appender name="WowItsTheLog4jFileAppender" type="log4net.Appender.FileAppender">
    <file value="mylog.txt" />
    <appendToFile value="true" />
    <layout type="log4net.Layout.XmlLayoutSchemaLog4j" >
      <locationInfo value="true" />
    </layout>
  </appender>

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

לפני שנחזור ל Chainsaw, נכתוב תוכנית קטנה ש"עובדת קשה" ונותנת הודעות ללוג מכל מיני classים ובת'רדים שונים, כולל exceptions ייזומים. בקיצור, תוכנית שעושה שמח. אני לא ארשום כאן את הקוד של התוכנית, כי זה לא מה שמעניין. מה שמעניין זה איך התוכנית כותבת ללוג ואיך משתמשים ב Chainsaw כדי לצפות בהודעות שמתקבלות. בכל מקרה, התוכנית מצורפת כולל כל ה source.

עובדים עם Chainsaw – למנסרים הידד

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

כדי לבצע שאילתות על ההודעות המוצגות, צריך להשתמש בתחביר של מנוע השאילתות של Chainsaw, ולהקליד באזור של Refine focus on. נטעם קצת ע"י דוגמאות:

MSG ~= ’email' מציג רק את ההודעות שמכילות את המילה email
MSG ~= ’email' && LOGGER ~= 'sender' רק הודעות שמכילות את המילה email ששם הלוגר שלהן מכיל את המילה sender
MSG ~= 'go' || MSG ~= 'before' מציג הודעות שמכילות את המילה go ו/או הודעות שמכילות את המילה before
( LOGGER == 'mylogger' && MSG ~= 'cat' ) || ( THREAD == 1234 ) מציג הודעותשהגיעו מת'רד מספר 1234 ו/או הודעות שמכילות את המילה cat שהגיעו מלוגר שנקרא mylogger
PROP.log4jid >= 400 מציג את כל ההודעות החל משורה 400
LEVEL >= 'warn' מציג רק הודעות מסוג Warn או גבוה ממנו (למשל Error יוצג, אבל Info לא יוצג)

שימו לב שיש רווח לפני ואחרי פתח/סגור סוגריים וכן לפני/אחרי אופרטורים וכד'. בקיצור, צריך רווחים, וה Chainsaw לא סולח ולא שוכח. אם משהו בתחביר השאילתה לא תקין, ה Chainsaw פשוט מתעלם ממנה, ולא מציג שום הודעת שגיאה. כזה הוא, לא משהו ביחס למשתמשים. שיהיה.

קבלת הודעות ב UDP

ב Chainsaw, כמו גם ב viewerים אחרים, יש אפשרות של קבלת הודעות לוג באמצעות תקשורת TCP וכן UDP. כלומר, כמו שה log4net כותב הודעות לוג לקובץ, הוא יכול לשלוח אותם בפרוטוקול TCP או UDP לאן שנרצה. וככה אפשר לצפות בהודעות תוך כדי ריצה של כמה תוכנות במקביל. כשעובדים בסביבה מבוזרת זה פיצ'ר מאוד חזק. אגב, ב UDP לא ניתן לשלוח הודעות לוג ארוכות. מה לעשות, ככה זה.

אז איך?

1. בכל תוכנה רלוונטית, מגדירים ב log4net שליחת הודעות לוג ב UDP:

<appender name="HeyLetsGoWithUdp" type="log4net.Appender.UdpAppender">
  <remoteAddress value="localhost" />
  <remotePort value="48899" />
  <layout type="log4net.Layout.XmlLayoutSchemaLog4j" >
    <locationInfo value="true" />
  </layout>
</appender>

2. מגדירים receiver ב Chainsaw שיאזין להודעות ב UDP באותו פורט שהגדרנו קודם. התמונות הבאות מסבירות את זה:

מוסיפים ומגדירים

זהו.

ועוד כמה דברים על ה Chainsaw

הסקירה כאן היא רק ברמה של היכרות, ויש עוד כמה דברים חביבים ב Chainsaw הפרחח:

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

ניתן לבצע Find

אפשר למיין את ההודעות (המיון הדיפולטי הוא סדר ההודעות כפי שנרשמו ללוג או כפי שהתקבלו ע"י ה Chainsaw, וזה לא בהכרח ה Timestamp שלהן)

הגדרות – מציע לכם לשנות בהגדרות שה Cyclic buffer size יהיה, נניח, 50000. ובאותו מקום אפשר גם להסיר את הסימון מ Confirm Exit.

ה Chainsaw יכול להיתקע בגלל מחסור בזכרון. כדי להתגבר על זה, רצוי להגדיר בקובץ bat הקצאת זיכרון גדולה יותר. פשוט להוסיף את הטקסט -Xms32m -Xmx1024m אחרי ה java. כך שהתוצאה היא

java -Xms32m -Xmx1024m -Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger -classpath jakarta-oro-2.0.6.jar;jmdns.jar;log4j-1.3alpha-7.jar;log4j-chainsaw-2.0alpha-1.jar;log4j-optional-1.3alpha-7.jar;log4j-oro-1.3alpha-7.jar;log4j-smtp-1.3alpha-7.jar;log4j-xml-1.3alpha-7.jar;log4j-zeroconf.jar;xstream-1.1.2.jar org.apache.log4j.chainsaw.LogUI

סיכום

זהו, עד כאן לענייני Chainsaw ו log4net. יש, כמובן, כלים נוספים, ויש תשתיות לוג כאלו ואחרות (יש למשל את SmartInspect – אני לא מת על הקונספט שלהם, כי זה להכניס business logic לתוך תשתית הלוג, אבל שווה בדיקה). אני לא מתיימר לקבוע ש log4net טובה יותר מתשתיות אחרות. אבל אני כן חושב ש log4net היא תשתית מצויינת ללוג, עושה את העבודה בצורה טובה, מאפשרת הגדרות מתקדמות כמו סינונים, ומאפשרת הרחבות. בנוסף לכל, log4net היא open source, וזה אומר שגם אם יש באג, אפשר בקלות להכנס לקוד ולראות מה קורה גם בפנים. כדי לצפות בתוצרי הלוג אני משתמש ב Chainsaw, שהוא כלי מצוין לחתכים ולשאילתות, אבל מצריך קצת סבלנות בעבודה.

אם יש להשיג viewer טוב יותר ל log4net – תנו לי פינג.

ועד אז, לגלוג נעים!

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

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.

לגלגו ותהנו 🙂

פרויקט דוגמה

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