הטמעת מעקב שגיאות מרוכז (Sentry/Rollbar) ב-DevOps

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

היכולות שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1359
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1330
  • עיצוב לוגו לחברת B2B Advance
    עיצוב לוגו לחברת B2B Advance
    776
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1077
  • פיתוח לוגו חברת AIDER
    פיתוח לוגו חברת AIDER
    1022
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1113

Error tracking ב-DevOps: היכן אובדות שגיאות בפרודקשן

כשמעבד התשלומים נופל בפרודקשן, הלקוח הוא הראשון לדעת על כך, ולא התורן: הוא רואה את השגיאה בממשק וכותב לתמיכה. איסוף שגיאות מהפרודקשן אינו מחובר לקונטור השחרורים — האפליקציה כותבת את ה-stack לקובץ מקומי, מופעלת מחדש, וההקשר של החריגה אובד יחד עם התהליך.

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

קושי נפרד הוא אי-ההתאמה בין הסביבות. בסביבת ה-staging החריגה באפליקציה משוחזרת עם נתונים אחרים, בלי הנפחים האמיתיים ובלי מצב האינטגרציות החיצוניות. פגם שבפרודקשן חוזר באופן יציב «לא נתפס» בקונטור הבדיקות, והזמן הולך על השוואת סביבות במקום על תיקון.

error tracking מרכזי פותר זאת אחרת: חריגות נשלחות למאגר אחד ישירות מהפרודקשן, מקובצות לפי סוג ומיקום בקוד, ומתויגות לפי release, סביבה והסשן של המשתמש. כלי ברמה של Sentry מוסיף ל-stack תמונת הקשר — פרמטרי הבקשה, ה-release, מזהה הטרנזקציה — ומקשר את התקלה לפריסה מסוימת.

אז ניתוח האירוע מתנהל לפי כרטיס אחד: באיזה release זה הופיע, כמה משתמשים נפגעו, האם התדירות עולה אחרי ה-deploy האחרון. לפי הסימנים האלה מחליטים על rollback או תיקון דחוף לפני שהספירה תגיע למאות פניות. להלן — כיצד לבנות קונטור כזה.

מה נותן איסוף שגיאות מרכזי: אפקטים מדידים

איסוף שגיאות מרכזי סוגר את הנקודה העיוורת המרכזית: תקלה בפרודקשן ממשיכה להתקיים עד לתלונה הראשונה, ולא עד לאירוע הראשון במערכת הניטור. במקום שורות אינסופיות של לוגים והתכתבויות בצ'אט מופיעה נקודת איסוף שגיאות אחת, שבה לכל קריסה יש שירות, סביבה, release ו-stack של קריאות.

מהירות הגילוי וניתוח האירועים

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

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

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

כשכל השירותים והסביבות שולחים נתונים לאותו מאגר, השוואה של תקלות בין releases וקונטורים הופכת לפעולה של כמה דקות. נראה לעין שקונטור הבדיקות קורס לעתים קרובות יותר מהפרודקשן — רגרסיה נתפסת לפני ה-deploy ולא לפי פנייה של לקוח.

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

אפשרויות פריסה: ענן, קונטור עצמי, תוכנית היברידית

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

אפשרות מתי מתאימה מגבלות
איסוף שגיאות בענן אין דרישות לאחסון מקומי, נדרשים התחלה מהירה והתראות מוכנות האירועים יוצאים מחוץ לפרימטר; יש למסך שדות רגישים בצד האפליקציה
פריסה בקונטור עצמי דרישות רגולטוריות, פרימטר סגור, נתונים אישיים ב-traces התפעול עלינו: מסד האירועים, שמירת נתונים (retention), עדכונים, גיבויים, תורנות
תוכנית היברידית אגרגטים ומטריקות ניתן להוציא החוצה, ואילו אירועים גולמיים חייבים להישאר בפנים שני קונטורים מסונכרנים, ניתוב אירועים והפרדת הרשאות מורכבים יותר
מודול מובנה של פלטפורמת ניטור כבר קיים סטאק של לוגים ומטריקות, נדרש מינימום רכיבים חדשים קיבוץ שגיאות חוזרות וניתוח לפי release חלשים יותר

קריטריונים לבחירה

