تسجيل السجلات في تطبيقات C#: أفضل الممارسات في .NET

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

تسجيل الأحداث في تطبيقات C#: أفضل الممارسات والأدوات (.NET)



تسجيل الأحداث ليس مجرد كتابة رسائل في ملف. إنه مكون حيوي لأي تطبيق إنتاجي بلغة C#. بدون نظام تسجيل أحداث عالي الجودة، أنت تعمل بشكل أعمى: تبقى الأخطاء غير مكتشفة، ويصعب تحليل الأداء، ويتحول التصحيح إلى تخمين. في هذه المقالة، سنستعرض أفضل ممارسات تسجيل الأحداث في بيئة .NET، وننظر في المكتبات الشائعة (Serilog, NLog)، ومستويات تسجيل الأحداث الصحيحة، والنهج المنظم لجمع البيانات.



1. اختيار مكتبة تسجيل الأحداث: Serilog vs NLog



في عالم .NET، هناك العديد من الحلول الناضجة. الأكثر شيوعًا هما Serilog و NLog. كلاهما يدعم تسجيل الأحداث غير المتزامن، والعديد من sinks (أهداف الإخراج)، والتكامل مع .NET Core/5+ من خلال ILogger.



Serilog

يشتهر Serilog بفلسفته في تسجيل الأحداث المنظم. بدلاً من السلاسل النصية البسيطة، تقوم بتمرير الكائنات، ويقوم Serilog بتسلسلها إلى JSON. هذا مثالي لأنظمة مثل Elasticsearch أو Seq أو Datadog.



// مثال Serilogusing Serilog;

Log.Logger = new LoggerConfiguration() .MinimumLevel.Information() .WriteTo.Console() .WriteTo.File("logs/app-.log", rollingInterval: RollingInterval.Day) .CreateLogger();

Log.Information("المستخدم {UserId} قام بتسجيل الدخول في {Time}", userId, DateTime.UtcNow);


NLog

NLog هو أداة أكثر تقليدية، لكنها لا تقل قوة. إنها مناسبة تمامًا للمشاريع التي تحتاج إلى تكوين مرن عبر XML أو الكود. يدعم تدوير الملفات، والإرسال عبر البريد الإلكتروني، والتكامل مع قواعد البيانات.



// مثال NLogusing NLog;

private static readonly Logger Logger = LogManager.GetCurrentClassLogger();

Logger.Info("المستخدم {UserId} قام بتنفيذ إجراء", userId);


متى تختار ماذا؟ إذا كنت تبني خدمات مصغرة أو تستخدم ELK-stack، فاختر Serilog. إذا كنت بحاجة إلى إعداد بسيط في مشاريع قديمة، فاختر NLog. في كلتا الحالتين، كلاهما يدعم ILogger القياسي من Microsoft.Extensions.Logging.



2. مستويات تسجيل الأحداث: متى وماذا تكتب



من أكثر الأخطاء شيوعًا كتابة كل شيء في مستوى Information أو، على العكس، وضع Debug في كل مكان. استخدم المستويات الصحيحة:



  • Trace (0) — معلومات مفصلة للغاية: الدخول/الخروج من الدوال، قيم المتغيرات. يُستخدم فقط أثناء التصحيح.
  • Debug (1) — رسائل تصحيح مفيدة للمطور، ولكن ليس للمشغل.
  • Information (2) — أحداث الأعمال: "تم إنشاء الطلب"، "تم تسجيل المستخدم". هذا هو مستوى العمل الرئيسي.
  • Warning (3) — حالة غير طبيعية لا تعطل التطبيق: انتهاء مهلة الطلب، إعادة محاولة الاتصال.
  • Error (4) — الاستثناءات المعالجة، أخطاء منطق الأعمال، أعطال في عمل الوحدة.
  • Critical (5) — أخطاء قاتلة: فقدان الاتصال بقاعدة البيانات، نقص الذاكرة، انهيار التطبيق بأكمله.


// مثال على الاستخدام الصحيح للمستوياتpublic async Task<Order> CreateOrderAsync(CreateOrderRequest request){    Log.Debug("بدء إنشاء الطلب للمستخدم {UserId}", request.UserId);

try { var order = new Order(request); await _repository.SaveAsync(order); Log.Information("تم إنشاء الطلب {OrderId} بواسطة المستخدم {UserId}", order.Id, request.UserId); return order; } catch (DbException ex) { Log.Error(ex, "خطأ في قاعدة البيانات أثناء إنشاء الطلب للمستخدم {UserId}", request.UserId); throw; // إعادة الرمي للأعلى }}


3. تسجيل الأحداث المنظم: لماذا هذا مهم؟



تسجيل الأحداث التقليدي من خلال

المدونات

توصيات الكتب