خبر خوب این است که این مورد تقریباً از قبل برای شما تصمیمگیری شده است. رخدادهای خطا با یک sampleRate جداگانه نمونهبرداری میشوند (نه tracesSampleRate) و مقدار پیشفرض آن ۱.۰ است — یعنی ثبت همه خطاها. برای اکثر قریببهاتفاق برنامهها همین پاسخ درست است و بهتر است آن را دست نزنید.
چرا خطاها بهصورت پیشفرض ۱۰۰٪ ثبت میشوند
خطاها به تعریف، کمتکرار و پرنشانه (High-signal) هستند. برخلاف Spanها که در آنها با انبوهی از نسخههای تکراری یک شکل درخواست سروکار دارید، خطا همان لحظهای است که چیزی خراب شده است. نمونهبرداری و حذف خطاها یعنی از دست دادن باگی که فقط یکی از هر هزار کاربر را درگیر میکند؛ دقیقاً همان باگی که بیش از همه سنتری برایش لازم دارید.
پس پیشفرض این است: همه خطاها را ثبت کنید. برخلاف پایش عملکرد، معمولاً حجم خطاها آنقدر نیست که مسئلهساز شود. سرویسی که آنقدر خطا تولید میکند که مجبور شوید آنها را نمونهبرداری و کاهش دهید، مشکلی بزرگتر از سهمیه سنتری خود دارد.
sentry_sdk.init(
dsn="…",
sample_rate=1.0, # خطاها؛ پیشفرض، دستنخورده بماند
traces_sample_rate=0.1, # پایش عملکرد؛ همان چیزی که تنظیم میکنید
)
این دو نرخ مستقل از هم هستند و بهراحتی با هم اشتباه گرفته میشوند. tracesSampleRate کنترلکننده Traceها و Spanهاست (پایش عملکرد) و sampleRate کنترلکننده خطاهاست. کاهش نرخ پایش عملکرد برای صرفهجویی در سهمیه، باعث از دست رفتن Crashها نمیشود؛ این مهمترین نکته این مستند است.
چه زمانی واقعاً خطاها را نمونهبرداری کنیم
چند مورد صادقانه وجود دارد که کاهش نرخ خطا به کمتر از ۱.۰ منطقی است:
- سیل شناختهشدهای که هنوز نمیتوانید رفعش کنید. یک وابستگی شخص ثالث در زمان قطعی سرویس، هزاران خطای یکسان در دقیقه تولید میکند. شما قبلاً آن را بررسی و اولویتبندی کردهاید و فقط حجمش در حال مصرف سهمیه است. در این حالت نمونهبرداری را موقتاً کاهش دهید؛ اما راهحل بهتر، یک فیلتر ورودی (Inbound Filter) یا قانون نادیدهگرفتن است که نویز را بدون دستزدن به نرخ نمونهبرداری، بهشکل تمیز حذف میکند.
- نوع خطایی که ذاتاً پرتکرار است. برخی برنامهها استثناهای «منتظره» را بهعنوان بخشی از جریان کنترل صادر میکنند. اگر نمیتوانید آنها را بازآرایی کنید، استفاده از Fingerprint بههمراه قانون نادیدهگرفتن، تمیزتر از نمونهبرداری است.
- حجم خطای واقعاً عظیمی که باگ نیست. نادر است. اگر به این نقطه رسیدید، نمونهبرداری کنید، اما آن را آخرین راهحل بدانید.
الگوی کلی این است: برای خطاها، فیلتر را به نمونهبرداری ترجیح دهید. نمونهبرداری، خطاها را بهصورت تصادفی حذف میکند؛ از جمله همان خطای نادر و مهم. اما فیلتر، خطاهای مشخصی را حذف میکند که تصمیم گرفتهاید اهمیت ندارند. فیلترها دقیقاند؛ نمونهبرداری ابزاری کلی است.
برآورد حجم خطاها
خطاها از نظر بودجهبندی مورد سادهای هستند، چون معمولاً کوچکاند:
errors/day ≈ error_rate × requests/day
اگر سرویس شما با نرخ خطای ۰.۱٪ و ۲ میلیون درخواست در روز کار کند، یعنی ۲٬۰۰۰ خطا در روز. هر رخداد خطا یک رخداد است، بهعلاوه هر پیوست، Breadcrumb و در صورت فعالبودن، یک Replay. برای اکثر تیمها این عدد در برابر بودجه پایش عملکرد ناچیز است.
یک رخداد خطا میتواند دادههای مرتبط زیادی با خود بیاورد: Breadcrumbها، یک Replay مرتبط، بدنه درخواست و پیوستها. اگر گزینه «ثبت Replay هنگام خطا» را فعال کنید، هر خطا ممکن است یک Replay هم تولید کند. همینجاست که حجم خطاها بهآرامی بالا میرود؛ نه از خود خطا، بلکه از Replayای که آن را فعال میکند.
گروهبندی است که کار را نجات میدهد
هزار کاربری که به یک خطای یکسان برخورد میکنند، هزار Issue جدا نمیسازند. سنتری آنها را در یک Issue گروهبندی میکند با شمارنده رخداد ۱٬۰۰۰. شما یک Stack Trace میخوانید، تعداد را میبینید و یکبار آن را رفع میکنید.
به همین دلیل حجم خطاها بهندرت همان مشکلی است که افراد از آن میترسند: گروهبندی، سیل رخدادها را به یک خط خوانا در فهرست Issueهای شما تبدیل میکند. شما بهازای هر رخداد هزینه (از نظر توجه) نمیدهید؛ بهازای هر Issue هزینه میدهید — موضوعی که در خواندن یک Issue به آن پرداختهایم.
خلاصه
- نرخ نمونهبرداری خطاها را روی
1.0بگذارید؛ تقریباً همیشه. - اگر حجم خطاها مسئله است، راهحل تقریباً همیشه یک فیلتر است، نه نرخ نمونهبرداری پایینتر؛ میخواهید نویز مشخص را حذف کنید، نه خطاهای تصادفی.
- خطاها را با
error_rate × requestsبودجهبندی کنید؛ معمولاً در کنار حجم Spanهای شما ناچ یزند. - مراقب Replayهای فعالشده هنگام خطا باشید که هزینه هر خطا را بالا میبرند.