پرش به مطلب اصلی

راهنمای هوشمند لاگ‌گیری در 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، تمام سرویس‌ها لاگ تولید می‌کنند و این لاگ‌ها در دو مسیر موازی ذخیره می‌شوند.

systemd-journald · /var/log/journalJournalsystemd-journald · /var/log/journalrsyslogd · /var/log/*Log Filesrsyslogd · /var/log/*nginx, sshd, postgresql, dockerServicesnginx, sshd, postgresql, dockerdmesg · journalctl -kKerneldmesg · journalctl -ksecure, audit.log, last, lastbAuth & Auditsecure, audit.log, last, lastbjournalctl, grep, tail, ausearchAccess Toolsjournalctl, grep, tail, ausearch

قانون طلایی: کجا بگردم؟​

این ساده‌ترین قانون است. حفظش کنید:

فکر شماکجا بگردیدابزار
«لاگ سرویس X رو می‌خوام»Journaljournalctl -u X
«لاگ فایل مستقیم سرویس رو می‌خوام»/var/log/cat, grep, tail
«لاگ کرنل رو می‌خوام»هر دوdmesg یا journalctl -k
«لاگ ورود کاربران رو می‌خوام»فایل خاصlast, lastb, lastlog
«لاگ امنیتی (audit) رو می‌خوام»فایل خاصausearch, aureport
«لاگ Docker رو می‌خوام»Docker enginedocker 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
معکوس (جدیدترین اول)-rreverse 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

این خطوط را به انتهای فایل اضافه کنید:

~/.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
لاگ Dockerlogdocker web-appآخرین ۱۰۰ خط
لاگ Docker لحظه‌ایlogdockerf web-appمثل tail -f
بلاک SELinuxselinux-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ها فاصله‌ی فکر و تایپ را حذف می‌کنند. یک‌بار بنویسید، همیشه با زبان خودتان با سیستم حرف بزنید.