تحقیق درباره شکست با لاگهای ساختیافته journal
پیشنیاز، پروژه پاکسازینشده درس قبل، متغیرهای labdir و unit در همان ترمینال، و دسترسی به journal کاربر است. اگر پروژه حذف شده، آزمایشگاه قبل را تکرار کنید. در ترمینال تازه مقادیر ثبتشده را دقیق بازگردانید؛ نام حدسی ندهید. اگر test زیر موفق نبود، ادامه ندهید. شکست عمدی و فایل fail درس قبل شواهد اولیهاند. تألیف: تحریریه درسآوند.
test -n "$labdir" && test -d "$labdir" && test -n "$unit"
systemctl --user show "$unit" -p ActiveState -p Result -p ExecMainStatusjournal فقط یک فایل متنی بلند نیست. هر رکورد، MESSAGE و فیلدهایی مانند PRIORITY، _UID، _PID و _SYSTEMD_USER_UNIT دارد؛ journald بخشی از فراداده را از محیط اجرای فرایند میگیرد. فیلتر ساختیافته دامنه بررسی را محدود میکند؛ همه رکوردها همه فیلدها را ندارند. مقدار ExecMainStatus=7 در این مثال با قرارداد worker سازگار است؛ در برنامه واقعی باید معنای کد را از مستندات همان برنامه گرفت.
journalctl --user -u "$unit" --since "10 minutes ago" --no-pager -o short-iso
journalctl --user -u "$unit" -n 5 --no-pager -o verboseshort-iso توالی و verbose ساختار رکورد را نشان میدهد. انتظار داریم planned failure و تلاشهای دوباره را ببینیم؛ متن دقیق وابسته به نسخه است. در verbose مقدار PRIORITY=3 را کنار پیام شکست پیدا کنید و نام _SYSTEMD_USER_UNIT را با unit خود مقایسه کنید. فیلتر -u همراه --user برای سرویس کاربری است؛ استفاده از -u در فضای سیستم ممکن است نتیجه دلخواه این آزمایش را ندهد.
اگر -- No entries -- دیدید، نتیجه نگیرید سرویس هیچ پیام نداده است. نام unit، بازه زمان، ساعت ماشین و مجوز دسترسی را بررسی کنید؛ --user به journal پایدار و تنظیم مناسب دسترسی کاربر وابسته است. محیط محدود یا نگهداری فقط در حافظه میتواند این آزمایش را ناممکن کند. در چنین محیطی صرفاً برای ادامه تمرین به گروههای پرامتیاز اضافه نشوید یا پیکربندی سراسری را تغییر ندهید؛ ماشین آزمایشی از پیش آمادهشده انتخاب کنید. خروجی status نیز همیشه جای تاریخچه کامل journal را نمیگیرد.
journalctl --user -u "$unit" --since "10 minutes ago" -p err --no-pager
journalctl --user -u "$unit" --since "10 minutes ago" PRIORITY=3 --no-pagerفرمان اول err و سطوح شدیدتر، یعنی اولویتهای صفر تا سه را نشان میدهد؛ فرمان دوم فقط مقدار دقیق سه را میخواهد. عدد کوچکتر شدیدتر است. در برنامه این دوره پیشوند <3> با SyslogLevelPrefix=yes سطح خطا را تعیین کرده است؛ صرف وجود واژه error در MESSAGE سطح را عوض نمیکند. پس از یافتن خطا، دوباره خروجی بدون فیلتر اولویت را بخوانید تا رخدادهای عادی قبل از شکست حذف نشوند.
در گزارش، زمان و unit، مشاهده، فرضیه و آزمون اصلاح را ثبت کنید. اینجا مشاهده پیام fail file exists و خروج ۷ است؛ فرضیه این است که نشانگر عمداً ایجادشده برنامه را متوقف کرده است. رسیدن به start-limit-hit پیامد تکرار شکست است، نه نخستین علت. پاک کردن شمارنده پیش از ثبت شواهد میتواند بررسی را گیج کند. پس از خواندن شواهد، نشانگر را حذف و فقط وضعیت همان unit را بازنشانی میکنیم.
rm -- "$labdir/fail"
systemctl --user reset-failed "$unit"
systemctl --user start "$unit"
systemctl --user status "$unit" --no-pager
journalctl --user -u "$unit" --since "1 minute ago" --no-pagerانتظار داریم اجرای تازه active شود و heartbeat دوباره ثبت شود. مشاهده heartbeat تأیید بیشتری از موفقیت start میدهد؛ در برنامه واقعی آزمون آمادگی لازم است. reset-failed وضعیت شکست و شمارنده محدودیت آغاز را پاک میکند؛ داده journal را پاک نمیکند. تمرین: چرا پس از این اصلاح، جستوجوی ده دقیقه اخیر هنوز خطا نشان میدهد؟ پاسخ: journal تاریخچه رخدادهاست؛ خطای قبلی شاهد رخداد گذشته است و معیار سلامت جاری باید زمان اجرای جدید را هم لحاظ کند.
نگهداری لاگ با دوام قطعی آن تفاوت دارد. Storage=volatile داده را زیر /run نگه میدارد و معمولاً با راهاندازی مجدد از بین میرود؛ persistent زیر /var را ترجیح میدهد، اما ممکن است موقتاً به حافظه برگردد. محدودیت حجم، زمان نگهداری و نرخ پیامها نیز میتواند باعث حذف یا نپذیرفتن رکوردها شود. نمایش پیام، دوام در برابر قطع برق را تضمین نمیکند؛ journal محلی جای آرشیو مستقل را نمیگیرد.
journalctl --user --disk-usage
journalctl --user --list-boots --no-pagerاین فرمانها مصرف فایلهای قابل دسترس و بوتهای دارای شواهد را نشان میدهند. نبود بوت قبلی علت را ثابت نمیکند. پیش از اشتراک خروجی، توکن و آرگومان حساس را بررسی کنید. برای پایان، سرویس و پیوندش را حذف میکنیم؛ journal پاک نمیشود و خطاهای گذشته طبق سیاست عادی سیستم باقی میمانند.
systemctl --user disable --now "$unit"
rm -- "$labdir/worker.sh" "$labdir/$unit"
rmdir -- "$labdir"
systemctl --user daemon-reload
unset labdir unitمنابع رسمی انگلیسی:
journalctl filters: https://www.freedesktop.org/software/systemd/man/latest/journalctl.html
Journal fields: https://www.freedesktop.org/software/systemd/man/latest/systemd.journal-fields.html
Journal collection and access: https://www.freedesktop.org/software/systemd/man/latest/systemd-journald.service.html
Journal storage and retention: https://www.freedesktop.org/software/systemd/man/latest/journald.conf.html
Log level prefixes: https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html
متن درسهای عمومی را بدون ورود بخوانید.