TGViewer
C# Geeks (.NET) C# Geeks (.NET) @csharpgeeks · 550 subscribers
Post #732 248
🔍 وقتی یک تراکنش وسط مسیر Fail می‌شود، واقعاً از کجا شروع به Debug می‌کنید؟
فرض کنید یک کاربر روی دکمه پرداخت کلیک می‌کند. چند ثانیه بعد...
❌ پرداخت ناموفق می‌شود.
حالا سؤال اینجاست:
مشکل دقیقاً کجا رخ داده است؟
آیا API Gateway درخواست را دریافت نکرده؟
آیا Validation در Command Handler شکست خورده؟
آیا داده داخل Database ذخیره نشده؟
آیا Outbox پردازش نشده؟
آیا پیام وارد RabbitMQ نشده؟
یا Consumer پیام را دریافت کرده ولی پردازش آن Fail شده؟
اگر هر سرویس فقط لاگ خودش را داشته باشد...
عملاً وارد یک کابوس خواهید شد.
😵 سناریوی رایج

فرض کنید سیستم شما از این بخش‌ها تشکیل شده است:
Client
│
▼
API Gateway (Ocelot)
│
▼
Payment Service
│
▼
Command Handler
│
▼
Database + Outbox
│
▼
Background Job
│
▼
RabbitMQ
│
▼
Notification Service

حالا برای پیدا کردن علت خطا باید:
🔹 لاگ Gateway را باز کنید.
🔹 بعد لاگ Payment Service را بررسی کنید.
🔹 بعد لاگ Background Service را.
🔹 بعد لاگ RabbitMQ Consumer را.
🔹 بعد لاگ Notification Service را.
هر کدام روی یک Instance جدا... با Timestampهای مختلف... و فقط امیدوار باشید که ساعت همه سرورها Sync باشد.

📌راه‌حل؟
ءCentralized Logging + Correlation ID + OpenTelemetry
🎯 تجربه واقعی در Hub پرداخت Dr. Link
در هاب پرداخت Dr. Link تعداد زیادی سرویس مستقل وجود دارد.
پرداخت فقط یک درخواست HTTP نیست.
بعد از ثبت درخواست، چندین اتفاق پشت سر هم رخ می‌دهد:
✅ ذخیره اطلاعات
✅ اجرای Business Ruleها
✅ ثبت Domain Event
✅ ذخیره در Outbox
✅ ءPublish شدن پیام توسط MassTransit
✅ پردازش توسط سرویس‌های دیگر
اگر Correlation نداشته باشیم...
ردیابی مسیر تقریباً غیرممکن می‌شود.
🆔 همه چیز از Correlation ID شروع می‌شود
به محض اینکه درخواست وارد Ocelot API Gateway می‌شود...
یک Correlation ID تولید می‌شود.
مثلاً:
a17d59d8-78d2-4b1f-bd89-40d3f52b44f3

این شناسه همراه درخواست به تمام سرویس‌ها ارسال می‌شود.
X-Correlation-Id:
a17d59d8-78d2-4b1f-bd89-40d3f52b44f3

از این لحظه...
تمام لاگ‌های مربوط به این درخواست همین شناسه را خواهند داشت.
🌐 اما داستان فقط HTTP نیست...

قسمت سخت ماجرا زمانی شروع می‌شود که سیستم وارد دنیای Asynchronous Messaging می‌شود.
در همین نقطه رد درخواست گم می‌شود.
📨 ءCorrelation ID داخل پیام هم قرار می‌گیرد
هنگام Publish کردن پیام توسط MassTransit همان Correlation ID داخل Envelope پیام ذخیره می‌شود.
یعنی پیام چیزی شبیه این خواهد داشت:
CorrelationId

a17d59d8-78d2-4b1f-bd89-40d3f52b44f3

در نتیجه...
وقتی Consumer پیام را دریافت می‌کند...
همان شناسه هنوز همراه پیام است.
هیچ بخشی از مسیر گم نمی‌شود.
📝 ءSerilog هم به صورت خودکار این شناسه را وارد Logها می‌کند
به کمک یک Serilog Enricher
ءCorrelation ID مستقیماً از:
✅ HTTP Header
یا
✅ MassTransit Message
خوانده می‌شود.
در نتیجه دیگر لازم نیست بنویسیم:
Log.Information(
"Payment {CorrelationId}",
correlationId);

تمام Logها به صورت خودکار این مقدار را خواهند داشت.
⚙️ نقش MediatR Pipeline Behavior

قبلاً برای Cross-Cutting Concernها از Pipeline Behavior استفاده کرده بودیم.
حالا همان Pipeline یک مسئولیت جدید هم دارد.
در ابتدای اجرای هر Command:
یک Logging Scope باز می‌کند.
BeginScope()

CorrelationId

از این لحظه...
هر لاگی که داخل:
Repository
Domain Service
Application Service
EF Core
یا هر بخش دیگری ثبت شود...
به صورت خودکار همین Correlation ID را خواهد داشت.
بدون اینکه حتی یک بار آن را دستی پاس بدهیم.
More from @csharpgeeks
  1. Sep 22, 2026یه مدتی قراره از دنیای NET. فاصله بگیرم، چون وقتشه برم سربازی. راستش نمیدونم این مدت رو چج…
  2. Sep 20, 2026🔥 حالا مشکل اصلی: Alert Storm فرض کن Database از دسترس خارج شده. ۱۰۰ Pod داری. هر Pod می‌…
  3. Sep 20, 2026🚨 طراحی سیستم Monitoring و Alerting در یک سیستم بزرگ فرض کن ساعت ۳ صبح است. سیستم شما با…
  4. Sep 19, 2026#Engineering_Leadership تصمیم نگرفتن هم یک تصمیم است یه چیز عجیب توی تیم‌های مهندسی: گاهی…
  5. Sep 19, 2026☑ چک‌لیست آماده‌سازی تیم، فرایندها و زیرساخت برای توسعه با AI توجه: هیچ چک‌لیستی جهان‌شمول…
  6. Sep 19, 2026📌پایان یک انتظار طولانی: اعتبارسنجی ناهمگام (Async Validation) در NET 11.
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →