دليل شامل لـ Winston مع JavaScript (Node.js): أمثلة وتطبيقات

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

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

ابدأ الدورة

ما هو Winston ولماذا تحتاجه؟

Winston هي مكتبة قوية ومرنة لتسجيل السجلات (logging) في بيئة Node.js. تم إنشاؤها بواسطة Charlie Robbins، وهي واحدة من أشهر المكتبات لتسجيل الأحداث في نظام JavaScript البيئي. تتيح Winston للمطورين تسجيل الرسائل بمستويات أهمية مختلفة (info, warn, error, debug وغيرها)، وتخصيص تنسيقات الإخراج (JSON، نص عادي، مع طوابع زمنية)، بالإضافة إلى توجيه السجلات إلى وجهات متعددة (الكونسول، الملفات، قواعد البيانات، الخدمات الخارجية).

لماذا تحتاج Winston؟ في أي تطبيق جاد، تسجيل الأحداث ليس رفاهية بل ضرورة. فهو يساعد في:

  • تصحيح أخطاء التطبيق: تتيح لك السجلات فهم ما حدث في النظام وقت حدوث الخطأ.
  • مراقبة الأداء: يمكنك تسجيل وقت تنفيذ الاستعلامات واكتشاف الاختناقات.
  • تحليل سلوك المستخدمين: تساعد السجلات في فهم كيفية تفاعل المستخدمين مع التطبيق.
  • حفظ التاريخ: يمكن تخزين جميع الأحداث في ملفات أو قواعد بيانات لتحليلها لاحقًا.
  • تعزيز الأمان: يمكن للسجلات تسجيل الأنشطة المشبوهة ومحاولات الاختراق.

يحل Winston هذه المهام بأناقة وكفاءة، حيث يوفر واجهة موحدة للعمل مع السجلات.

تثبيت Winston

يتم تثبيت Winston عبر مدير الحزم npm. افتح الطرفية (Terminal) في المجلد الجذري لمشروعك ونفذ الأمر التالي:

npm install winston

إذا كنت تستخدم yarn:

yarn add winston

بعد التثبيت، يمكنك استيراد Winston إلى مشروعك:

const winston = require('winston');

للمشاريع التي تستخدم ES modules (type: "module" في ملف package.json):

import winston from 'winston';

بداية سريعة مع مثال عملي

لنقم بإنشاء مسجل بسيط يطبع الرسائل في الكونسول وفي ملف:

// logger.js
const winston = require('winston');

// إنشاء مسجل بناقلين: الكونسول وملف
const logger = winston.createLogger({
    level: 'info', // الحد الأدنى لمستوى التسجيل
    format: winston.format.json(), // تنسيق الإخراج JSON
    transports: [
        new winston.transports.Console(), // طباعة في الكونسول
        new winston.transports.File({ filename: 'combined.log' }) // حفظ في ملف
    ]
});

// استخدام المسجل
logger.info('تم تشغيل التطبيق');
logger.warn('تحذير: مستوى الذاكرة منخفض');
logger.error('خطأ في الاتصال بقاعدة البيانات');

console.log('تم تسجيل السجلات. تحقق من ملف combined.log');

بعد تشغيل هذا الكود، ستظهر السجلات في الكونسول، وستجد أيضًا ملف combined.log في المجلد الجذري للمشروع.

الطرق والوظائف الأساسية في Winston

يوفر Winston واجهة برمجة تطبيقات (API) غنية. دعنا نستعرض 10 طرق ووظائف رئيسية مع أمثلة.

1. winston.createLogger(options)

الوظيفة: إنشاء نسخة جديدة من المسجل بإعدادات محددة. هذه هي الطريقة الأساسية لإنشاء مسجل.

المعلمات:

  • options.level (string): الحد الأدنى لمستوى التسجيل (مثل 'info', 'debug', 'error').
  • options.format (Format): تنسيق إخراج السجلات (مثل winston.format.json(), winston.format.simple()).
  • options.transports (Transport[]): مصفوفة من الناقلات التي تحدد أين تذهب السجلات.
  • options.defaultMeta (Object): بيانات وصفية ستُضاف إلى كل رسالة.
  • options.exitOnError (boolean): إذا كان true، ستنتهي العملية عند حدوث خطأ في التسجيل (القيمة الافتراضية true).

مثال:

const logger = winston.createLogger({
    level: 'debug',
    format: winston.format.json(),
    transports: [
        new winston.transports.Console()
    ]
});

2. logger.log(level, message, meta)

الوظيفة: تسجيل رسالة بمستوى محدد. هذه هي الطريقة العامة لتسجيل أي مستوى.

المعلمات:

  • level (string): مستوى الرسالة (مثل 'info', 'error').
  • message (string): نص الرسالة.
  • meta (Object, اختياري): بيانات إضافية مرتبطة بالرسالة.

مثال:

logger.log('info', 'تم تحميل الصفحة بنجاح', { userId: 123 });

3. logger.info(message, meta)

الوظيفة: تسجيل رسالة بمستوى 'info'. اختصار لـ logger.log('info', ...).

مثال:

logger.info('تم بدء الخادم على المنفذ 3000');

4. logger.warn(message, meta)

الوظيفة: تسجيل رسالة تحذيرية بمستوى 'warn'.

مثال:

logger.warn('اقتراب حد الذاكرة المسموح به');

5. logger.error(message, meta)

الوظيفة: تسجيل رسالة خطأ بمستوى 'error'.

مثال:

logger.error('فشل الاتصال بقاعدة البيانات', { errorCode: 500 });

6. logger.debug(message, meta)

الوظيفة: تسجيل رسالة تصحيح أخطاء بمستوى 'debug'.

مثال:

logger.debug('تم استدعاء الدالة getUser مع المعاملات:', { userId: 42 });

7. logger.add(transport)

الوظيفة: إضافة ناقل جديد إلى المسجل بعد إنشائه.

مثال:

logger.add(new winston.transports.File({ filename: 'error.log', level: 'error' }));

8. logger.remove(transport)

الوظيفة: إزالة ناقل موجود من المسجل.

مثال:

logger.remove(consoleTransport);

9. logger.clear()

الوظيفة: إزالة جميع الناقلات من المسجل.

مثال:

logger.clear(); // إزالة جميع الناقلات

10. logger.profile(id, [meta])

الوظيفة: بدء أو إنهاء ملف تعريف أداء (performance profile) لقياس وقت التنفيذ.

مثال:

logger.profile('testProfile');
// ... بعض العمليات ...
logger.profile('testProfile'); // سيسجل الوقت المستغرق

تخصيص التنسيقات والناقلات

يتيح Winston تخصيصًا واسعًا. يمكنك دمج تنسيقات مختلفة واستخدام ناقلات متعددة في وقت واحد. على سبيل المثال، يمكنك تنسيق السجلات بتنسيق JSON مع طابع زمني وإرسالها إلى ملف وخدمة خارجية مثل Loggly أو Papertrail.

باستخدام Winston، يمكنك بناء نظام تسجيل قوي ومرن يناسب احتياجات تطبيقك تمامًا.

توصيات