אנחנו בוחנים ארבעה דברים: נפח האירועים ומשך שמירת הנתונים על שגיאות, עומק הבידוד של הקונטור, הצורך לקשר שגיאה ל-release ול-commit, וכן מי תורן על האיסוף והניתוח.

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

שלבי ההטמעה: מהאודיט ועד מסירה לתחזוקה

סדר השלבים חשוב יותר מהמהירות: אם מפעילים את האיסוף לפני האודיט, חלק מהתקלות יישאר בלתי נראה — גם הלוגים הנוכחיים לא מציגים אותן. לכן קודם מתארים את מה שכבר נצפה, ורק אחר כך מרחיבים את הכיסוי.

הכנה ותרשים זרימת השגיאות

  1. אודיט של הניטור הנוכחי. מנתחים אילו תקלות נתפסות כיום — חריגות בשרת, קריסות בלקוחות, כשלים של משימות רקע — והיכן הנתונים קטועים או לא נאספים בכלל.
  2. תרשים זרימת השגיאות. עוקבים אחרי מסלול האירוע מהשירות ועד המאגר ומסמנים את הקטעים שבהם הוא אובד בעת תקלת רשת או הפעלה מחדש של התהליך.
  3. הגדרת האיסוף. מחברים את כל הקונטורים, מגדירים כללי קיבוץ כדי שתקלה אחת לא תתפרק למאות רשומות, ומגבילים את קצב השליחה — הזרם לא אמור להעמיס על המאגר.
  4. העשרה בנתוני build וסביבה. מקשרים את האירוע ל-build ולקונטור מסוימים: השגיאה מקושרת מיד לשינויים, במקום לחפש אותה ידנית בלוגים.

קבלה: כיצד מאמתים שהנתונים אינם אובדים

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

תוצרים בסיום: קונפיגורציות, תרשימים, נהלים

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

  • קונפיגורציות איסוף: הגדרות של ספריות הלקוח ושל קליטת האירועים בשרת — רמות הלוג, כללי קיבוץ של תקלות דומות, ספי סינון רעש.
  • תרשים זרימת השגיאות: מסלול האירוע מהתקלה בשירות ועד הכרטיס בפאנל — היכן הוא מועשר בהקשר, היכן נשמר, כמה זמן נשמר.
  • כללי הפרדה בין סביבות: פרויקטים ומפתחות נפרדים לפיתוח, לבדיקות ולקונטור הפרודקשן — רעש הבדיקות לא נכנס לפיד הייצור.
  • מדיניות גישה לנתונים: תפקידי הצוותים, מי רואה דוחות עם נתונים אישיים, וכיצד מוגדר מיסוך של שדות רגישים.
  • נוהל ניתוח אירועים: מי מקבל התראה ובאיזה פרק זמן, כיצד נרשמת הסיבה ולפי איזה סימן שגיאה נחשבת סגורה.
  • הוראות לחיבור שירותים חדשים: סדר שלב-אחר-שלב עם תבניות קונפיגורציה מוכנות וצ'ק-ליסט לאימות שהאירועים מגיעים.

כיצד בנויה התיעוד הנמסר

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

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

מקרה בוחן: כיצד קיצרנו את זמן הגילוי של תקלה

הלקוח — מוצר שמבוסס על כמה שירותים ואפליקציה לנייד. את התקלות בפרודקשן מצאו המשתמשים: האות הגיע במכתב לתמיכה או בביקורת בחנות האפליקציות, ומשם הגיע לתורן. הטמענו איסוף שגיאות מרכזי על Rollbar עם קישור האירועים ל-release, לסביבה ולרכיב.

מה היה לפני ההטמעה

זמן הגילוי של תקלה נמדד בשעות ותלוי בכך שמתי המשתמש יחליט לכתוב: חלק מהקריסות לא התגלו בכלל. קריסות חוזרות חיו שבועות — אותה תקלה הגיעה בניסוחים שונים ונרשמה בידי אנשים שונים. שיעור השגיאות שנותחו עמד על כשליש, השאר נסגר כ«לא משוחזר», והעומס על התמיכה גדל יחד עם מספר הפניות.

מה השתנה אחרי

