TGViewer
C# Geeks (.NET) C# Geeks (.NET) @csharpgeeks · 550 subscribers
Post #405 141
⚙️ Cross-Cutting Concern شماره ۱ - لاگ‌گیری (Logging)

لاگ‌گیری یکی از جنبه‌های بنیادین توسعهٔ نرم‌افزار است که به شما اجازه می‌دهد رفتار یک برنامه را بررسی کنید.
این قابلیت برای دیباگ کردن (Debugging)، پایش سلامت سیستم (Monitoring Application Health) و ردیابی فعالیت کاربران و ناهنجاری‌های سیستم (Tracking User Activities and System Anomalies) حیاتی است.

در زمینهٔ Clean Architecture، پیاده‌سازی لاگ‌گیری باید به گونه‌ای انجام شود که اصل تفکیک وظایف (Separation of Concerns) حفظ شود.

🧠 رویکرد ظریف با MediatR’s IPipelineBehavior

یکی از راه‌های زیبا برای رسیدن به این هدف، استفاده از IPipelineBehavior در MediatR است.
با قرار دادن منطق لاگ‌گیری درون یک Pipeline Behavior، اطمینان حاصل می‌کنیم که لاگ‌گیری به‌عنوان یک دغدغهٔ مجزا و مستقل از منطق تجاری در نظر گرفته می‌شود.

این روش به ما امکان می‌دهد اطلاعات دقیقی از درخواست‌هایی که در سراسر برنامه جریان دارند ثبت کنیم.

📋 ویژگی‌های یک سیستم لاگ‌گیری مؤثر

لاگ‌گیری مؤثر باید یکنواخت (Consistent)، دارای زمینه (Context-Rich) و غیرمزاحم (Non-Intrusive) باشد.
با استفاده از قابلیت‌های Structured Logging در Serilog، می‌توانیم لاگ‌هایی بسازیم که نه‌تنها گویا هستند بلکه به‌راحتی قابل جست‌وجو نیز هستند.
این ویژگی برای درک وضعیت برنامه در هر لحظه از زمان ضروری است.

اگر این کار به‌درستی انجام شود، Structured Logging بینش‌های بسیار ارزشمندی دربارهٔ وضعیت برنامه ارائه می‌دهد —
بدون آن‌که منطق اصلی سیستم را شلوغ کند.
این کار نوعی تعادل میان جزئیات و شفافیت (Balance of Granularity and Clarity) است که اطمینان می‌دهد لاگ‌ها ابزاری مفید باشند نه منبعی از نویز.

🧩 نمونه کد
using Serilog.Context;

internal sealed class RequestLoggingPipelineBehavior<TRequest, TResponse>(
ILogger<RequestLoggingPipelineBehavior<TRequest, TResponse>> logger)
: IPipelineBehavior<TRequest, TResponse>
where TRequest : class
where TResponse : Result
{
public async Task<TResponse> Handle(
TRequest request,
RequestHandlerDelegate<TResponse> next,
CancellationToken cancellationToken)
{
string requestName = typeof(TRequest).Name;

logger.LogInformation(
"Processing request {RequestName}",
requestName);

TResponse result = await next();

if (result.IsSuccess)
{
logger.LogInformation(
"Completed request {RequestName}",
requestName);
}
else
{
using (LogContext.PushProperty("Error", result.Error, true))
{
logger.LogError(
"Completed request {RequestName} with error",
requestName);
}
}

return result;
}
}
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 →