راهنمای هوشمند لاگگیری در Rocky Linux
این سند برای مهندسان زیرساختی نوشته شده که میخواهند بهجای حفظ کردن دهها دستور، مستقیماً فکرشان را به دستور تبدیل کنند. اگر تا حالا شده ساعت ۱۱ شب کسی بپرسد «سرویس Nginx از ۳ تا ۵ چرا قطع بوده؟» و شما بدانید چه میخواهید ولی ندانید چه تایپ کنید، این راهنما برای شماست.
مشکل کجاست؟
بین «آنچه در ذهنتان است» و «آنچه باید تایپ کنید» یک درهی عمیق وجود دارد. مسئله معمولاً ندانستن journalctl یا grep نیست؛ مسئله این است که نمیدانید سؤال ذهنیتان را چطور به یک دستور دقیق تبدیل کنید.
مسئله فقط پیدا کردن یک دستور نیست. باید بدانید برای پاسخ به یک سؤال مشخص، کدام لاگ را بررسی کنید، چه بازهای را انتخاب کنید و چه اطلاعاتی را از میان حجم زیاد خروجی استخراج کنید.
این راهنما چه چیزی را تغییر میدهد؟
بهجای حفظ کردن دستورات، الگوی زیر را یاد میگیرید:
سؤال ذهنی → منبع لاگ → فیلتر مناسب → دستور لینوکس → نتیجه
وقتی این الگو را درونی کنید، برای هر مشکل جدید کافی است سؤال درست را بسازید و مرحلهبهمرحله به دستور تبدیلش کنید. این سند نقش یک مترجم ذهنی را بازی میکند — نه دیکشنریای که حفظ کنید، بلکه روشی برای فکر کردن که دیگر دستور را فراموش نکنید.
صحنه اول: «لاگ Nginx رو از ساعت ۳ تا ۵ بده»
بیایید همان سناریوی واقعی را قدمبهقدم حل کنیم — نه با حفظ کردن دستور، بلکه با تکهتکه کردن فکر و ترجمهی هر تکه.
تکنیک Chunking (تکهسازی ذهنی)
مغز انسان نمیتواند یک رشتهی طولانی از کاراکترها را یکجا نگه دارد. اما اگر آن را به تکههای معنادار بشکنید، هر تکه مثل یک کلمهی آشنا میشود. این همان تکنیک Chunking در روانشناسی شناختی است.
فکر شما چهار کلمه است و هر کلمه دقیقاً یک تکه از دستور میشود:
| فکر شما (فارسی) | بخش دستور (لینوکس) | معنی |
|---|---|---|
| لاگ | journalctl | ابزار مشاهدهی لاگهای systemd |
| Nginx | -u nginx | فیلتر بر اساس نام سرویس |
| از ساعت ۳ | --since "15:00" | شروع بازهی زمانی |
| تا ساعت ۵ | --until "17:00" | پایان بازهی زمانی |
نتیجهی نهایی، دقیقاً همان چیزی است که در ذهنتان بود:
journalctl -u nginx --since "15:00" --until "17:00"
این مثل سفارش غذاست. نمیگویید «آن ترکیب شیمیایی نان و پنیر و سبزیجات را با حرارت ۲۰۰ درجه به مدت ۱۲ دقیقه آماده کنید.» میگویید: «یه پیتزا سبزیجات بده.» لاگگیری هم همین است — کافیست تکههای منو (تکههای دستور) را بشناسید.
تمرین ذهنی — همین الان امتحان کنید
قبل از رفتن به بخش بعد، این سناریو را در ذهنتان حل کنید:
«لاگ سرویس SSH رو از دیروز تا الان بده»
| فکر | دستور |
|---|---|
| لاگ | journalctl |
| SSH | -u sshd |
| از دیروز | --since "yesterday" |
| تا الان | نیازی نیست — پیشفرض «تا الان» است |
journalctl -u sshd --since "yesterday"
اگر توانستید بدون نگاه کردن به جواب این دستور را بسازید، مغزتان دارد مثل ترمینال فکر میکند.
مغزتان را بشناسید — چرا دستورات را فراموش میکنید؟
قبل از ادامه، باید بفهمیم چرا یادگیری دستورات لینوکس سخت است. وقتی دشمن را بشناسید، پیروزی آسانتر است.
سه دشمن حافظهی شما
- بار شناختی: مغز شما فقط ۷±۲ آیتم را همزمان در حافظهی کوتاهمدت نگه میدارد. یک دستور مثل
journalctl -u nginx --since --until -p err -o jsonبیش از ۷ تکه دارد. - نبود اتصال معنایی: وقتی
--sinceرا حفظ میکنید، هیچ اتصال معنایی به فکر «از فلان وقت» ندارد. فقط یک رشتهی حروف است که پاک میشود. - تکرار نشدن: منحنی فراموشی Ebbinghaus نشان میدهد بدون تکرار، ۷۰٪ اطلاعات در ۲۴ ساعت اول پاک میشود.
سه سلاح ما
ما از سه تکنیک روانشناسی شناختی استفاده میکنیم:
| تکنیک | توضیح ساده | کاربرد در لاگگیری |
|---|---|---|
| Chunking | شکستن اطلاعات بزرگ به تکههای کوچک معنادار | هر فکر = یک تکه دستور |
| Mental Model | ساختن نقشهی ذهنی از نحوهی کار سیستم | فهمیدن «لاگ از کجا میآید و کجا میرود» |
| Pattern Recognition | یادگیری الگو به جای حفظ کردن | ۵ الگوی طلایی = ۹۰٪ نیازها |
لاگها کجا هستند؟ — نقشهی ذهنی Rocky Linux
قبل از هر چیز باید بدانید لاگها از کجا میآیند، کجا ذخیره میشوند و چطور به آنها دسترسی پیدا کنید. در Rocky Linux، تمام سرویسها لاگ تولید میکنند و این لاگها در دو مسیر موازی ذخیره میشوند.
قانون طلایی: کجا بگردم؟
این سادهترین قانون است. حفظش کنید:
| فکر شما | کجا بگردید | ابزار |
|---|---|---|
| «لاگ سرویس X رو میخوام» | Journal | journalctl -u X |
| «لاگ فایل مستقیم سرویس رو میخوام» | /var/log/ | cat, grep, tail |
| «لاگ کرنل رو میخوام» | هر دو | dmesg یا journalctl -k |
| «لاگ ورود کاربران رو میخوام» | فایل خاص | last, lastb, lastlog |
| «لاگ امنیتی (audit) رو میخوام» | فایل خاص | ausearch, aureport |
| «لاگ Docker رو میخوام» | Docker engine | docker logs |
تصور کنید شهر شما دو کتابخانه دارد: یکی دیجیتال (Journal) که با موتور جستجو کار میکند، و یکی سنتی (فایلها) که باید خودتان قفسهها را بگردید. بیشتر وقتها کتابخانهی دیجیتال کافی است.
مسیر درست برای پیدا کردن لاگ
لازم نیست مسیر تمام فایلهای لاگ را حفظ کنید. ابتدا مشخص کنید دنبال چه نوع اطلاعاتی هستید: سرویس، کرنل، ورود کاربران یا رویدادهای امنیتی.
اگر سرویس توسط systemd مدیریت میشود، journalctl بهترین نقطهی شروع است؛ چون میتوانید لاگها را بر اساس سرویس، زمان، سطح خطا و حتی PID فیلتر کنید. برای برنامههایی که لاگ اختصاصی دارند، مسیر /var/log/ را بررسی کنید. در خطاهای مربوط به کرنل و سختافزار، dmesg و journalctl -k دید بهتری میدهند.
اصل ماجرا این است: اول نوع لاگ را تشخیص دهید، بعد محل ذخیره و ابزار مناسب را انتخاب کنید.
پنج الگوی طلایی — ۹۰٪ نیازهایتان
تحقیقات نشان میدهد ۹۰ درصد لاگگیریهای روزانهی یک مهندس زیرساخت با فقط ۵ الگو قابل انجام است.
| # | سؤال ذهنی | دستور |
|---|---|---|
| ۱ | «لاگ فلان سرویس رو بده» | journalctl -u نام-سرویس |
| ۲ | «از فلان وقت تا فلان وقت» | journalctl --since "..." --until "..." |
| ۳ | «فقط خطاها / هشدارها» | journalctl -p err |
| ۴ | «لحظهای نشونم بده» | journalctl -f -u نام-سرویس |
| ۵ | «ترکیب موارد بالا» | journalctl -u nginx -p err --since "yesterday" |
فرمول ترکیب الگوها
حالا فرمول کلی را ببینید:
journalctl + [چی؟] + [کی؟] + [چقدر مهم؟] + [چطور نمایش بده؟]
journalctl -u سرویس --since "شروع" --until "پایان" -p سطح -o فرمت
هر بخش اختیاری است. نیازی نیست همه را بنویسید:
# فقط «چی»
journalctl -u nginx
# «چی» + «کی»
journalctl -u nginx --since "today"
# «چی» + «کی» + «چقدر مهم»
journalctl -u nginx --since "today" -p err
# «چی» + «لحظهای»
journalctl -f -u nginx
سطوح اهمیت در systemd از کم به زیاد: debug, info, notice, warning, err, crit, alert, emerg. وقتی -p err میدهید، همهی سطوح بالاتر از err هم شامل میشوند.
جدول ترجمهی کامل: فکر → دستور
این جدول مهمترین بخش این سند است. هر بار فکری در ذهنتان شکل گرفت، اینجا را نگاه کنید.
«چی؟» — نام سرویس
| فکر شما | دستور |
|---|---|
| لاگ Nginx رو بده | journalctl -u nginx |
| لاگ SSH رو بده | journalctl -u sshd |
| لاگ فایروال رو بده | journalctl -u firewalld |
| لاگ Docker رو بده | journalctl -u docker |
| لاگ PostgreSQL رو بده | journalctl -u postgresql |
| لاگ MariaDB/MySQL رو بده | journalctl -u mariadb |
| لاگ Apache رو بده | journalctl -u httpd |
| لاگ Cron رو بده | journalctl -u crond |
| لاگ DNS رو بده | journalctl -u named |
| لاگ NTP/زمان رو بده | journalctl -u chronyd |
| لاگ شبکه رو بده | journalctl -u NetworkManager |
| لاگ ایمیل رو بده | journalctl -u postfix |
| لاگ همه چیز رو بده | journalctl |
| لاگ کرنل رو بده | journalctl -k |
نام سرویس را نمیدانید؟ systemctl list-units --type=service لیست تمام سرویسها را نشان میدهد.
«کی؟» — بازهی زمانی
| فکر شما | دستور |
|---|---|
| از امروز | --since "today" |
| از دیروز | --since "yesterday" |
| یک ساعت اخیر | --since "1 hour ago" |
| ۳۰ دقیقه اخیر | --since "30 min ago" |
| از ساعت ۳ | --since "15:00" |
| از ساعت ۳ تا ۵ | --since "15:00" --until "17:00" |
| تاریخ مشخص | --since "2024-06-15" |
| تاریخ و ساعت مشخص | --since "2024-06-15 09:00" |
| از این بوت | -b |
| از بوت قبلی | -b -1 |
«چقدر مهم؟» — سطح اهمیت
| فکر شما | دستور | توضیح |
|---|---|---|
| فقط بحرانیها | -p crit | سیستم در خطر فروپاشی |
| فقط خطاها | -p err | خطاهای مهم |
| خطاها و بالاتر | -p err | شامل crit, alert, emerg هم میشود |
| فقط هشدارها | -p warning | مشکلات بالقوه |
| همه چیز از هشدار به بالا | -p warning | شامل err, crit, alert, emerg |
«چطور نشون بده؟» — فرمت خروجی
| فکر شما | دستور | توضیح |
|---|---|---|
| معمولی نشون بده | پیشفرض | فرمت استاندارد |
| خلاصه نشون بده | -o short | تاریخ + پیام |
| JSON نشون بده | -o json-pretty | برای پردازش ماشینی |
| بدون برش خط | --no-pager | مناسب pipe کردن |
| آخرین N خط | -n 50 | مثل tail |
| لحظهای نشون بده | -f | مثل tail -f |
| معکوس (جدیدترین اول) | -r | reverse order |
صحنههای واقعی — تمرین عملی
حالا سناریوهای واقعی را با همین روش حل کنیم. هر صحنه یک موقعیت واقعی است که احتمالاً برایتان پیش آمده.
صحنه ۲: «چرا سرور ریاستارت شد؟»
صبح آمدهاید و سرور ریاستارت شده. میخواهید بدانید دیشب چه شده:
# خطاهای بوت قبلی (دیشب)
journalctl -b -1 -p err
# اگه بخوای بدونی کرنل چرا ریاستارت کرده
journalctl -b -1 -k -p err
# تاریخچهی ریاستارتها
last reboot
صحنه ۳: «کی SSH زده به سرور؟»
# لاگینهای موفق امروز
journalctl -u sshd --since "today" | grep "Accepted"
# لاگینهای ناموفق امروز
journalctl -u sshd --since "today" | grep "Failed"
# یا سادهتر: آخرین ورودها
last -10
# لاگینهای ناموفق
lastb -10
# یا از فایل مستقیم
grep "Failed password" /var/log/secure
صحنه ۴: «دیسک پر شده — چرا؟»
# حجم لاگهای journal
journalctl --disk-usage
# حجم فایلهای /var/log
du -sh /var/log/* | sort -rh | head -15
# پاک کردن لاگهای قدیمیتر از ۷ روز
journalctl --vacuum-time=7d
# محدود کردن حجم به ۵۰۰ مگ
journalctl --vacuum-size=500M
# چرخش فوری لاگفایلها
logrotate -f /etc/logrotate.conf
journalctl --vacuum-time و --vacuum-size لاگها را برای همیشه پاک میکنند. قبل از اجرا مطمئن شوید به آنها نیازی ندارید. برای محیطهای production بهتر است ابتدا یک نسخه پشتیبان روی سرور دور بگیرید.
صحنه ۵: «فایروال داره چیزی رو بلاک میکنه»
# لاگ فایروال
journalctl -u firewalld --since "1 hour ago"
# بستههای drop/reject شده در کرنل
journalctl -k --since "1 hour ago" | grep -i "drop\|reject\|block"
# یا مستقیم از dmesg
dmesg -T | grep -i "drop\|reject"
# لاگ fail2ban (IP بن شده؟)
fail2ban-client status
fail2ban-client status sshd
صحنه ۶: «کانتینر Docker کرش کرده»
# لاگ کانتینر (آخرین ۱۰۰ خط)
docker logs web-app --tail 100
# لاگ کانتینر لحظهای
docker logs web-app -f
# لاگ از یه زمان خاص
docker logs web-app --since "1h"
# لاگ سرویس Docker خودش
journalctl -u docker -p err --since "today"
# بررسی وضعیت و دلیل خروج
docker inspect web-app | jq '.[0].State'
صحنه ۷: «سرور کند شده — چی داره منابع رو میخوره؟»
# تمام خطاهای یک ساعت اخیر
journalctl -p err --since "1 hour ago" --no-pager
# خطاهای کرنل (OOM Killer, I/O errors)
dmesg -T | grep -i "oom\|error\|fail\|kill"
# بررسی OOM
journalctl -k | grep -i "oom\|out of memory"
# خطاهای I/O دیسک
dmesg -T | grep -i "i/o error\|read error\|write error"
صحنه ۸: «سرویس بالا نمیاد»
# اول: ببین خود systemctl چی میگه
systemctl status nginx
# دوم: لاگهای اخیر سرویس
journalctl -u nginx -n 50 --no-pager
# سوم: فقط خطاها
journalctl -u nginx -p err -n 20
# چهارم: لاگ خود Nginx
tail -50 /var/log/nginx/error.log
# پنجم: شاید پورت اشغاله؟
ss -tlnp | grep ":80\|:443"
ترتیب این پنج مرحله را حفظ کنید: وضعیت سرویس → لاگ سرویس → خطاهای فیلترشده → لاگ اختصاصی → منابع سیستم. این الگو تقریباً همیشه شما را به ریشهی مشکل میرساند.
فراتر از journalctl — فایلهای کلاسیک
journalctl خیلی قدرتمند است، ولی همهی لاگها آنجا نیستند. بعضی سرویسها فایلهای لاگ جداگانه هم دارند.
نقشهی فایلهای لاگ مهم
| مسیر فایل | چی توش هست | فکر شما |
|---|---|---|
/var/log/messages | لاگ عمومی سیستم | «یه چیز عجیب شده ولی نمیدونم چیه» |
/var/log/pvm/messages | لاگ عمومی PVM | «چه اتفاقی در مجازیساز PVM افتاده» |
/var/log/secure | لاگ احراز هویت (SSH, sudo, login) | «کی لاگین کرده؟» |
/var/log/audit/audit.log | لاگ امنیتی SELinux و audit | «SELinux بلاک کرده؟» |
/var/log/nginx/error.log | خطاهای Nginx | «سایت خطا میده» |
/var/log/nginx/access.log | درخواستهای HTTP | «چند نفر زدن؟ از کجا؟» |
/var/log/cron | اجرای کرونجابها | «کرونجاب اجرا شده یا نه؟» |
/var/log/maillog | لاگ ایمیل (postfix) | «ایمیل رفته یا نه؟» |
/var/log/boot.log | لاگ بوت سیستم | «موقع بوت مشکلی بوده؟» |
/var/log/firewalld | لاگ فایروال | «فایروال چیکار کرده؟» |
/var/log/dnf.log | نصب/آپدیت پکیجها | «چی نصب شده اخیراً؟» |
ابزارهای جستجو در فایل
هر وقت فکر کردید «بگرد توی فایل و فلان کلمه رو پیدا کن»:
# جستجوی ساده
grep "کلمه" /مسیر/فایل
# جستجوی بدون حساسیت به بزرگ/کوچک
grep -i "error" /var/log/messages
# جستجو با نمایش شمارهی خط
grep -n "Failed" /var/log/secure
# جستجو در فایلهای فشرده (.gz)
zgrep "error" /var/log/messages-20240615.gz
# آخرین ۵۰ خط
tail -50 /var/log/messages
# لحظهای دنبال کن
tail -f /var/log/nginx/error.log
# آخرین ۵۰ خط و بعد لحظهای
tail -50f /var/log/secure
grep مثل Ctrl+F در مرورگر است — ولی برای فایلها. tail -f مثل این است که یک دوربین زنده روی فایل بگذارید و هر خط جدید که نوشته شد ببینید.
جستجوی هوشمند — هنر فیلتر کردن
بعضی وقتها لاگها هزاران خط هستند و شما دنبال سوزن در انبار کاه میگردید. اینجاست که ابزارهای فیلتر به کمکتان میآیند.
«فقط خطوطی که فلان کلمه رو دارن»
# فکر: «لاگهایی که کلمه error دارن»
journalctl -u nginx --since "today" | grep "error"
# فکر: «لاگهایی که کلمه error یا fail دارن»
journalctl -u nginx --since "today" | grep -iE "error|fail"
# فکر: «لاگهایی که کلمه info ندارن» (معکوس)
journalctl -u nginx --since "today" | grep -v "info"
«چند بار اتفاق افتاده؟»
# فکر: «چند بار لاگین ناموفق بوده امروز؟»
journalctl -u sshd --since "today" | grep "Failed" | wc -l
# فکر: «از چه IPهایی لاگین ناموفق بوده؟»
grep "Failed password" /var/log/secure | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -20
# فکر: «چند نفر به سایت زدن؟»
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
«بر اساس زمان فیلتر کن»
# فکر: «فقط لاگهای بین ساعت ۳ تا ۵ از فایل»
awk '/15:00:/,/17:00:/' /var/log/messages
# فکر: «فقط لاگهای امروز Jun 15»
grep "Jun 15" /var/log/messages
«خروجی رو مرتب و خلاصه کن»
# فکر: «خطاها رو گروهبندی کن ببینم کدوم بیشتره»
journalctl -p err --since "today" --no-pager | awk '{print $5}' | sort | uniq -c | sort -rn
# فکر: «نتیجه رو توی فایل ذخیره کن»
journalctl -u nginx --since "today" -p err > /tmp/nginx-errors.log
لاگهای امنیتی — «کی چیکار کرده؟»
Audit (حسابرسی سیستم)
سیستم Audit لینوکس هر عمل حساس را ثبت میکند. وقتی فکر میکنید «کی این فایل رو تغییر داده؟» یا «کی sudo زده؟»:
# تمام اتفاقات امنیتی امروز
ausearch -ts today
# چه کسی sudo زده؟
ausearch -ts today -m USER_CMD
# لاگینهای ناموفق
ausearch -ts today -m USER_LOGIN --success no
# خلاصه گزارش امنیتی
aureport --summary
# گزارش لاگینها
aureport -l
# گزارش احراز هویتهای ناموفق
aureport --failed
SELinux — «SELinux بلاک کرده؟»
# آیا SELinux چیزی رو بلاک کرده؟
ausearch -m AVC -ts today
# خلاصه بلاکهای SELinux
ausearch -m AVC -ts today | aureport -a
# یا مستقیم از فایل
grep "denied" /var/log/audit/audit.log | tail -20
Fail2Ban — «کی بن شده؟»
# وضعیت کلی fail2ban
fail2ban-client status
# کدوم IPها بن شدن توی SSH؟
fail2ban-client status sshd
# لاگ عملکرد fail2ban
journalctl -u fail2ban --since "today"
# یه IP رو آنبن کن
fail2ban-client set sshd unbanip 1.2.3.4
لاگهای کرنل و بوت
dmesg — «سختافزار مشکل داره؟»
وقتی فکر میکنید مشکل از سختافزار یا درایور است:
# لاگ کرنل با زمان خوانا
dmesg -T
# فقط خطاها و هشدارها
dmesg -T -l err,warn
# مشکل دیسک هست؟
dmesg -T | grep -i "error\|fail\|i/o"
# مشکل مموری هست؟
dmesg -T | grep -i "oom\|memory"
# مشکل شبکه هست؟
dmesg -T | grep -i "eth\|link\|network"
# لاگ کرنل لحظهای
dmesg -Tw
بوت — «موقع بالا اومدن مشکلی بوده؟»
# لاگ بوت فعلی
journalctl -b
# لاگ بوت قبلی
journalctl -b -1
# خطاهای بوت
journalctl -b -p err
# لیست بوتها
journalctl --list-boots
# چقدر طول کشید بالا بیاد
systemd-analyze
# کدوم سرویس بوت رو کند کرده
systemd-analyze blame | head -20
ترکیب قدرتمند — Pipe Mastery
یکی از قدرتمندترین مفاهیم لینوکس pipe (|) است. با ترکیب دستورات، میتوانید هر سوالی را جواب بدهید.
# «۱۰ تا IP که بیشترین لاگین ناموفق رو دارن بده»
grep "Failed password" /var/log/secure | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10
# «HTTP status code 500 چند بار اومده امروز؟ به تفکیک URL»
awk '$9 == 500 {print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
# «لاگ خطاهای Nginx رو لحظهای ببینم و فقط 502 رو فیلتر کنم»
tail -f /var/log/nginx/error.log | grep "502"
# «از تمام سرویسها خطاهای امروز رو بده و گروهبندی کن»
journalctl -p err --since "today" --no-pager | awk '{print $5}' | sort | uniq -c | sort -rn | head
عیبیابی رایج
«journalctl خروجی خالی میده!»
# بررسی: آیا journal فعال است؟
systemctl status systemd-journald
# بررسی: آیا لاگ persistent است؟
ls -la /var/log/journal/
# اگر دایرکتوری وجود نداره → لاگها بعد از ریبوت پاک میشن
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald
بهصورت پیشفرض در بعضی نسخههای Rocky Linux، journal فقط در /run/log/journal/ (حافظهی فرّار) ذخیره میشود. اگر /var/log/journal/ وجود نداشته باشد، تمام لاگها بعد از ریاستارت پاک میشوند.
«زمان لاگها اشتباهه!»
# بررسی تایمزون
timedatectl
# تنظیم تایمزون تهران
sudo timedatectl set-timezone Asia/Tehran
# بررسی همگامسازی ساعت
chronyc tracking
«لاگها خیلی زیادن نمیتونم بخونم!»
# راهحل ۱: فقط خطاها
journalctl -u nginx -p err
# راهحل ۲: آخرین N خط
journalctl -u nginx -n 30
# راهحل ۳: معکوس (جدیدترین اول)
journalctl -u nginx -r -n 30
# راهحل ۴: خروجی JSON برای پردازش
journalctl -u nginx -o json-pretty -n 5
# راهحل ۵: ذخیره در فایل
journalctl -u nginx --since "today" > /tmp/nginx.log
less /tmp/nginx.log
«permission denied میده!»
بعضی لاگها فقط با root خوانده میشوند:
# اجرای مستقیم با sudo
sudo journalctl -u nginx
# یا کاربر را به گروه systemd-journal اضافه کنید
sudo usermod -aG systemd-journal $USER
# بعد logout/login کنید
عضویت در گروه systemd-journal به کاربر اجازهی خواندن تمام لاگهای سیستم را میدهد. این گروه را فقط به کاربرانی بدهید که واقعاً به آن نیاز دارند — لاگها ممکن است حاوی اطلاعات حساس مثل توکن یا رمز در URL باشند.
چیتشیت ذهنی — مرجع سریع
این جدول را پرینت بگیرید و کنار مانیتورتان بچسبانید.
| فکر شما | دستور |
|---|---|
| «لاگ سرویس X رو بده» | journalctl -u X |
| «از ساعت ۳ تا ۵» | --since "15:00" --until "17:00" |
| «از دیروز» | --since "yesterday" |
| «یه ساعت اخیر» | --since "1 hour ago" |
| «فقط خطاها» | -p err |
| «فقط هشدارها و بالاتر» | -p warning |
| «لحظهای نشون بده» | -f |
| «آخرین N خط» | -n 50 |
| «لاگ کرنل» | journalctl -k یا dmesg -T |
| «لاگ بوت قبلی» | journalctl -b -1 |
| «کی لاگین کرده؟» | last · lastb · lastlog |
| «لاگ Docker container» | docker logs container-name |
| «لاگ امنیتی» | ausearch -ts today |
| «بگرد دنبال کلمه X» | | grep "X" |
| «حجم لاگها چقدره؟» | journalctl --disk-usage |
| «لاگ قدیمی پاک کن» | journalctl --vacuum-time=7d |
ساخت Alias فارسیوار — واقعاً با سیستم حرف بزنید!
حالا به جالبترین بخش رسیدیم. میخواهیم واقعاً همانطور که فکر میکنیم دستور بزنیم. با ساختن alias، میتوانید دستوراتی مثل این بنویسید:
$ log nginx az 3 ta 5
$ logerr sshd az yesterday
$ logf nginx
$ logboot ghabli
$ ki-ssh-zade
آمادهسازی
فایل ~/.bashrc را باز کنید:
nano ~/.bashrc
این خطوط را به انتهای فایل اضافه کنید:
# ═══════════════════════════════════════════════════
# Think → Log: Aliasهای فارسیوار لاگگیری
# ═══════════════════════════════════════════════════
# ─── لاگ سرویس (ساده) ───
# استفاده: log nginx
log() {
journalctl -u "$1" --no-pager -n 100
}
# ─── لاگ سرویس + بازه زمانی ───
# استفاده: logaz nginx "15:00" "17:00"
logaz() {
journalctl -u "$1" --since "$2" --until "$3" --no-pager
}
# ─── لاگ خطاهای سرویس ───
# استفاده: logerr nginx
# استفاده: logerr nginx "yesterday"
logerr() {
if [ -z "$2" ]; then
journalctl -u "$1" -p err --no-pager -n 100
else
journalctl -u "$1" -p err --since "$2" --no-pager
fi
}
# ─── لاگ لحظهای ───
# استفاده: logf nginx
logf() {
journalctl -u "$1" -f
}
# ─── لاگ بوت فعلی ───
alias logboot='journalctl -b --no-pager | tail -100'
# ─── لاگ بوت قبلی ───
alias logboot-ghabli='journalctl -b -1 -p err --no-pager'
# ─── لاگ کرنل ───
alias logkernel='dmesg -T | tail -50'
# ─── کی SSH زده؟ ───
alias ki-ssh-zade='echo "=== ورودهای موفق ===" && last -15 && echo "" && echo "=== ورودهای ناموفق ===" && lastb -15 2>/dev/null || echo "(نیاز به sudo دارد)"'
# ─── IPهای مشکوک ───
alias ip-mashkook='echo "=== 20 IP با بیشترین لاگین ناموفق ===" && grep "Failed password" /var/log/secure 2>/dev/null | awk "{print \$(NF-3)}" | sort | uniq -c | sort -rn | head -20'
# ─── حجم لاگها ───
alias hajm-log='echo "=== Journal ===" && journalctl --disk-usage && echo "" && echo "=== /var/log ===" && du -sh /var/log/* 2>/dev/null | sort -rh | head -15'
# ─── خطاهای امروز (همه سرویسها) ───
alias khatahaye-emrooz='journalctl -p err --since "today" --no-pager'
# ─── خلاصه خطاها به تفکیک سرویس ───
alias kholase-khata='journalctl -p err --since "today" --no-pager | awk "{print \$5}" | sort | uniq -c | sort -rn | head -20'
# ─── وضعیت fail2ban ───
alias ban-list='fail2ban-client status && echo "---" && fail2ban-client status sshd 2>/dev/null'
# ─── لاگ داکر ───
# استفاده: logdocker container-name
logdocker() {
docker logs "$1" --tail 100
}
# استفاده: logdockerf container-name (لحظهای)
logdockerf() {
docker logs "$1" -f
}
# ─── SELinux بلاک کرده؟ ───
alias selinux-block='ausearch -m AVC -ts today 2>/dev/null || echo "audit نصب نیست یا sudo لازم است"'
# ─── تاریخچه ریاستارت ───
alias restart-ha='last reboot | head -10'
فایل را ذخیره کنید و اجرا کنید:
source ~/.bashrc
حالا امتحان کنید!
| فکر فارسی | دستور | کاربرد |
|---|---|---|
| «لاگ Nginx رو بده» | log nginx | آخرین ۱۰۰ خط لاگ سرویس |
| «خطاهای SSH از دیروز» | logerr sshd "yesterday" | خطاها با بازه |
| «لاگ Nginx از ۳ تا ۵» | logaz nginx "15:00" "17:00" | لاگ در بازهی زمانی |
| «لاگ Nginx لحظهای» | logf nginx | مثل tail -f |
| «کی SSH زده؟» | ki-ssh-zade | لاگینهای موفق و ناموفق |
| «IPهای مشکوک کدومن؟» | ip-mashkook | ۲۰ IP با بیشترین ناموفق |
| «خطاهای امروز همه سرویسها» | khatahaye-emrooz | همهی خطاها |
مرجع سریع Aliasها
| فکر فارسی | دستور | کاربرد |
|---|---|---|
| لاگ سرویس | log nginx | آخرین ۱۰۰ خط |
| لاگ + بازه | logaz nginx "15:00" "17:00" | بازهی زمانی |
| فقط خطاها | logerr nginx | خطاهای سرویس |
| خطاها از دیروز | logerr nginx "yesterday" | خطاها با بازه |
| لاگ لحظهای | logf nginx | مثل tail -f |
| لاگ بوت | logboot | بوت فعلی |
| لاگ بوت قبلی | logboot-ghabli | خطاهای بوت قبل |
| لاگ کرنل | logkernel | آخرین ۵۰ خط dmesg |
| کی SSH زده | ki-ssh-zade | لاگینهای موفق و ناموفق |
| IPهای مشکوک | ip-mashkook | ۲۰ IP با بیشترین ناموفق |
| حجم لاگ | hajm-log | حجم Journal و /var/log |
| خطاهای امروز | khatahaye-emrooz | همهی خطاها |
| خلاصهی خطاها | kholase-khata | به تفکیک سرویس |
| لیست بنها | ban-list | وضعیت fail2ban |
| لاگ Docker | logdocker web-app | آخرین ۱۰۰ خط |
| لاگ Docker لحظهای | logdockerf web-app | مثل tail -f |
| بلاک SELinux | selinux-block | بلاکهای امروز |
| تاریخچهی ریاستارت | restart-ha | آخرین ریاستارتها |
نصب روی همهی سرورها
برای استقرار این aliasها روی سرورهای دیگر:
# ۱. فایل alias رو جدا نگه دارید
cat ~/.bashrc | grep -A 200 "Think → Log" > ~/think-log-aliases.sh
# ۲. کپی به سرور دیگر
scp ~/think-log-aliases.sh user@remote-server:~/
# ۳. در سرور مقصد اضافه کنید
ssh user@remote-server
cat ~/think-log-aliases.sh >> ~/.bashrc
source ~/.bashrc
برای تیمهای چندنفره، این فایل را در یک مخزن Git نگه دارید و با یک اسکریپت ساده روی همهی سرورها همگام کنید. اینطوری همهی اعضای تیم با یک زبان مشترک با سیستم حرف میزنند.
تمرین نهایی — مهارتتان را محک بزنید
بدون نگاه کردن به بخشهای قبلی، سعی کنید هر سناریو را حل کنید.
تمرین ۱: «لاگ PostgreSQL رو از ۲ ساعت پیش تا الان بده. فقط خطاها.»
journalctl -u postgresql -p err --since "2 hours ago"
تمرین ۲: «میخوام لحظهای ببینم چه خطاهایی توی کل سیستم داره تولید میشه.»
journalctl -f -p err
تمرین ۳: «از فایل لاگ Nginx خطهایی که 502 دارن رو بگرد و بشمار.»
grep "502" /var/log/nginx/error.log | wc -l
تمرین ۴: «بوت قبلی چه خطاهای کرنلی داشته؟»
journalctl -b -1 -k -p err
تمرین ۵: «لاگ کانتینر api-server رو از ۱ ساعت پیش بده.»
docker logs api-server --since "1h"
تمرین ۶: «خلاصه بده ببینم امروز کدوم سرویس بیشترین خطا رو داشته.»
journalctl -p err --since "today" --no-pager | awk '{print $5}' | sort | uniq -c | sort -rn | head -20
یا با alias:
kholase-khata
خلاصه
- فکرتان را تکهتکه کنید. مغز نمیتواند یک دستور طولانی را یکجا نگه دارد، ولی چهار تکهی معنادار را بهراحتی به خاطر میسپارد.
- هر تکه = یک بخش دستور. «چی» →
-u، «کی» →--since/--until، «چقدر مهم» →-p، «چطور نمایش» →-o/-n/-f. - اول نوع لاگ را تشخیص دهید، بعد ابزار را انتخاب کنید. Journal برای سرویسها،
/var/log/برای فایلهای اختصاصی،dmesgبرای کرنل،ausearchبرای امنیت. - pipe (
|) قدرتمندترین سلاح شماست. ترکیبgrep،awk،sort،uniqوheadهر سؤالی را به جواب تبدیل میکند. - aliasها فاصلهی فکر و تایپ را حذف میکنند. یکبار بنویسید، همیشه با زبان خودتان با سیستم حرف بزنید.