האירועים מקובצים ל-traces לפי ה-stack של הקריאות ומתויגים בתגיות של סביבה, release ושירות — לכל שגיאה יש בעלים. התורן מקבל אות לערוץ בדקות הראשונות, לפני הפניות הראשונות לתמיכה.

קיבוץ נפרד לפי release מראה איזה deploy הוסיף את התקלה, ומאפשר לבצע rollback לפני שהזרם של התלונות גדל.

מדדים לפני ואחרי:

  • הזמן מהקריסה ועד האות — משעות ל-2-3 דקות;
  • שיעור השגיאות עם בעלים ברור — משליש ל-9 מתוך 10;
  • פניות חוזרות על תקלות שכבר ידועות הצטמצמו פי שלושה;
  • קריסות חוזרות הפסיקו לחזור: לכל אחת יש כלל סגירה.

במה error tracking מרכזי שונה מתיעוד לוגים

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

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

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

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

ערך נפרד הוא הקישור בין השגיאה ל-release. האירוע מתויג בגרסת ה-build ובנקודה בהיסטוריית השינויים, ולכן בעיה חדשה מופרדת מידועה, והרגרסיה נראית מיד אחרי ה-deploy. זה נותן תשובה מהירה: לבצע rollback או לתקן קדימה, ואיזה קטע קוד בדיוק נפגע.

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

ספקות טכניים לפני ההתחלה: שאלות נפוצות

לפני ההתחלה הצוות הטכני בודק לא «האם המערכת עובדת», אלא כיצד היא תתנהג בכשלים, בשיאי עומס וברגרסיות. להלן — תשובות לשאלות שעולות לרוב בתהליך התיאום: מאי-זמינות של הקולט ועד הפרדת הרשאות.

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

מה יקרה אם הקולט החיצוני אינו זמין?

שליחת האירועים מתבצעת באופן אסינכרוני ואינה חוסמת את עיבוד הבקשות. האירועים נשמרים בבאפר מקומי ונשלחים לאחר שהחיבור מתחדש; כשהבאפר מתמלא נזרקים הוותיקים ביותר ולא החדשים. המשתמשים באותו זמן לא מבחינים בדבר.

איזה נפח נתונים יוצא החוצה?

רק ה-stack של הקריאות, הקשר הבקשה וגרסת ה-build — בלי תוכן של מסדי נתונים ובלי נתונים אישיים. הזרם מוגבל בשיעור דגימה ובמסננים, ולכן הנפח שלו צפוי מראש ואינו גדל יחד עם התעבורה.

כיצד לסנן רעש וכפילויות?

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

האם אפשר לעבוד בקונטור סגור?

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

כיצד להפריד את הגישה של צוותים לנתוני השגיאות?

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

נדון במשימה ונחזור עם תוכנית הטמעה

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

  • הרכב השירותים והסביבות: אילו אפליקציות, משימות רקע ולקוחות ניידים צריכים להיכנס למערכת, כמה סביבות ואילו מהן שולחות אירועים.
  • דרישות למיקום הנתונים: האם מותר לשלוח דוחות לשירות חיצוני או שנדרש קונטור בתוך הפרימטר, וכיצד אנחנו ממסכים שדות רגישים ב-stack traces.
  • תפקידי הצוותים: מי הבעלים של הפרויקט, מי מנתח התראות, כיצד מחלקים הרשאות ומגדירים מיון אירועים לפי אחראים.
  • נוהל ההתראות: אילו תקלות נחשבות קריטיות, לאן שולחים את האות — צ'אט, דואר, תורן — ואיזה סף, כדי שההתראות לא יהפכו לרעש שמפסיקים לקרוא.
  • קריטריוני מוכנות: איזה שיעור של מסלולים מכוסה במעקב, אילו סוגי שגיאות נתפסים, וכיצד מאמתים שאירוע הגיע וקובץ נכון.
  • פורמט המסירה: תיעוד הקונפיגורציה, תרשים זרימת האירועים, הוראות לתורנים — מה שיאפשר לצוות לעבוד עם המערכת בלעדינו.
  • הרשאות: כיצד מוציאים מפתחות, היכן מאחסנים סודות, וכיצד מבטלים גישה כשמשתנה הרכב הצוות.

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