معمولا برای یادگیریِ لاگ گرفتن یا همان Logging زمان زیادی صرف نمیکنیم. چون یک console.log نوشتن، آنقدرها هم سخت نیست. شاید اگر بخواهید جاوا اسکریپت یاد بگیرید، اولین چیزی که از این زبان عجیب ببینید، یک لاگ ساده باشد:
console.log('Hello World!');
اما حقیقت این است که وقتی اپلیکیشنتان بزرگ و بزرگتر میشود، این console.log ساده و جذاب تبدیل به ابزاری ناکارآمد میشود که لازم میشود فکری به حالش کنیم.
فرض کنید تابعی نوشتید که درست کار نمیکند یا همان به قول اهل فن، باگ دارد. شاید اولین قدمی که برای حل مشکل یا همان دیباگ کردن این تابع برداریم، لاگ گرفتن از تکتک ورودیها و خروجی این تابع است. شاید آن وسطها هم لاگهای دیگری قرار دهیم تا بهتر متوجه شویم که برنامهیمان چگونه پیشروی میکند و یا باز به قول اهل فن، flow برنامه را مشاهده کنیم.
خب، لاگها را نوشتیم. تا به اینجا همه چیز خوب است، باگ را هم یافتیم و همه چیز به خیر و خوشی تمام شد. حالا با این همه عبارت console.log چه کنیم؟ اضافه و دست و پا گیر هستند. پاکشان میکنیم و میرویم سراغ قابلیت یا حتی باگ بعدی. برای حل این باگ، نیاز است که دوباره با flow برنامه آشنا شویم و ببینیم که بدنهی if اجرا میشود یا else؟ آن تابعی که پیش از این دیباگش کردیم، چه خروجی میدهد؟ ۵ یا ۱۵؟ در این حالت، مجبوریم دوباره چند console.log بنویسیم. شاید همانهایی که چند لحظهی پیش پاکشان کردیم.
حالا فرض کنید اپلیکیشن را نوشتیم و قرار است روی سرور مستقر کنیم تا کاربرهایمان از این اَپ فوقالعاده استفاده کنند. چگونه مطمئن میشویم همه چیز درست کار میکند؟ همهی سرویسها اجرا شدهاند و برنامهی ما هم به سرویسهای مورد نظر با موفقیت وصل شده است؟ از کجا متوجه میشویم که چه زمانی خطایی رخ داد؟ در کجا؟ وقتی خطا رخ داد، تابعمان چه چیزی را ورودی گرفته بود؟
اگر به این پاراگراف رسیدید، فرض میکنم Logging برایتان مهم است و نمیخواهید با صورت سرخ شدهی مدیرتان، وقتی که در حال پرس و جو از مشتری هستید که دقیقا چه چیزا را وارد کرد که به خطا خورد، مواجه شدید، در ادامه با من همراه باشید.
یکی از دلایلی که لاگهایمان را پاک میکنیم، برای این است که خروجی واضحتری داشته باشیم. وقتی تعداد لاگها زیاد باشد و هر لاگ هم اطلاعات زیادی را در صفحه، نمایش دهد، عملا نمیتوانیم لاگ مورد نظرمان را به خوبی ببینیم و این همه لاگ، اذیت کننده خواهند بود.
استفاده از console.log راه حل خوبی برای لاگ گرفتن نیست. چون تنظیماتی ندارد که بخواهید در شرایط مختلف لاگ را کنترل کنید. یا شاید لازم باشد که لاگها را به سرویسهایی که آنها را ذخیره و دستهبندی میکنند ارسال کنید. console.log هیچکدام از این قابلیتها را ندارد.
با افتخار، معرفی میکنم: پکیج Winston، ابزاری حرفهای با قابلیتهایی که تمام ضعفهای console.log را میپوشاند. Winston معروفترین پکیج Logging برای Node.js است که به برخی از قابلیتهایش اشاره میکنم:
وینستون با دستور زیر نصب میشود:
npm install winston
حالا فقط کافیست هر جایی که لازم دارید، آن را وارد کنید و لاگ بگیرید:
const winston = require('winston'); winston.info('Hello World!');
و شاید هم لازم داشته باشید وینستون را تنظیم کنید که لاگها را به فایل خاصی انتقال دهد:
winston.configure({ transports: [ new (winston.transports.File)({ filename: 'myLogs.log' }), ] });
همانطور که میبینید، transports در واقع یک آرایه است، یعنی میتوانید همزمان به مقاصد مختلف لاگها را هدایت کنید. شاید بخواهید همزمان علاوه بر اینکه لاگها را داخل فایلی ذخیره میکنید، آنها را به سرویسهای Sentry.io و یا Loggly.com هم هدایت کنید.
حتما میپرسید که وینستون چطور میخواهد لاگها را مدیریت کند؟ وقتی قرار است هیچ لاگی را پاک نکنیم، چون بعدها به درد خواهند خورد.
وینستون با استفاده از استانداری که در RFC5424 تعریف شده است، از شما میخواهد که لاگها را در سطوح مختلی قرار دهید. بعدا، میتوانید بخواهید که کدام سطح را هنگام نمایش لاگها، نمایش دهد. در واقع، ما از ۶ سطح مختلف صحبت میکنیم:
توجه داشته باشید که وینستون، بهجای warning از verbose و به جای trace از عبارت silly استفاده میکند. هر چند که میتوانید حتی سطوح خودتان را هم تعریف کنید.
با استفاده از وینستون، در شرایط مختلف میتوانید، یک لاگ در سطح مورد نظرتان ایجاد کنید:
winston.error('An error occurred'); winston.info('Connected to database.');
و حالا خیلی راحت، میتوانید از وینستون بخواهید که لاگهای کدام سطح را نمایش دهد:
winston.level = 'warning';
وقتی یک سطح یا level را تعیین میکنید، وینستون سعی میکند تمام لاگهای آن سطح و بالاتر از آن را نمایش دهد. مثلا در نمونهی بالا، چون سطح را روی warning تنظیم کردیم، تمام لاگهای مرتبط با warning و error و fatal نمایش داده خواهند شد.
با استفاده از این پکیج و تنظیم کردن آن، کارهای مختلفی میتوانید انجام دهید. حتی میتوانید از وینستون بخواهید که لاگها را در فرمت JSON خروجی دهد و یا برای نمونه، خطاها را به رنگ قرمز نمایش دهد.
بخشهایی از این نوشته، با ترجمهی Node Logging Basics شکل گرفته است.