→ buildbench

הודעה ב-DLQ בלי שום לוג

שאלתי את עצמי בבוקר שאלה תמימה: יש לי משהו ב-DLQ? התשובה הייתה כן — שתי הודעות ב-email-alerts-dlq, אותו digest של אותו משתמש, יום אחרי יום. הרפלקס המיידי היה ללכת ל-CloudWatch Logs, לחפש את ה-source_id של הליסטינג, ולקרוא את ה-stack trace.

לא היה stack trace. לא היה כלום.

הציפייה ששגתה

המודל המנטלי שלי על DLQ היה פשוט מדי: הודעה נכנסת ל-DLQ כי ה-handler קרס. אם ה-handler קרס, יש exception. אם יש exception, יש שורה ב-CloudWatch עם logger.exception("Failed to process email SQS record") שכתבתי בידיים שלי בקוד.

חיפשתי את השורה הזו לפי תאריך, לפי RequestId, לפי source_id של הליסטינג. כלום. ואז התחלתי לחשוב שאולי ה-Sentry בולע את הלוג, או שה-LOG_LEVEL גבוה מדי, או שה-logger לא מתחבר ל-CloudWatch בכלל.

כל אחת מההיפותזות האלה הייתה שגויה — אבל הן כולן הסיחו אותי מהשאלה הנכונה.

המספר שפתר את הכל

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

=== Lambda Invocations ===
2026-05-04  0
2026-05-05  0

=== SQS NumberOfMessagesReceived ===
2026-05-04  3
2026-05-05  3

ה-SQS poller משך את ההודעה שלוש פעמים ביום (maxReceiveCount=3, ואז drop ל-DLQ). אבל ה-Lambda לא הופעל אפילו פעם אחת. אין לוג כי לא היה מה ללוג. הקוד שלי מעולם לא רץ.

זה לא בעיית logging. זו בעיית delivery בין ה-Event Source Mapping לבין ה-Lambda — איפשהו בין SQS שמודיע “יש הודעה” לבין הקוד שלי שאמור לקבל אותה, משהו נופל בשקט. Errors=0, Throttles=0, LastProcessingResult=None.

המסקנה

כשמסתכלים על DLQ, השאלה הראשונה לא צריכה להיות “מה הקוד שלי עשה לא נכון”. היא צריכה להיות:

כמה פעמים ה-Lambda רץ באותם תאריכים, וכמה פעמים ה-SQS קיבל את ההודעה?

אם המספרים שווים — יש exception, חפש אותו. אם Invocations < Received — הקוד שלך לא רלוונטי בכלל, הבעיה ב-poller, ב-permissions של ה-ESM, או ב-init של ה-Lambda שנופל לפני ה-handler.

חיפשתי שעתיים את הלוג שלא היה קיים, כי המודל המנטלי שלי הניח שאם הודעה הגיעה ל-DLQ — אז הקוד שלי רץ ונכשל. הוא לא רץ.

הפעם הבאה שאני רואה DLQ מלא, אני פותח קודם את גרף ה-Invocations.