آشنایی با مفهوم Structured Logging در توسعهٔ نرم‌افزار

آشنایی با مفهوم Structured Logging در توسعهٔ نرم‌افزار

پیشرفت روزافزون تکنولوژی به‌ تدریج زحمت انسان‌ها را کمتر و کمتر کرده اما بعضی از کارکردهای انسان را تحت هیچ شرایطی نمی‌توان از تکنولوژی انتظار داشت به گونه‌ای که مثلاً هوش‌ مصنوعی در عالی‌ترین سطح پیشرفت هم نمی‌تواند با هوش بشر در یک سطح قرار بگیرد و یکی از مصادیق این تفاوت، توانایی آینده‌نگری بشر است. اگر دولوپر برای محصول خود آینده‌نگری نکند، حتی اگر تولیدکنندۀ پیشرفته‌ترین نرم‌افزار قابل‌تصور هم باشد، همان محصول می‌تواند سبب نابودی خود و همچنین ایجاد انواع هزینه‌ها، اعم از مادی و معنوی، برای دولوپرش شود و از همین روی، به منظور جلوگیری از بروز انواع مشکلاتی که ممکن است در غیاب آینده‌نگری برای دولوپر پیش بیاید، وی می‌بایست در پروسۀ توسعه، تست و در نهایت دیپلوی محصول خود به ریزترین و دقیق‌ترین موارد توجه کند و این مهم به‌ دست نمی‌آید مگر با ثبت دقیق و جزئی‌نگرانۀ تمام اقداماتی که در تولید محصول صورت می‌گیرد که اصطلاحاً تحت‌ عنوان Structured Logging شناخته می‌شود.

اولین کسی باشید که به این سؤال پاسخ می‌دهید

چگونه لاگ‌های پروژه را به‌ صورت منظم ثبت کنیم؟
بدون شک ثبت لاگ‌های پروژه به ساده‌سازی موضوعات مهمی مثل دیباگینگ، تحلیل و مانیتورینگ پروژه کمک می‌کند. در گذشته تصور می‌شد که ثبت لاگ‌ها فقط برای اپلیکیشن‌هایی مناسب است که در آن‌ها رابط کاربری وجود ندارد و از طریق کامندلاین اجرا می‌شوند؛ به‌ علاوه اینکه دولوپرهای حرفه‌ای از لاگ‌های سیستم برای بهبود آن و همچنین ایجاد یک #تجربهٔ کاربری بهتر استفاده می‌کنند.

در واقع، فقط زمانی که نرم‌افزار به مرحلۀ نهایی رسیده و به شکل محصول درآمده، دولوپر نسبت به گزارش عملکرد (مثلاً در رابطه با بروز Stack Trace) دقت می‌کند. گاهی اوقات هم دولوپر بلافاصله متوجه می‌شود که اِشکال کار در کجا است اما در اغلب موارد دولوپر از ترتیب اتفاقاتی که منجر به ایجاد آن اِشکال شده آگاهی ندارد و این ناآگاهی باعث می‌شود تا دولوپر بالاجبار کار خود را برای پیدا کردن مشکل بر مبنای حدس و گمان، کشف و جستجو به‌ پیش ببرد که این مستلزم صرف زمان زیادی است (Stack Trace که تحت عناوین دیگری همچون Stack Backtrace و یا Stack Traceback نیز شناخته می‌شود، خلاصه‌ای از روندی می‌باشد که نرم‌افزاری پیموده تا به نقطهٔ فعلی رسیده است.)

آشنایی با مفهوم Structured Logging
بدون شک لاگ‌گیری به‌ صورت کامل تنها برای تشخیص اِشکالات پروژ‌ه‌های نرم‌افزاری کاربرد ندارد چرا که چنانچه این کار به‌ صورت دقیق انجام شود، می‌تواند به تحلیل تجاری محصول هم کمک کند (مثلاً نحوۀ کار کردن با سیستم را توضیح دهد یا می‌تواند برای مانیتورینگ پروژه مفید واقع گردد. به‌ عنوان مثالی دیگر هم می‌توان گفت که این امکان را فراهم می‌کند تا دولوپر بفهمد چه نوع عملکردهایی در تولید نرم‌افزار مورد استفاده قرار گرفته است.) یک تیم متشکل از دولوپرهای حرفه‌ای، حتماً به صورت خودکار مسئولیت انجام توسعه، تست و مانیتورینگ را برای نرم‌افزارهایی که کدنویسی می‌کند بر عهده می‌گیرد اما طراحی و به‌کارگیری یک سیستم لاگینگ کاربردی و مؤثر، انجام این وظایف را برای تیم توسعهٔ نرم‌افزار و یا شخص دولوپر، به شکل چشمگیری ساده‌تر و راحت‌تر می‌کند.

