TGViewer
C# Geeks (.NET) C# Geeks (.NET) @csharpgeeks · 548 subscribers
Post #194 89
لاگینگ در NET. - بهترین شیوه‌ها 📝

لاگ‌ها باید به شما در رفع باگ‌ها کمک کنند و توضیح دهند که اپلیکیشن در حال حاضر چه کاری انجام می‌دهد. آن‌ها نباید شما را در متن غرق کنند یا آن یک خطی را که نیاز دارید، پنهان کنند. این راهنما نشان می‌دهد که چگونه لاگینگ را در NET. مدرن راه‌اندازی کنید، پیام‌های ساختاریافته (structured) بنویسید، سطح مناسب را انتخاب کنید و request correlation را اضافه کنید. همچنین، لاگ‌ها را با متریک‌ها اشتباه نگیرید، اشتباه است که برای بررسی تعداد فراخوانی‌های API در هر بازه زمانی X، لاگ اضافه کنید.

شروع سریع (Minimal API) 🚀

// Program.cs
var builder = WebApplication.CreateBuilder(args);
// لاگینگ در کنسول به صورت پیش‌فرض فعال است؛ می‌توانید آن را از طریق appsettings.json تغییر دهید
var app = builder.Build();

app.MapGet("/", (ILogger<Program> log) =>
{
log.LogInformation("Health probe hit at {UtcNow}", DateTime.UtcNow);
return "OK";
});

app.Run();


این کد از قبل در کنسول با timestamp، سطح لاگ، دسته‌بندی و پیام می‌نویسد. پیکربندی
در appsettings.json قرار دارد.

سطوح لاگ که منطقی هستند

🔬 Trace :
بسیار پرحرف، جریان گام‌به‌گام. در پروداکشن خاموش است.
🐞 Debug :
در طول توسعه مفید است؛ بعداً می‌توان آن را با خیال راحت غیرفعال کرد.

ℹ️ Information :
رویدادهای سطح بالا: شروع برنامه، تکمیل درخواست، رویدادهای بیزینسی.

⚠️ Warning :
شرایط غیرعادی: تلاش‌های مجدد (retries)، تایم‌اوت‌هایی که بازیابی می‌شوند.

❌ Error :
شکست‌هایی که شما catch و مدیریت می‌کنید (شامل exception).

🔥 Critical :
اپلیکیشن سالم نیست.

پایین‌ترین سطحی را انتخاب کنید که هنوز فوریت مناسب را منتقل می‌کند. اگر همه چیز Information باشد، هیچ چیز Information نیست.

لاگینگ ساختاریافته بهتر از الحاق رشته است
قالب‌های پیام (Message templates)، داده‌ها را برای کوئری زدن در آینده در فیلدها نگه می‌دارند. در اینجا از درون‌یابی رشته (string interpolation) خودداری کنید.
// ✅ خوب
log.LogInformation("User {UserId} logged in from {Ip}", userId, ip);

// ❌ بد (کوئری زدن سخت است)
log.LogInformation($"User {userId} logged in from {ip}");

با قالب‌ها، ابزارها می‌توانند بر روی UserId یا Ip بدون تجزیه متن، فیلتر کنند.
استثناها را به عنوان اولین آرگومان وارد کنید:
try
{
await service.ProcessAsync(orderId);
}
catch (Exception ex)
{
log.LogError(ex, "Failed to process order {OrderId}", orderId);
}


پیکربندی لاگینگ از طریق appsettings.json ⚙️

{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Microsoft.EntityFrameworkCore.Database.Command": "Warning"
},
"Console": {
"FormatterName": "json",
"FormatterOptions": {
"IncludeScopes": true,
"UseUtcTimestamp": true
}
}
}
}


دسته‌بندی‌های پرسروصدا (مانند جزئیات داخلی فریم‌ورک) را به Warning کاهش دهید.
فرمت‌دهنده JSON با جمع‌آوری‌کننده‌های لاگ به خوبی کار می‌کند و فیلدها را ساختاریافته نگه می‌دارد.

دسته‌بندی‌ها و DI🗃

دسته‌بندی لاگر، نوعی است که شما درخواست می‌کنید. این به فیلتر کردن و گروه‌بندی لاگ‌ها کمک می‌کند.
public sealed class BillingService(ILogger<BillingService> log)
{
public void Charge(Guid orderId, decimal amount)
=> log.LogInformation("Charging {OrderId} {Amount}", orderId, amount);
}


Scopeها و Correlation IDها 🔗

اسکوپ ها پراپرتی‌های اضافی را به هر خط لاگ داخل یک بلوک متصل می‌کنند. یک Correlation ID برای هر درخواست اضافه کنید تا بتوانید یک مسیر را در سراسر ماژول‌ها ردیابی کنید.
app.Use(async (ctx, next) =>
{
var cid = ... // Get Correlation ID from header or create a new one

using (loggerFactory.CreateLogger("Correlation").BeginScope(new Dictionary<string, object?>
{
["CorrelationId"] = cid
}))
{
// ...
await next();
}
});

حالا هر خط لاگ در آن درخواست شامل CorrelationId است.
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 →