پرش به محتویات

مشاهده‌پذیری و کارایی

هر Feature پیش از انتشار باید از روی Log، Metric و Trace قابل عیب‌یابی باشد. بهینه‌سازی فقط با اندازه‌گیری انجام می‌شود و Telemetry نباید Secret، PII یا Cardinality کنترل‌نشده ایجاد کند.

سه ستون Telemetry

سیگنال استاندارد کاربرد
Log log/slog با JSON رخداد قابل جست‌وجو و Context عملیاتی
Metric OpenTelemetry/Prometheus نرخ، خطا، زمان و Saturation
Trace OpenTelemetry و W3C Trace Context مسیر درخواست میان API، DB، Worker و Provider

Trace و Metric در OpenTelemetry Go پایدارند. Log با slog تولید و در صورت نیاز با Trace ID مرتبط می‌شود؛ استفاده از API آزمایشی Log در OpenTelemetry نباید Core کد را قفل کند.

Log ساخت‌یافته

  • فیلد پایه شامل timestamp، level، service، version، environment، request_id، trace_id و event است.
  • Error یک error_code پایدار و در صورت امن بودن Chain خلاصه دارد؛ Stack فقط در Error داخلی و محیط کنترل‌شده ثبت می‌شود.
  • شماره موبایل، Token، OTP، Cookie، متن Ticket، Query Parameter حساس، URL امضاشده و payload Provider Redact می‌شوند.
  • Log موفق هر Request در بار بالا Sample می‌شود، اما Error، Audit و رخداد امنیتی بدون از دست‌رفتن نگهداری می‌شوند.
  • Levelها معنا دارند: debug برای Development، info برای تغییر عادی وضعیت، warn برای اختلال قابل تحمل و error برای شکست نیازمند اقدام.
  • Health Check موفق Log نمی‌شود تا Noise ایجاد نکند.

Metric

برای API از RED و برای Resource از USE استفاده می‌شود:

  • Rate، Error و Duration درخواست HTTP بر اساس Route Template و Status Class
  • Utilization، Saturation و Error برای CPU، Memory، Disk، Network و Connection Pool
  • Query Duration، Pool Wait، Transaction Rollback و Slow Query
  • Queue Depth، Oldest Job Age، Retry، Dead Letter و Handler Duration
  • Login Success/Failure، OTP Send/Verify و Refresh Reuse بدون Label موبایل یا Account
  • Provider Duration، Error Class و Rate Limit بر اساس نام Provider و Operation محدود
  • Object Upload/Download، Rejection و Scan Duration

Label شامل user_id، building_id، request_id، Object Key یا Error Text ممنوع است. Route به Template مانند /buildings/{id} تبدیل می‌شود. Cardinality هر Metric پیش از Merge بررسی می‌شود.

Trace

  • ورودی HTTP Trace Context معتبر را می‌پذیرد و Correlation داخلی جدید در صورت نبود آن می‌سازد.
  • Span برای Use Case، Query مهم، Job و تماس Provider ساخته می‌شود؛ Functionهای کوچک Span جدا نمی‌گیرند.
  • Attributeها Allowlist دارند و PII یا Payload کامل ثبت نمی‌شود.
  • Sampling در Head برای حالت عادی و نگهداری بیشتر Error/Latency در Collector تنظیم می‌شود.
  • Propagation به Provider فقط وقتی قرارداد و ریسک افشای Header روشن باشد انجام می‌شود.

Health و آمادگی

  • /livez فقط زنده‌بودن Process را نشان می‌دهد و Dependency بیرونی را Check نمی‌کند.
  • /readyz آمادگی پذیرش Traffic و Dependencyهای ضروری مانند PostgreSQL را با Timeout کوتاه بررسی می‌کند.
  • /startupz در صورت نیاز شروع طولانی را از Liveness جدا می‌کند.
  • پاسخ Health بدون نسخه Secret، DSN، Topology یا جزئیات خطای داخلی است.
  • شکست SMS، Push یا Object Storage لزوما API را Unready نمی‌کند؛ مسیر Durable باید Backlog و Alert ایجاد کند.

SLO و بودجه خطا

شاخص هدف اولیه Production
Availability API 99.9 درصد ماهانه برای درخواست‌های واجد SLI
p95 خواندن حداکثر 200ms Server-side
p95 نوشتن حداکثر 400ms Server-side
Error Rate داخلی کمتر از 0.5 درصد درخواست‌های واجد SLI
Age صف OTP در p95 کمتر از 5 ثانیه پیش از تماس Provider
RPO حداکثر 5 دقیقه
RTO حداکثر 60 دقیقه

این هدف‌ها پس از Load Test و انتخاب Topology نهایی تصویب می‌شوند. یک VPS Single Point of Failure است و ممکن است Availability یا RTO را تامین نکند؛ داشبورد باید فاصله واقعی با هدف را نشان دهد، نه اینکه عدد را تضمین‌شده فرض کند.

Error Budget برای اولویت‌دادن Reliability به Feature استفاده می‌شود. سوختن سریع Budget، Deploy خودکار Development را متوقف و برای Production Release Gate ایجاد می‌کند.

Alert

  • Alert باید Symptom قابل اقدام را هدف بگیرد، نه هر Metric غیرعادی را.
  • Alert دارای Severity، مالک، Dashboard و Runbook است.
  • Multi-window Burn Rate برای SLO و Threshold پایدار برای ظرفیت استفاده می‌شود.
  • نبود Telemetry، توقف Backup، رشد Queue، Refresh Reuse، افزایش Cross-tenant Deny و Disk کم Alert مستقل دارند.
  • Alert بدون اقدام مشخص حذف یا اصلاح می‌شود تا Alert Fatigue ایجاد نکند.

Profiling و Optimization

  • Profile و Benchmark فقط در محیط کنترل‌شده و با داده غیرحساس اجرا می‌شوند.
  • Endpointهای pprof عمومی نیستند و پشت شبکه یا Authentication عملیاتی قرار می‌گیرند.
  • ترتیب کارایی: اندازه‌گیری، یافتن Bottleneck، تغییر کوچک، مقایسه و ثبت نتیجه است.
  • ابتدا Query، تعداد Round Trip، Serialization و Allocationهای پرتکرار بررسی می‌شوند.
  • Cache فقط با مالکیت، TTL، Invalidation و Consistency مشخص اضافه می‌شود؛ Redis در نسخه اول پیش‌فرض نیست.
  • sync.Pool، Query پیچیده، Denormalization و Goroutine بیشتر بدون Profile و Benchmark ممنوع‌اند.
  • Standard Library یا حذف Dependency به‌تنهایی ادعای Performance نیست؛ اثر تغییر Router، Middleware یا Allocation فقط با Benchmark و Load Test همان Workload پذیرفته می‌شود.
  • مسیر موفق HTTP برای تشخیص 404/405 نباید Response Body را Buffer یا فهرست Routeها را Scan کند؛ کار اضافه تشخیص Method فقط در مسیر Unmatched مجاز است.

Capacity

  • Headroom هدف برای CPU، Memory، Disk، Connection و Queue در بار معمول حداقل 30 درصد است.
  • Disk PostgreSQL، WAL و Object Cache جداگانه پایش و Forecast می‌شوند.
  • Load Test ظرفیت هر Replica و Database را پیش از تغییر Traffic تعیین می‌کند.
  • Limit Container کمتر از نیاز واقعی و بیشتر از ظرفیت Host تنظیم نمی‌شود؛ OOM و CPU Throttling Metric دارند.
  • افزایش Replica نباید مجموع Connection Pool را از ظرفیت Database عبور دهد.

معیار پذیرش

  • داشبورد API، PostgreSQL، Worker، Provider و Host پیش از Release وجود دارد.
  • هر Alert بحرانی Runbook و مالک دارد.
  • هیچ Label یا Log حاوی PII و Secret نیست.
  • Load Test بودجه p95 و ظرفیت Headroom را با Artifact قابل تکرار اثبات می‌کند.
  • Restore Metric و Queue Age از ابتدا قابل مشاهده‌اند.

منابع رسمی