Structured Logging واقعاً چه‌ کاری برای دولوپرها انجام می‌دهد؟
تصور غالب این است که پشتیبانی از محصول تولیدشده نسبت به اضافه کردن آپشن‌ها و امکانات جدید برای محصول، از اهمیت بسیار کمتری برخوردار می‌باشد اما واقعیت امر آن است که اگر پشتیبانی به‌ درستی انجام شود، همیشه می‌توان امکانات جدید را به‌ سادگی هرچه تمام‌تر به محصول اضافه نمود که همین مسئله منجر به بهبود کیفیت نرم‌افزار می‌شود. به‌ عبارت دیگر، آنچه باعث بقای محصول می‌شود، پشتیبانی کافی و آن‌ هم به حرفه‌ای‌ترین شکل ممکن است به طوری که تجربه نشان داده است که به‌ مرور و با گذشت زمان، می‌توان با اضافه کردن امکانات و آپشن‌های مختلف، محصول را عالی‌تر و ارزشمندتر نمود اما این فقط در صورتی است که دولوپرها لاگ‌های پروژه را به‌ صورت دائمی و منظم در جایی ثبت کرده باشند (در ارتباط با بهتر شدن کیفیت نرم‌افزار به مرور زمان می‌توانید به مقالهٔ آیا شباهت‌هایی مابین تهیهٔ قورمه‌سبزی و توسعهٔ نرم‌افزار وجود دارد؟ مراجعه نمایید.)

Structured Logging چه پرسش‌هایی را پاسخگو خواهد بود؟
حال در ادامه پرسش‌هایی را می‌بینید که با به‌کارگیری سیستم لاگینگ، پاسخگویی به آن‌ها بسیار ساده می‌شود (البته در صورتی که این سیستم از اولین لحظۀ شروع پروژه، به‌ کار گرفته شود):

- چه اشکالی باعث بروز Stack Trace شده است؟
- چه سلسله اتفاقاتی باعث شده است که دستوری که به نرم‌افزار داده شده است به‌ صورت ناگهانی اجرا نشود؟
- کاربران محصول تولیدشده چه کسانی هستند؟
- نظر کاربران بعد از استفادۀ طولانی‌مدت از محصول چیست؟
- کاربران محصول تولیدشده را برای انجام چه کاری مورد استفاده قرار می‌دهند؟ 
- چقدر زمان لازم است که نرم‌افزار دستور صادر شده را پردازش کند؟
- چه میزان حافظۀ آزاد در نرم‌افزار موجود است؟

ملاحظات عملی
انفجار اطلاعاتی عظیمی در صنعت توسعهٔ نرم‌افزار در حال رخ دادن است و همچنین رشد فزاینده و فوق‌العاده‌ای در زیرساخت‌های صنایع سیستمی ایجاد شده است و در چنین شرایطی، کسب توانایی برای کشف ایرادات و ارتباط‌ احتمالی میان اطلاعاتی که از سیستم‌های مختلف به‌ دست می‌آید، ضرورتی به نظر می‌رسد. در همین راستا، سیستم لاگ‌گیری نرم‌افزاری ما می‌بایست شرایطی را فراهم کند که دولوپر توانایی پیگیری و مانیتورینگ عملکردِ تعداد بالایی کاربر که با دیوایس‌های مختلفی سیستم‌مان را مورد استفاده قرار می‌دهند به‌ دست آورد که این توانایی در صورتی حاصل می‌شود که یک سیستم لاگ‌گیری استاندارد و دقیق به‌ کار گرفته شده باشد.

حال سؤال اینجا است که فرمت مناسب ثبت لاگ‌های سیستم چیست؟ به‌ عبارتی، فرمتی که برای انسان و ماشین قابل‌درک باشد. به طور کلی، گزینه‌های مختلفی برای انجام این کار وجود دارد که از آن جمله می‌توان ثبت لاگ‌ها در قالب فایل‌های XML، ثبت در فایل‌های متنی و یا دیتابیس اشاره کرد؛ اما معروف‌ترین و شناخته‌شده‌ترین فرمت، JSON است (گرچه یکسری ابزارها همچون Logstash وجود دارند که فرمت‌های مختلف را به جیسون تبدیل می‌کنند، اما بهتر آن است که در همان وهلهٔ اول، لاگ‌ها را در قالب جیسون ذخیره ساخت.)

