مقدمة في تسجيل الأحداث لتطبيقات TypeScript
\n\nتسجيل الأحداث هو عملية تسجيل الأحداث التي تحدث أثناء تشغيل البرنامج. بالنسبة لتطبيقات TypeScript، خاصة تلك التي تعمل في بيئة Node.js، فإن تسجيل الأحداث المُعد بشكل صحيح ليس مجرد ممارسة جيدة، بل هو أداة بالغة الأهمية لتصحيح الأخطاء والمراقبة وتحليل الأخطاء.
\n\nالعديد من المطورين المبتدئين يقتصرون على استخدام console.log(). ومع ذلك، في بيئة الإنتاج (production)، هذا الأسلوب غير فعال: فهو لا يسمح بالتحكم المرن في مستويات الأهمية، أو تصفية الرسائل، أو حفظها في ملفات. في هذه المقالة، سنشرح كيفية إنشاء نظام احترافي لتسجيل الأحداث في TypeScript من الصفر.
لماذا لا يجب استخدام console.log في الإنتاج؟
\n\nلنلق نظرة على مثال نموذجي:
\n\n// أسلوب سيء - استخدام console.log مباشرة\nfunction processOrder(orderId: string): void {\n console.log(`Processing order ${orderId}`);\n try {\n // منطق الأعمال\n } catch (error) {\n console.error(`Error processing order: ${error}`);\n }\n}\n\n\nمشاكل هذا الأسلوب:
\n- \n
- غياب مستويات التسجيل: لا يمكن فصل رسائل التصحيح عن الأخطاء الحرجة. \n
- لا تنسيق: صعوبة قراءة كميات كبيرة من البيانات. \n
- لا يمكن إعادة التوجيه: جميع الرسائل تذهب فقط إلى stdout/stderr. \n
- مشاكل في الأداء: الكتابة المتزامنة إلى وحدة التحكم قد تبطئ التطبيق. \n
أفضل الممارسات لتسجيل الأحداث في TypeScript
\n\n1. اختيار مكتبة لتسجيل الأحداث
\n\nبالنسبة لـ TypeScript، يُوصى باستخدام إحدى المكتبتين الشائعتين:
\n- \n
- Winston — مسجل أحداث قوي ومرن مع دعم الناقلات (ملف، وحدة تحكم، قواعد بيانات). \n
- Pino — مسجل أحداث فائق السرعة، مثالي لتطبيقات الحمل العالي (high-load). \n
سنقوم بتثبيت Winston:
\nnpm install winston\nnpm install @types/winston --save-dev\n\n\n2. إنشاء مسجل أحداث قابل للتكوين
\n\nسننشئ وحدة logger.ts:
import winston from 'winston';\n\nconst logger = winston.createLogger({\n level: process.env.LOG_LEVEL || 'info',\n format: winston.format.combine(\n winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),\n winston.format.errors({ stack: true }),\n winston.format.json()\n ),\n transports: [\n new winston.transports.Console({\n format: winston.format.combine(\n winston.format.colorize(),\n winston.format.simple()\n )\n }),\n new winston.transports.File({ \n filename: 'logs/error.log', \n level: 'error' \n }),\n new winston.transports.File({ \n filename: 'logs/combined.log' \n })\n ]\n});\n\nexport default logger;\n\n\nالآن يمكن استخدام مسجل الأحداث في أي وحدة:
\nimport logger from './logger';\n\nfunction getUser(id: string) {\n logger.info(`Fetching user with ID: ${id}`);\n try {\n // منطق الحصول على المستخدم\n logger.debug('User data retrieved successfully');\n } catch (error) {\n logger.error('Failed to fetch user', { userId: id, error });\n }\n}\n\n\n3. استخدام مستويات تسجيل الأحداث
\n\nالمستويات القياسية (من الأقل أهمية إلى الأكثر أهمية):
\n- \n
- debug — معلومات تصحيح مفصلة (للتطوير فقط). \n
- info — رسائل معلوماتية قياسية. \n
- warn — تحذيرات حول مشاكل محتملة. \n
- error — أخطاء تتطلب الانتباه. \n
قم بتعيين مستوى تسجيل الأحداث من خلال متغيرات البيئة:
\n// في ملف .env\nLOG_LEVEL=debug # للتطوير\nLOG_LEVEL=warn # للإنتاج\n\n\n4. تسجيل الأحداث المهيكل
\n\nقم بتمرير إضاف