تسجيل (Logging) لـ C# (.NET): مراجعة أفضل الحلول
التسجيل (Logging) هو جانب بالغ الأهمية في تطوير أي تطبيق جاد بلغة C#. فهو يسمح بتتبع حالة النظام، تشخيص الأخطاء، تحليل سلوك المستخدمين، وجمع مقاييس الأداء. في النظام البيئي لـ .NET، توجد عدة مكتبات ناضجة للتسجيل، لكل منها نقاط قوتها. في هذه المقالة، سنستعرض ثلاثة من أشهر الحلول: Serilog، NLog، و log4net، بالإضافة إلى التجريد القياسي Microsoft.Extensions.Logging.
لماذا نحتاج إلى مكتبة منفصلة للتسجيل؟
الفئة المدمجة System.Diagnostics.Debug أو Console.WriteLine مناسبة فقط لأبسط السيناريوهات. توفر المكتبات الاحترافية ما يلي:
- مستويات التسجيل (Trace، Debug، Information، Warning، Error، Fatal) — تصفية مرنة للرسائل.
- التسجيل المنظم (Structured Logging) — حفظ البيانات بتنسيق JSON مع إمكانية التحليل لاحقًا.
- مستقبلات متعددة (sinks/targets) — الكتابة إلى ملف، قاعدة بيانات، وحدة التحكم، ELK-Stack، Sentry، Application Insights، إلخ.
- تكوين ديناميكي — تغيير مستوى التسجيل دون إعادة تشغيل التطبيق.
- الأداء — كتابة غير متزامنة، تخزين مؤقت، تأثير ضئيل على سرعة التشغيل.
1. Serilog — المعيار الحديث
Serilog هي المكتبة الأكثر شيوعًا لـ .NET، والتي ركزت على التسجيل المنظم. بدلاً من تنسيق السلاسل باستخدام string.Format، تستخدم عناصر نائبة مسماة:
using Serilog;
Log.Logger = new LoggerConfiguration() .MinimumLevel.Debug() .WriteTo.Console() .WriteTo.File("logs/app-.log", rollingInterval: RollingInterval.Day) .WriteTo.ApplicationInsights(TelemetryConfiguration.Active, TelemetryConverter.Traces) .CreateLogger();
// مثال على التسجيل المنظمLog.Information("المستخدم {UserId} قام بتنفيذ الطلب {OrderId} بقيمة {Total:C}", userId, orderId, total);Serilog مثالي للخدمات المصغرة (microservices)، التطبيقات السحابية، والمشاريع التي يتطلب فيها تحليل عميق للسجلات عبر Kibana أو Grafana.
2. NLog — المرونة والأداء
NLog هي مكتبة قوية مع إمكانيات توجيه غنية. تدعم التكوين عبر XML وكذلك الإعداد البرمجي. من مميزات NLog آلية الكتابة غير المتزامنة المدمجة ودعم القواعد الشرطية.
using NLog;
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public void ProcessOrder(Order order){ Logger.Info("بدء معالجة الطلب {OrderId}", order.Id); try { // منطق الأعمال Logger.Debug("تمت معالجة الطلب {OrderId} بنجاح", order.Id); } catch (Exception ex) { Logger.Error(ex, "خطأ في معالجة الطلب {OrderId}", order.Id); throw; }}غالبًا ما يتم اختيار NLog لتطبيقات سطح المكتب (WPF، WinForms) والمشاريع القديمة (legacy) نظرًا لسهولة الترحيل من log4net.
3. log4net — المخضرم المُجرّب
log4net هو منفذ (port) لمكتبة Java الشهيرة log4j. إنه الحل الأقدم الذي لا يزال يُستخدم بنشاط في المشاريع المؤسسية. الميزة الرئيسية هي العدد الهائل من المحولات (adapters) والمستقبلات (appenders) التي تم تطويرها على مدى عقود.
// التكوين عبر XML (log4net.config)<log4net> <appender name="RollingFile" type="log4net.Appender.RollingFileAppender"> <file value="logs/app.log" /> <rollingStyle value="Date" /> <datePattern value="yyyyMMdd" />