چه مواردی باید در لاگ ثبت شوند؟
لایبرری‌های استاندارد برای لاگ‌گیری مانند SLF4J، حاوی اطلاعات مفصل و مفیدی هستند که از آن جمله می‌توان به مواردی زیر اشاره نمود:

- Timestamp
- PID
- Thread
- Level 
- Loggername 

در صورتی‌ که بخواهیم امکان دستیابی چندگانه و مانیتورینگ چندین سیستم و دیوایس را به‌ صورت هم‌زمان به‌ دست آوریم، نیاز به ایجاد یک توکن برای شناسایی عملکرد نرم‌افزار داریم که معمولاً تحت‌عنوان Request ID  یا Transaction ID نامیده می‌شود که چنین توکنی این امکان را برای ابزار لاگ‌گیری فراهم می‌کند تا فقط روند اتفاقات و جزئیاتی را که به یک دستور خاص مرتبط هستند استخراج کرده و نمایش دهد و این در حالی می‌باشد که ممکن است این اطلاعات از چندین سیستم و دیوایس مختلف در مورد آن موضوع خاص استخراج شود.

سطوح استاندارد لاگ‌گیری
اجزاء مختلف یک سیستم می‌بایست با سطح لاگینگ که مورد استفاده قرار می‌گیرد، سازگار باشد که در ادامه مواردی را به‌ صورت پیشنهادی ملاحظه می‌کنید که به شما برای تشخیص سطح مناسب برای استفاده در هر مرحله از پروژه کمک می‌کنند:

- Error: از این سطح برای ایرادات غیرقابل پیش‌بینی استفاده می‌شود (به‌ عنوان مثال، قطع شدن کانکشن، ایرادات منطقی و یا کانفیگ اشتباه)

- Warning: از این سطح برای ایرادات قابل‌پیش‌بینی استفاده می‌شود (به‌ عنوان مثال، بروز مشکل در احراز هویت کاربر)

- Info: هر اطلاعاتی که در رابطه با تحلیل تجاری محصول است به‌ علاوهٔ اطلاعات لازم برای دیباگینگ و مانیتورینگ در این سطح ثبت می‌شوند (به‌ عنوان مثال، انجام شدن درخواست کاربر، اِسنپ‌شات‌هایی از میزان استفاده از ریسورس‌های سرور یا اطلاعات مربوط به زمانبندی)

- Debug: از این سطح برای چیزهایی که باید در دیدرس دولوپر باشد استفاده می‌شود (به‌ عنوان مثال، ورود به لایه‌های مختلف ساخت نرم‌افزار با استفاده از پارامترهای مختلف که فقط دولوپر به‌ آن‌ها دسترسی دارد)

- Trace: این سطح برای چیزهایی که ممکن است دولوپر به‌ صورت موقت مورد استفاده قرار دهد به‌ کار گرفته می‌شود (به‌ عنوان مثال، دامپ دیتا)

به طور کلی، انواع مختلفی از ابزارها برای لاگ‌گیری و تحلیل لاگ‌های سیستم وجود دارد که از آن جمله‌ می‌توان به موارد زیر اشاره کرد و لازم به ذکر است که اکثر این ابزارها می‌توانند برای ثبت/جستجوی لاگ‌ها در فرمت JSON مورد استفاده قرار بگیرند:

- Graylog
- (Elasticsearch/Logstash/Kibana (ELK
- Loggly  
- Splunk

فرقی نمی‌کند که از چه اصول، فرمت و ابزاری برای ثبت لاگ‌های نرم‌افزار خود استفاده کنیم؛ بلکه مهم آن است که این‌ کار را به بهترین شکل ممکن انجام داده تا به گنجینهٔ ارزشمندی از دیتای مرتبط با فرایندهای صورت گرفته در پشت‌پردهٔ نرم‌‌افزاری که توسعه داده‌ایم دست یابیم و از آن‌ها در جهت دیباگینگ، تحلیل، مانیتورینگ و در نهایت بهبود کیفیت نرم‌افزار خود استفاده نماییم.

منبع