שוביט מחשוב



בדיקת תקלות בלתי צפויות בניטור בעזרת Powershell

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

ניתן דוגמה פשוטה, נניח שאנו רוצים לנטר קובץ "myfile.txt" . רק לקרוא אם הוא מכיל "good" או "error" (האחרון מציין כמובן שישנה תקלה שעלינו להתריע עליה). אז אנחנו משתמשים בפונקציה של PS כדלקמן, ומתריעים כאשר הקובץ מכיל "0"

Get-Item -Path c:\myfile.txt
אך מה נעשה במצב בו הקובץ פתאום חסר (מצב שלא קרה עד כה)? במצב הזה נקבל את השגיאה הבאה :

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

כספק רציני של עולם ה NET., Powershell מכיל את מנגנון ה- Try ו Catch שנועד לבודד כל מיני מצבים שהם יש פונציאל לקטיעת סקריפט. שימוש במנגנון הזה בוודאי יכול לסייע כדי לעלות על מצבים בעייתיים כאלו, אבל במאמר הזה אני רוצה להציג טכניקה קצת שונה. אם נחזור לדוגמה שהצגתי מקודם, אפשר להריץ את אותה פקודה כך :

Get-Item -Path c:\myfile.txt -ErrorAction SilentlyContinue
הסיומת שמורכבת משני המילים המילים האחרונו :
-ErrorAction SilentlyContinue
מאפשרת לסקריפט להמשיך לרוץ, גם במקרה שהקובץ לא קיים. אז אמנם הסקריפט לא יקטע באמצע, זו התקדמות אבל עדיין לא תהיה לנו אינדיקציה אמיתית למהות הבעיה.

דרך יותר טובה להגיע למצב שבו יודעים בדיוק מה הבעיה היא כך :

Get-Item -Path c:\myfile.txt -ErrorAction SilentlyContinue -ErrorVariable checkIfFileExist
אז בנוסף לתוספת הראשונה שהוספנו שראינו שמאפשרץ לסקריפט לרוץ, הוספנו עוד משהו ש"לוכד" את הבעיה בתוך משתנה. הכרזנו על ErrorVriable ולאחריו שם המשתנה שהוא - checkIfFileExist. זו התוספת החדשה כולה :
-ErrorVariable checkIfFileExist
מיד לאחר הרצת השורה אפשר לבדוק את הערך במשתנה checkIfFileExis. למשל כך
if($checkIfFileExis){#Here we can see the error}
checkIfFileExis מחזיר True במידה ונלכדה בתוכו שגיאה. זה טיפה מבלבל, אז אני מדגיש שוב - רק אם הוא True, סימן שהיתה בעיה עם הרצת הפקודה. מדוע הוא True ? משום שהוא מכיל את ה String של השגיאה עצמה. כך זה נראה אם נדפיס את הערך שלו :

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

הערה חשובה מאד - צריך לוודא לגבי כל פקודת PS (נקראות CMDLET) שהיא אכן מיישמת את המנגנון של ErrorVariable. אז במקרה של Get-Item אנחנו יודעים עכשיו שכן. אבל שימו לב מה קורה עם פקודה אחרת - InvokeWeb Request :

ביצעתי פנייה לאתר שאינו קיים בכלל (מבחינת DNS) גם מנגנון ה -ErrorAction (עם פרמטר אפשר SilentlyContinue ), וגם מנגנון ה ErrorVariable, אינם עובדים כמו שצריך עבור CMDLET הזה. מדוע לא יישמו בספריית PS הזו את המנגנונים המעולים האלו? איני יודע. ולכן מי שבוחר כן להשתמש בשיטה שהצעתי, מומלץ שיבדוק לפני זה שהיא מגיבה כמו שצריך למנגונינים האלו. בכל מקרה, אפשר תמיד לנסות את מנגנון Try ו Catch שבמקרה של Invoke-WebReques אכן עונה על הצורך של תפיסת השגיאה כמו שצריך :