التسجيل في تطبيقات TypeScript: أفضل الممارسات والأدوات

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

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

ابدأ الدورة

مقدمة: لماذا يعتبر التسجيل (Logging) مهمًا في TypeScript

التسجيل ليس مجرد تسجيل الأحداث في ملف. في تطبيقات TypeScript الحديثة، يُعد التسجيل المُهيأ بشكل صحيح أساسًا لتصحيح الأخطاء والمراقبة وتحليل الأداء. بدون سجلات عالية الجودة، يضيع المطور ساعات في إعادة إنتاج الأخطاء، ولا يستطيع فريق التشغيل تحديد نقاط الضعف بسرعة.

TypeScript، كطبقة إضافية فوق JavaScript، يوفر كتابة صارمة (Strict Typing)، مما يسمح بإنشاء أنظمة تسجيل أكثر قابلية للتنبؤ وأمانًا. ومع ذلك، فإن استخدام console.log() البسيط في بيئة الإنتاج (Production) هو نمط سيئ يؤدي إلى ضوضاء معلوماتية وفقدان بيانات مهمة.

في هذه المقالة، سنستعرض أفضل ممارسات التسجيل في TypeScript: من اختيار المكتبة إلى هيكلة السجلات والعمل مع السياق (Context).



اختيار مكتبة للتسجيل

في نظام TypeScript/Node.js البيئي، توجد عدة مكتبات شائعة. دعنا نستعرض ثلاثة خيارات رئيسية:

  • Winston — المكتبة الأكثر شيوعًا مع إعداد مرن لناقلات الإخراج (Transports) (الإخراج إلى وحدة التحكم، ملف، قاعدة بيانات). تدعم مستويات التسجيل والتنسيق.
  • Pino — مكتبة حديثة، موجهة نحو الأداء. مثالية للأنظمة عالية التحميل.
  • Bunyan — خيار أقل شيوعًا ولكنه مستقر. جميع المسجلات (Loggers) تُخرج البيانات بتنسيق JSON.

لتطبيق TypeScript نموذجي، نوصي باستخدام Winston أو Pino. مثال على إعداد Winston مع TypeScript:

import winston from 'winston';

const logger = winston.createLogger({ level: 'info', format: winston.format.json(), transports: [ new winston.transports.Console(), new winston.transports.File({ filename: 'error.log', level: 'error' }), ],});

logger.info('الخادم قيد التشغيل', { port: 3000 });


التكامل مع TypeScript: الأنواع والواجهات

للحصول على أقصى استفادة من الكتابة الصارمة (Typing)، قم بإنشاء غلاف (Wrapper) للمسجل باستخدام الواجهات (Interfaces):

interface LoggerOptions {  level?: string;  service?: string;}

interface ILogger { info(message: string, meta?: unknown): void; error(message: string, error?: Error): void; warn(message: string, meta?: unknown): void;}

سيسمح لك هذا بالتحكم الصارم في أنواع البيانات المرسلة وتجنب الأخطاء في مرحلة التجميع (Compilation).



مستويات التسجيل واستخدامها الصحيح

مستويات التسجيل القياسية (من الأكثر حرجًا إلى الأقل): error، warn، info، debug، trace. من المهم الالتزام بدلالات موحدة:

  • error — فقط للأخطاء غير القابلة للاسترداد التي تتطلب انتباه المطور.
  • warn — للمواقف التي قد تكون إشكالية ولكنها لا تعطل عمل التطبيق.
  • info — للأحداث الرئيسية: بدء تشغيل الخادم، معالجة طلب، تسجيل دخول ناجح.
  • debug — لتصحيح الأخطاء أثناء التطوير. لا تقم بتضمين هذا المستوى في بيئة الإنتاج (Production).

مثال على تغيير المستوى ديناميكيًا اعتمادًا على البيئة:

const logLevel = process.env.NODE_ENV === 'production' ? 'warn' : 'debug';const logger = winston.createLogger({ level: logLevel });


السجلات المنظمة والسياق

بدلاً من الرسائل النصية، استخدم السجلات المنظمة (Structured Logs) بتنسيق JSON. هذا يسمح بتحليل السجلات بسهولة باستخدام ELK-Stack (Elasticsearch, Logstash, Kibana) أو أنظمة أخرى.

تأكد من إضافة معلومات السياق: معرف الطلب (Request ID)، اسم المستخدم، اسم الخدمة، الطابع الزمني. مثال باستخدام Pino:

import pino from 'pino';

const logger = pino({ level: 'info', mixin() { return { service: 'my-api' }; },});

// إضافة

المدونات

توصيات الكتب