المقدمة
حلاً فعالًا لتسجيل البيانات أمر أساسي لنجاح أي تطبيق. وينستون هو مكتبة تسجيل متعددة الاستخدامات وحلاً شهيرًا متاحًا لتطبيقات Node.js. تتضمن ميزات وينستون دعمًا لخيارات تخزين متعددة، ومستويات تسجيل البيانات، واستعلامات التسجيل، ومحلل مدمج.
في هذا البرنامج التعليمي، ستستخدم وينستون لتسجيل تطبيق Node/Express الذي ستقوم بإنشائه كجزء من هذه العملية. سترى أيضًا كيفية دمج وينستون مع مورغان، وهو آخر سجل وسيط HTTP الشهير لـ Node.js، لتوحيد سجلات بيانات الطلبات HTTP مع معلومات أخرى. بعد الانتهاء من هذا البرنامج التعليمي، سيكون خادم Ubuntu الخاص بك يعمل بتطبيق Node/Express صغير، وسيتم تنفيذ وينستون لتسجيل الأخطاء والرسائل إلى ملف والوحدة النمطية.
المتطلبات الأولية
لمتابعة هذا البرنامج التعليمي، ستحتاج إلى:
-
خادم Ubuntu 20.04 مع مستخدم sudo غير جذري، يمكنك إعداده باتباع إعداد الخادم الأولي.
-
تم تثبيت Node.js باستخدام PPA (أرشيف الحزم الشخصية الرسمي) ، والذي يتم شرحه في كيفية تثبيت Node.js على Ubuntu 20.04، الخيار 2.
الخطوة 1 — إنشاء تطبيق Node/Express أساسي
يُستخدم Winston في كثير من الأحيان لتسجيل الأحداث من تطبيقات الويب المبنية بـ Node.js. في هذه الخطوة، ستقوم بإنشاء تطبيق ويب Node.js بسيط باستخدام إطار Express. ستستخدم express-generator
، أداة سطر الأوامر، لتشغيل تطبيق ويب Node/Express بسرعة.
نظرًا لأنك قمت بتثبيت مدير حزم Node خلال الشروط الأولية، يمكنك استخدام أمر npm
لتثبيت express-generator
:
تُثبّت العلمة -g
الحزمة بشكل عام، مما يعني أنه يمكن استخدامها كأداة سطر الأوامر خارج مشروع/وحدة Node موجودة.
بعد تثبيت express-generator
، يمكنك إنشاء تطبيقك باستخدام الأمر express
، تلاه اسم الدليل الذي تريد استخدامه للمشروع:
سيتم تسمية المشروع في هذا البرنامج التعليمي باسم myApp
.
ملاحظة: يمكن أيضًا تشغيل أداة express-generator
مباشرة دون تثبيتها بشكل عام كأمر متاح على مستوى النظام أولاً. للقيام بذلك، قم بتشغيل هذا الأمر:
الأمر npx
هو أداة تشغيل الأوامر المرفقة مع مدير الحزم Node Package Manager التي تجعل من السهل تشغيل أدوات سطر الأوامر من مسجل npm
.
أثناء التشغيل الأول، سيُطلب منك الموافقة على تنزيل الحزمة:
Need to install the following packages:
express-generator
Ok to proceed? (y)
قم بالرد بـ y
واضغط على ENTER
. الآن يمكنك استخدام npx express-generator
بدلاً من express
.
بعد ذلك، قم بتثبيت Nodemon، والذي سيعيد تحميل التطبيق تلقائيًا كلما قمت بإجراء تغييرات. يتعين إعادة تشغيل تطبيق Node.js في أي وقت يتم فيه إجراء تغييرات على الشفرة المصدرية لتحقيق تلك التغييرات، لذا سيقوم Nodemon تلقائيًا بمراقبة التغييرات وإعادة تشغيل التطبيق. نظرًا لأنك ترغب في القدرة على استخدام nodemon
كأداة سطر الأوامر، فقم بتثبيته بالعلمة -g
:
لإكمال إعداد التطبيق، انتقل إلى دليل التطبيق وقم بتثبيت التبعيات كما يلي:
بشكل افتراضي، تعمل التطبيقات التي تم إنشاؤها باستخدام express-generator
على المنفذ 3000
، لذا يجب التأكد من عدم حجب جدار الحماية لهذا المنفذ.
لفتح المنفذ 3000
، قم بتشغيل الأمر التالي:
الآن لديك كل ما تحتاجه لبدء تطبيق الويب الخاص بك. لفعل ذلك، قم بتشغيل الأمر التالي:
يبدأ هذا الأمر التطبيق على المنفذ 3000
. يمكنك اختبار ما إذا كان يعمل عن طريق توجيه متصفحك إلى http://your_server_ip:3000
. يجب أن ترى شيئًا مشابهًا لهذا:
في هذه النقطة، يمكنك بدء جلسة SSH ثانية إلى خادمك لبقية هذا البرنامج التعليمي، متركًا التطبيق الويب الذي بدأته للتو يعمل في الجلسة الأصلية. ستُسمى الجلسة الأولية التي تعمل فيها التطبيق جلسة A. ستظهر أي أوامر في جلسة A على خلفية بلون أزرق داكن مثل هذا:
ستستخدم الجلسة الجديدة من أجل تشغيل الأوامر وتحرير الملفات. ستُسمى هذه الجلسة جلسة B. ستظهر أي أوامر في جلسة B على خلفية بلون أزرق فاتح مثل هذا:
مالم يُشار إلى غير ذلك، ستقوم بتشغيل جميع الأوامر المتبقية في جلسة B.
في هذه الخطوة، قمت بإنشاء التطبيق الأساسي. في الخطوة التالية، ستقوم بتخصيصه.
الخطوة 2 — تخصيص متغيرات التسجيل
بينما التطبيق الافتراضي الذي تم إنشاؤه بواسطة express-generator
هو بداية جيدة، يجب عليك تخصيص التطبيق بحيث يتصل بسجل المعلومات الصحيح عند الحاجة.
express-generator
يتضمن وسيط تسجيل Morgan HTTP والذي ستستخدمه لتسجيل البيانات حول جميع طلبات HTTP. نظرًا لدعم Morgan لتدفقات الإخراج، فإنه يتماشى بشكل جيد مع دعم التدفق المدمج في Winston، مما يتيح لك تجميع سجلات بيانات الطلبات HTTP مع أي شيء آخر تختار تسجيله باستخدام Winston.
يستخدم قالب express-generator
المتغير logger
عند الإشارة إلى حزمة morgan
. نظرًا لأنك ستستخدم morgan
و winston
، وهما حزم تسجيل، يمكن أن يكون من الخلط بينهما أن تسمي أي واحدة منهما logger
. لتحديد المتغير الذي تريده، يمكنك تغيير تصريحات المتغيرات عن طريق تحرير ملف app.js
.
لفتح app.js
للتحرير، استخدم nano
أو محرر النص المفضل لديك:
ابحث عن السطر التالي بالقرب من أعلى الملف:
قم بتغيير اسم المتغير من logger
إلى morgan
:
يحدد هذا التحديث أن المتغير المعلن morgan
سيستدعي طريقة require()
المرتبطة بسجل الطلبات Morgan.
تحتاج إلى العثور على المواضع الأخرى التي تم فيها إشارة إلى المتغير logger
في الملف وتغييره إلى morgan
. كما ستحتاج أيضًا إلى تغيير تنسيق السجل المستخدم بواسطة حزمة morgan
إلى combined
، وهو تنسيق سجل Apache القياسي والذي سيتضمن معلومات مفيدة في السجلات، مثل عنوان IP البعيد ورأس طلب HTTP لوكيل المستخدم.
للقيام بذلك، ابحث عن السطر التالي:
قم بتحديثه إلى التالي:
هذه التغييرات ستساعدك على فهم الحزمة التي تم الإشارة إليها لتسجيل السجلات في أي وقت بعد دمج تكوين Winston.
عند الانتهاء، احفظ وأغلق الملف.
الآن بعد أن تم تهيئة تطبيقك، يمكنك البدء في العمل مع Winston.
الخطوة 3 — تثبيت وتكوين Winston
في هذه الخطوة، ستقوم بتثبيت وتكوين Winston. ستستكشف أيضًا الخيارات التكوينية المتاحة كجزء من حزمة winston
وستنشئ سجلًا لتسجيل المعلومات في ملف والوحدة التحكم.
قم بتثبيت winston
باستخدام الأمر التالي:
من المفيد الاحتفاظ بملفات التكوين الداعمة أو الأدوات لتطبيقاتك في دليل خاص. أنشئ مجلدًا باسم config
الذي سيحتوي على تكوين winston
:
ثم، أنشئ مجلدًا سيحتوي على ملفات السجل:
وأخيرًا، قم بتثبيت app-root-path
:
يعتبر الحزمة app-root-path
مفيدة عند تحديد مسارات في Node.js. على الرغم من أن هذه الحزمة ليست مرتبطة مباشرة بـ Winston، إلا أنها مفيدة عند تحديد مواقع ملفات السجل من جذر المشروع وتجنب بناء الجمل النسبية القبيحة.
الآن بعد أن تم وضع التكوين لمعالجة تسجيل السجلات، يمكنك تحديد إعداداتك. قم بإنشاء وفتح ~/myApp/config/winston.js
للتحرير:
سيحتوي ملف winston.js
على تكوين winston
الخاص بك.
بعد ذلك، أضف الكود التالي لطلب الحزمة app-root-path
و winston
:
مع وجود هذه المتغيرات، يمكنك تحديد إعدادات التكوين للنقل الخاص بك transports. النقل هو مفهوم قدمه Winston يشير إلى آليات التخزين/الإخراج المستخدمة للسجلات. يأتي Winston مع أربعة نقل أساسية مضمنة: Console, File, HTTP, و Stream.
سوف تركز على النقل الخاص بالوحدة الطرفية (console) والنقل الخاص بالملف لهذا البرنامج التعليمي. سيقوم النقل الخاص بالوحدة الطرفية بتسجيل المعلومات في الوحدة الطرفية، وسيقوم النقل الخاص بالملف بتسجيل المعلومات في ملف محدد. يمكن أن تحتوي كل تعريف للنقل على إعدادات التكوين، مثل حجم الملف، ومستويات السجل، وتنسيق السجل.
فيما يلي ملخص سريع للإعدادات التي ستستخدمها لكل نقل:
مستوى
: مستوى الرسائل المراد تسجيلها.اسم_الملف
: الملف المراد استخدامه لكتابة بيانات السجل إليه.التعامل_مع_الاستثناءات
: التقاط وتسجيل الاستثناءات غير المعالجة.الحجم_الأقصى
: الحجم الأقصى لملف السجل، بالبايت، قبل إنشاء ملف جديد.الملفات_الأقصى
: الحد الأقصى لعدد الملفات التي يتم إنشاؤها عند تجاوز حجم ملف السجل.التنسيق
: كيفية تنسيق إخراج السجل.
مستويات التسجيل تشير إلى أولوية الرسالة وتُعرف برقم صحيح. يستخدم Winston npm
مستويات تسجيل تتراوح من 0 إلى 6 (من الأعلى إلى الأدنى):
- 0: خطأ
- 1: تحذير
- 2: معلومات
- 3: http
- 4: مفصل
- 5: تصحيح
- 6: غبي
عند تحديد مستوى تسجيل لنقل معين، سيتم تسجيل أي شيء في هذا المستوى أو أعلى منه. على سبيل المثال، عند تعيين مستوى معلومات
، سيتم تسجيل أي شيء على مستوى خطأ
، تحذير
، أو معلومات
.
يتم تحديد مستويات السجل عند استدعاء المسجل، مما يعني أنه يمكنك تشغيل الأمر التالي لتسجيل خطأ: logger.error('رسالة خطأ الاختبار')
.
لازلت في ملف التكوين، أضف الكود التالي لتعريف إعدادات التكوين لنقلي الملف
و الوحدة النقالة
في تكوين وينستون
:
ثم، قم بإضافة الكود التالي لإنشاء مسجل جديد من نوع winston
مع نقلين (ملف ووحدة تحكم) باستخدام الخصائص المحددة في متغير options
:
بشكل افتراضي، يتم إخراج morgan
إلى وحدة التحكم فقط، لذا ستقوم بتعريف وظيفة تيار تكون قادرة على الحصول على الإخراج الذي تم إنشاؤه بواسطة morgan
في ملفات سجل winston
. ستستخدم مستوى info
لالتقاط الإخراج من قبل كليهما (الملف ووحدة التحكم). أضف الكود التالي إلى ملف التكوين:
أخيرًا، أضف الكود أدناه لتصدير المسجل بحيث يمكن استخدامه في أجزاء أخرى من التطبيق:
سيبدو ملف تكوين winston
الكامل الآن كما يلي:
احفظ وأغلق الملف.
لديك الآن المسجل المكون بشكل صحيح ، ولكن تطبيقك لا يزال غير على دراية به ، أو كيفية استخدامه ، لذا تحتاج إلى دمج المسجل مع التطبيق.
الخطوة 4 — دمج وينستون مع التطبيق
لجعل مسجلك يعمل مع التطبيق ، تحتاج إلى جعل express
على دراية به. رأيت في الخطوة 2 أن تكوين express
الخاص بك يقع في app.js
، لذا يمكنك استيراد مسجلك إلى هذا الملف.
افتح الملف للتحرير:
أضف تعريفًا لمتغير winston
بالقرب من أعلى الملف مع البيانات الأخرى المطلوبة باستخدام الكود التالي:
المكان الأول الذي ستستخدم فيه winston
هو مع morgan
. لا تزال في app.js
، ابحث عن السطر التالي:
قم بتحديثه ليشمل خيار stream
:
هنا، قم بتعيين خيار stream
لواجهة التيار التي قمت بإنشائها كجزء من تكوين winston
.
احفظ وأغلق الملف.
في هذه الخطوة، قمت بتكوين تطبيق Express الخاص بك للعمل مع Winston. في الخطوة التالية، ستقوم بمراجعة بيانات السجل.
الخطوة 5 — الوصول إلى بيانات السجل وتسجيل رسائل السجل المخصصة
الآن بعد تكوين التطبيق، أنت جاهز لرؤية بعض بيانات السجل. في هذه الخطوة، ستقوم بمراجعة إدخالات السجل وتحديث إعداداتك برسالة سجل مخصصة عينية.
إذا قمت بإعادة تحميل الصفحة في متصفح الويب، يجب أن ترى شيئًا مماثلًا للإخراج التالي في وحدة التحكم لجلسة SSH A:
Output[nodemon] restarting due to changes...
[nodemon] starting `node bin/www`
info: ::1 - - [25/Apr/2022:18:10:55 +0000] "GET / HTTP/1.1" 200 170 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"
info: ::1 - - [25/Apr/2022:18:10:55 +0000] "GET /stylesheets/style.css HTTP/1.1" 304 - "http://localhost:3000/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"
هناك اثنتان من إدخالات السجل هنا: الأولى للطلب إلى الصفحة HTML؛ الثانية للنمط المرتبط. نظرًا لأن كل نقل مكون لمعالجة بيانات السجل على مستوى info
، يجب أن ترى أيضًا معلومات مماثلة في النقل الموجود في الملف الموجود في المسار ~/myApp/logs/app.log
.
لعرض محتويات ملف السجل، قم بتشغيل الأمر التالي:
tail
سيقوم بإخراج أجزاء الملف الأخيرة في الطرفية الخاصة بك.
يجب أن ترى شيئًا مشابهًا للتالي:
{"level":"info","message":"::1 - - [25/Apr/2022:18:10:55 +0000] \"GET / HTTP/1.1\" 304 - \"-\" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36\"\n","timestamp":"2022-04-25T18:10:55.573Z"}
{"level":"info","message":"::1 - - [25/Apr/2022:18:10:55 +0000] \"GET /stylesheets/style.css HTTP/1.1\" 304 - \"http://localhost:3000/\" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36\"\n","timestamp":"2022-04-25T18:10:55.588Z"}
سيتم كتابة الإخراج في ملف النقل ككائن JSON نظرًا لاستخدامك winston.format.json()
في خيار format
لتكوين نقل الملف. يمكنك معرفة المزيد عن JSON في مقدمة لـ JSON.
حتى الآن، يقوم المسجل الخاص بك بتسجيل طلبات HTTP والبيانات ذات الصلة فقط. هذه المعلومات ضرورية لوجودها في السجلات الخاصة بك.
في المستقبل، قد ترغب في تسجيل رسائل سجل مخصصة، مثل تسجيل الأخطاء أو تحليل أداء استعلام قاعدة البيانات. كمثال، ستقوم باستدعاء المسجل من مسار معالج الأخطاء. بشكل افتراضي، يتضمن حزمة express-generator
بالفعل مسار معالج الأخطاء 404
و 500
، لذا ستعمل مع ذلك.
افتح ملف ~/myApp/app.js
:
ابحث عن كتلة الشيفرة في الجزء السفلي من الملف التي تبدو مثل هذا:
هذا القسم هو مسار معالج الأخطاء النهائي الذي سيرسل في نهاية المطاف استجابة خطأ إلى العميل. نظرًا لأن جميع أخطاء الخادم ستمر عبر هذا المسار، فمن المكان الجيد لتضمين مسجل winston
.
لأنك الآن تتعامل مع الأخطاء، ترغب في استخدام مستوى تسجيل السجل error
. تم تكوين كل من وسائل النقل لتسجيل رسائل مستوى error
، لذا يجب أن ترى الإخراج في سجلات الملف والوحدة التحكم.
يمكنك تضمين أي شيء تريده في السجل، بما في ذلك المعلومات مثل:
err.status
: رمز حالة الخطأ HTTP. إذا لم يكن هناك رمز موجود بالفعل، فالافتراضي هو500
.err.message
: تفاصيل الخطأ.req.originalUrl
: عنوان URL الذي تم طلبه.req.path
: جزء المسار من عنوان URL الطلب.req.method
: طريقة HTTP للطلب (GET، POST، PUT، إلخ.).req.ip
: عنوان IP البعيد للطلب.
قم بتحديث مسار المعالجة الخاص بالأخطاء لتضمين تسجيل السجل winston
:
احفظ وأغلق الملف.
للاختبار هذه العملية، حاول الوصول إلى صفحة غير موجودة في مشروعك. سيؤدي الوصول إلى صفحة غير موجودة إلى إثارة خطأ 404. في متصفح الويب الخاص بك، حاول تحميل العنوان URL التالي: http://عنوان_خادمك_IP:3000/foo
. بفضل القالب الذي أنشأه express-generator
، تم تهيئة التطبيق للرد على مثل هذا الخطأ.
سيعرض متصفحك رسالة خطأ مثل هذه:
عندما تلقي نظرة على الوحدة النمطية في جلسة SSH A، يجب أن تكون هناك إدخالات سجل للخطأ. بفضل تطبيق تنسيق colorize
، يجب أن يكون من السهل رؤيته:
Output[nodemon] starting `node bin/www`
error: 404 - Not Found - /foo - GET - ::1
info: ::1 - - [25/Apr/2022:18:08:33 +0000] "GET /foo HTTP/1.1" 404 982 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"
info: ::1 - - [25/Apr/2022:18:08:33 +0000] "GET /stylesheets/style.css HTTP/1.1" 304 - "http://localhost:3000/foo" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"
أما بالنسبة للمسجل الملفي، يجب أن يظهر لك تشغيل الأمر tail
مرة أخرى السجلات الجديدة:
سترى رسالة مثل الآتي:
{"level":"error","message":"404 - Not Found - /foo - GET - ::1","timestamp":"2022-04-25T18:08:33.508Z"}
تتضمن رسالة الخطأ جميع البيانات التي أوجدت بشكل خاص winston
لتسجيلها كجزء من معالج الأخطاء. ستشمل هذه المعلومات حالة الخطأ (404 – غير موجود)، وعنوان URL المطلوب (localhost/foo
)، وطريقة الطلب (GET
)، وعنوان IP الذي قام بالطلب، والطابع الزمني للطلب.
الاستنتاج
في هذا البرنامج التعليمي، قمت ببناء تطبيق ويب بسيط بواسطة Node.js وقمت بدمج حلاً للسجلات باستخدام Winston الذي سيكون أداة فعالة لتوفير رؤية في أداء التطبيق.
يمكنك القيام بالمزيد لبناء حلول تسجيل قوية لتطبيقاتك، وخاصة عندما تصبح احتياجاتك أكثر تعقيدًا. لمعرفة المزيد حول وسائل النقل في Winston، انظر وثائق وسائل النقل في Winston. لإنشاء وسائل نقل مخصصة، انظر إضافة وسائل نقل مخصصة. لإنشاء نقطة نهاية HTTP للاستخدام مع نقل HTTP الأساسي، انظر winstond
. لاستخدام Winston كأداة للتحليل، انظر التحليل.