গাইড

Linux-এর লগ: journalctl, /var/log, rsyslog ও logrotate

হালনাগাদ: · Skillaria.Top

আধুনিক Linux-এ লগ জমা করে journald, আর পড়া হয় journalctl দিয়ে: journalctl -u nginx একটি সার্ভিসের লগ দেখায়, -f রিয়েল টাইমে স্রোত দেখায়, --since ও -p সময় ও গুরুত্ব অনুযায়ী ছাঁকে। লেখা লগ ফাইল থাকে /var/log-এ, সেগুলো লেখে rsyslog বা অ্যাপ্লিকেশন নিজে, আর logrotate নিয়মিত পুরনো ফাইল সংকুচিত ও মুছে দেয়, যাতে ডিস্ক ভরে না যায়।

রাতে সার্ভিস পড়ে গেলে উত্তর প্রায় সবসময় লগে থাকে — প্রশ্ন শুধু কোথায় খুঁজবেন। আধুনিক Linux ডিস্ট্রিবিউশনে (Ubuntu, Debian, RHEL, Fedora, Arch) ঘটনাগুলো জমা করে journald সার্ভিস, আর পড়তে হয় journalctl কমান্ডে। সমান্তরালে অনেক প্রোগ্রাম সাধারণ টেক্সট ফাইল লেখে /var/log-এ, আর সেগুলোর আকার দেখে logrotate। নিচে ব্যবহারিকভাবে দেখানো হবে কীভাবে journalctl দিয়ে Linux-এর লগ পড়তে হয়, বাকি লগ কোথায় থাকে, এবং ঘূর্ণনের সময় কীভাবে গুরুত্বপূর্ণ কিছু না হারাতে হয়।

Linux-এ লগ কোথায় থাকে

উৎস তিনটি, এগুলোকে একটি মানচিত্রের মতো মাথায় রাখা ভালো:

  • journald — systemd-র বাইনারি লগ। সব সার্ভিসের stdout ও stderr, কার্নেলের বার্তা ও syslog গ্রহণ করে। সংরক্ষিত হয় /var/log/journal/-এ (স্থায়ী) বা /run/log/journal/-এ (রিবুট পর্যন্ত)।
  • /var/log — টেক্সট ফাইল। সেগুলো লেখে rsyslog (যেমন /var/log/syslog, /var/log/auth.log) বা অ্যাপ্লিকেশন নিজে: nginx, PostgreSQL, MySQL।
  • কার্নেল রিং বাফার — ড্রাইভার ও হার্ডওয়্যারের বার্তা, যা দেখায় dmesg বা journalctl -k।
ফাইলএতে কী থাকে
/var/log/syslog (Debian/Ubuntu)সাধারণ সিস্টেম লগ
/var/log/messages (RHEL/Fedora)একই জিনিস Red Hat পরিবারে
/var/log/auth.log বা /var/log/secureলগইন, sudo, SSH
/var/log/kern.logকার্নেলের বার্তা
/var/log/dpkg.log, /var/log/apt/প্যাকেজ ইনস্টল
/var/log/nginx/ওয়েব সার্ভারের access.log ও error.log
/var/log/wtmp, /var/log/btmpবাইনারি লগইন রেকর্ড, পড়া হয় last ও lastb দিয়ে

/var/log-এর বেশিরভাগ ফাইল শুধু root বা adm গ্রুপ পড়তে পারে, তাই পড়ার কমান্ড প্রায়ই sudo দিয়ে চালাতে হয়।

journalctl: মৌলিক কমান্ড

আর্গুমেন্ট ছাড়া journalctl পুরো লগ দেখায়, সবচেয়ে পুরনো থেকে, less পেজারে। এটি খুব কমই দরকার — সাধারণত আগে থেকেই পরিসর ছোট করা হয়।

journalctl              # পুরো লগ, পুরনো থেকে নতুন
journalctl -e           # সরাসরি শেষে খোলা
journalctl -n 50        # শেষ 50 লাইন
journalctl -r           # উল্টো ক্রমে, নতুন উপরে
journalctl --no-pager   # less ছাড়া, স্ক্রিপ্ট ও grep-এর জন্য সুবিধাজনক

পেজারের ভেতরে less-এর পরিচিত কী কাজ করে: / — খোঁজা, G — শেষে যাওয়া, q — বের হওয়া। লম্বা লাইন স্ক্রিনের প্রস্থে কাটা হয়; বাঁ ও ডান তীর দিয়ে সেগুলো সরানো যায়।

একটি সার্ভিসের লগ: journalctl -u

সবচেয়ে সাধারণ কাজ — একটি systemd ইউনিট কী লিখেছে তা দেখা। ফাইল খুঁজে গ্রেপ করার দরকার নেই:

$ sudo journalctl -u nginx -n 20
Oct 14 03:12:41 web1 systemd[1]: Starting nginx.service - A high performance web server...
Oct 14 03:12:41 web1 nginx[1834]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Oct 14 03:12:41 web1 systemd[1]: nginx.service: Control process exited, code=exited, status=1/FAILURE
Oct 14 03:12:41 web1 systemd[1]: nginx.service: Failed with result 'exit-code'.

ফ্ল্যাগ -u একাধিকবার দেওয়া যায়: journalctl -u nginx -u php8.2-fpm দুটি সার্ভিসের লগ সময় অনুযায়ী মিশিয়ে দেখায়, যা ত্রুটি দুটির সংযোগস্থলে ঘটলে কাজে লাগে। ব্যবহারকারীর ইউনিটের (systemctl --user) জন্য journalctl --user -u নাম।

রিয়েল টাইমে লগ: journalctl -f

sudo journalctl -u nginx -f

এটি tail -f-এর মতো: শেষের 10 লাইন দেখায় এবং নতুন লাইনের অপেক্ষা করে। সার্ভিস রিস্টার্ট করার বা ত্রুটি পুনরায় ঘটানোর সময় এটি আলাদা টার্মিনালে চালিয়ে রাখা সুবিধাজনক। বের হতে Ctrl+C।

সময় ও বুট অনুযায়ী ফিল্টার

সমস্যা কখন হয়েছে জানা থাকলে --since ও --until ফ্ল্যাগে সময়সীমা দিন। এগুলো সঠিক তারিখ এবং আপেক্ষিক মান দুটোই বোঝে:

journalctl --since "2026-10-14 02:50" --until "2026-10-14 03:30"
journalctl --since "1 hour ago"
journalctl --since yesterday --until today
journalctl -u nginx --since "10 min ago"

আরেকটি কার্যকর ভাগ — সিস্টেমের বুট অনুযায়ী। সার্ভার নিজে রিবুট হলে কারণ খোঁজা হয় আগের সেশনের শেষে:

$ journalctl --list-boots
 -2 8f1c...  Sat 2026-10-12 09:01:12 UTC  Sun 2026-10-13 22:47:03 UTC
 -1 a7d2...  Sun 2026-10-13 22:48:30 UTC  Tue 2026-10-14 03:05:51 UTC
  0 c3e9...  Tue 2026-10-14 03:07:02 UTC  Tue 2026-10-14 09:15:40 UTC

$ journalctl -b -1 -e      # আগের বুটের শেষ অংশ
$ journalctl -b            # শুধু বর্তমান বুট

বুটের তালিকা তখনই পাওয়া যায়, যখন লগ ডিস্কে সংরক্ষিত থাকে। কীভাবে তা চালু করা যায়, নিচে journald-এর কনফিগারেশন অংশে দেখানো হয়েছে।

গুরুত্ব অনুযায়ী ফিল্টার: journalctl -p

প্রতিটি রেকর্ডের একটি syslog অগ্রাধিকার আছে, 0 থেকে 7 পর্যন্ত। ফ্ল্যাগ -p দেওয়া স্তর এবং তার চেয়ে গুরুতর সবকিছু দেখায়:

কোডনামকখন ব্যবহার হয়
0emergসিস্টেম অকার্যকর
1alertঅবিলম্বে হস্তক্ষেপ দরকার
2critগুরুতর ত্রুটি
3errত্রুটি
4warningসতর্কবার্তা
5noticeউল্লেখযোগ্য কিন্তু স্বাভাবিক ঘটনা
6infoতথ্যমূলক বার্তা
7debugডিবাগ
journalctl -p err -b              # বুট থেকে সব ত্রুটি
journalctl -p warning..err -u ssh # একটি সার্ভিসের জন্য স্তরের পরিসর

journalctl -p err -b রিবুট বা আপডেটের পরে একটি ভালো প্রথম পরীক্ষা: কয়েক সেকেন্ডে দেখায় কোথায় কী ভুল হলো।

খোঁজা ও অন্যান্য ফিল্টার

journald প্রতিটি রেকর্ডের সঙ্গে কাঠামোবদ্ধ ফিল্ড রাখে, আর সেগুলো দিয়ে grep ছাড়াই ফিল্টার করা যায়:

journalctl _PID=1834                 # প্রসেস নম্বর দিয়ে
journalctl _COMM=sshd                # প্রোগ্রামের নাম দিয়ে
journalctl _UID=1000                 # ব্যবহারকারী দিয়ে
journalctl /usr/sbin/sshd            # চালানো ফাইলের পথ দিয়ে
journalctl -k                        # শুধু কার্নেলের বার্তা (dmesg-এর মতো)
journalctl -t CRON                   # syslog শনাক্তকারী দিয়ে
journalctl -g "Out of memory"        # লেখার ভেতরে খোঁজা, রেগুলার এক্সপ্রেশন

ফ্ল্যাগ -g (--grep) systemd 237-এ যোগ হয়েছে; পুরনো সিস্টেমে সাধারণ পাইপ journalctl --no-pager | grep ... ব্যবহার করুন। বিভিন্ন ফিল্ডের ফিল্টার “এবং” দিয়ে যুক্ত হয়, তাই journalctl -u nginx -p err --since today শুধু আজকের nginx ত্রুটি দেখাবে।

আউটপুটের ফরম্যাট

ফ্ল্যাগ -o ফরম্যাট বদলায়। সবচেয়ে কাজের বিকল্পগুলো:

  • -o short-iso — সময় ISO 8601 ফরম্যাটে, অ্যাপ্লিকেশনের লগের সঙ্গে তুলনার জন্য সুবিধাজনক।
  • -o verbose — রেকর্ডের সব ফিল্ড, যেমন _SYSTEMD_UNIT, _PID, _BOOT_ID।
  • -o json বা json-pretty — স্ক্রিপ্ট বা jq-এ প্রসেসিংয়ের জন্য।
  • -o cat — শুধু বার্তার টেক্সট, তারিখ ও হোস্ট ছাড়া।
journalctl -u myapp -o json --since today | jq -r '.MESSAGE'

journald কনফিগার করা: সংরক্ষণ ও আকার

সেটিংস থাকে /etc/systemd/journald.conf-এ (পরিবর্তন ভালো হয় /etc/systemd/journald.conf.d/*.conf-এ রেখে)। মূল প্যারামিটার — Storage:

  • persistent — লগ ডিস্কে /var/log/journal-এ লেখা হয় এবং রিবুটের পরেও টিকে থাকে।
  • volatile — শুধু মেমরিতে, /run/log/journal-এ।
  • auto (ডিফল্ট) — /var/log/journal ডিরেক্টরি থাকলে ডিস্কে।

কিছু ন্যূনতম ইমেজে ওই ডিরেক্টরি থাকে না, ফলে রিবুটের পরে ইতিহাস হারিয়ে যায়। স্থায়ী সংরক্ষণ চালু করতে:

sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald

যাতে journal পুরো ডিস্ক না নেয়, সীমা দিন:

# /etc/systemd/journald.conf.d/size.conf
[Journal]
Storage=persistent
SystemMaxUse=500M
MaxRetentionSec=1month

ডিফল্টে SystemMaxUse হলো ফাইল সিস্টেমের আকারের 10%, তবে 4 GB-র বেশি নয়।

journalctl লগ কীভাবে পরিষ্কার করবেন

$ journalctl --disk-usage
Archived and active journals take up 1.8G in the file system.

sudo journalctl --vacuum-size=300M   # সর্বোচ্চ 300 MB রাখা
sudo journalctl --vacuum-time=2weeks # দুই সপ্তাহের পুরনো রেকর্ড মোছা
sudo journalctl --rotate             # সক্রিয় ফাইল বন্ধ করা, যাতে সেটিও মোছা যায়

/var/log/journal থেকে rm দিয়ে ফাইল মুছবেন না: vacuum একই কাজ নিরাপদে করে এবং সক্রিয় ফাইলে হাত দেয় না।

rsyslog: ঐতিহ্যবাহী টেক্সট লগ

rsyslog একটি ডেমন, যা syslog বার্তা গ্রহণ করে (journald থেকে ফরওয়ার্ড হওয়াগুলোও) এবং নিয়ম অনুযায়ী ফাইলে সাজায়। কনফিগারেশন — /etc/rsyslog.conf ও /etc/rsyslog.d/*.conf। একটি নিয়ম গঠিত হয় উৎস.স্তর সিলেক্টর ও একটি কাজ দিয়ে:

# /etc/rsyslog.d/50-default.conf (অংশ)
auth,authpriv.*        /var/log/auth.log
*.*;auth,authpriv.none -/var/log/syslog
kern.*                 -/var/log/kern.log

পথের আগে বিয়োগ চিহ্ন (-) মানে প্রতিটি লাইনের পরে ডিস্কে সিঙ্ক না করে লেখা — দ্রুত, কিন্তু দুর্ঘটনায় শেষের কয়েকটি লাইন হারাতে পারে। কনফিগ বদলালে আগে সিনট্যাক্স যাচাই করে সার্ভিস রিস্টার্ট করুন:

sudo rsyslogd -N1
sudo systemctl restart rsyslog

rsyslog-কে journald-এর পাশে রাখার মূল কারণ — লগ কেন্দ্রীয় সার্ভারে পাঠানো। একটি লাইনে সব TCP-তে যাবে:

# /etc/rsyslog.d/90-remote.conf
*.* @@logs.example.com:514

একটি @ মানে UDP, দুটি @@ মানে TCP। পুরো সার্ভার নষ্ট হলেও লগের কপি অন্য মেশিনে থাকবে। স্ক্রিপ্ট থেকে সিস্টেম লগে নিজের বার্তা লিখতে logger ব্যবহার করুন:

logger -t backup -p user.err "ডেটাবেস ব্যাকআপ ব্যর্থ হয়েছে"
journalctl -t backup -n 5

logrotate: লগ ঘূর্ণন

টেক্সট লগ অনন্তকাল বাড়তে থাকে, যদি না কেউ ছাঁটে। এই কাজটি করে logrotate: প্রতিদিন (cron বা logrotate.timer দিয়ে) এটি বর্তমান ফাইলের নাম বদলায়, পুরনোগুলো সংকুচিত করে এবং সবচেয়ে পুরনোগুলো মুছে দেয়। সাধারণ সেটিংস — /etc/logrotate.conf, প্রোগ্রামের নিয়ম — /etc/logrotate.d/-এ।

# /etc/logrotate.d/myapp
/var/log/myapp/*.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    create 0640 myapp adm
    postrotate
        systemctl reload myapp > /dev/null 2>&1 || true
    endscript
}
নির্দেশঅর্থ
daily / weekly / size 100Mকখন ঘোরানো হবে
rotate 14কতগুলো পুরনো ফাইল রাখা হবে
compress, delaycompressgzip-এ সংকোচন, তবে সবচেয়ে নতুন আর্কাইভ অসংকুচিত রাখা
missingok, notifemptyফাইল না থাকলে অভিযোগ না করা, খালি ফাইল না ঘোরানো
create 0640 user groupনতুন ফাইল কী অধিকার নিয়ে তৈরি হবে
copytruncateফাইল কপি করে তারপর খালি করা — যেসব প্রোগ্রাম লগ আবার খুলতে জানে না তাদের জন্য
postrotate ... endscriptঘূর্ণনের পরের কমান্ড, সাধারণত অ্যাপ্লিকেশনকে ফাইল পুনরায় খুলতে সংকেত

নিয়ম কোনো পরিবর্তন ছাড়া যাচাই করতে এবং জোর করে ঘূর্ণন চালাতে:

sudo logrotate -d /etc/logrotate.d/myapp   # ড্রাই রান, বিস্তারিত সহ
sudo logrotate -f /etc/logrotate.d/myapp   # এখনই ঘোরানো

সাধারণ ভুল — postrotate বা copytruncate ভুলে যাওয়া। তখন অ্যাপ্লিকেশন পুরনো ডেসক্রিপ্টরে নামবদলানো app.log.1-এ লিখতে থাকে, আর নতুন app.log খালি পড়ে থাকে।

টেক্সট লগ পড়া

/var/log-এর ফাইলের জন্য সাধারণ ইউটিলিটিই যথেষ্ট:

sudo tail -n 100 /var/log/syslog          # শেষের কয়েক লাইন
sudo tail -F /var/log/nginx/error.log     # ঘূর্ণন টিকিয়ে অনুসরণ
sudo less +G /var/log/auth.log            # শেষে খোলা
sudo zgrep "Failed password" /var/log/auth.log.*.gz   # সংকুচিত আর্কাইভে খোঁজা
sudo grep -c " 500 " /var/log/nginx/access.log        # কতগুলো 500 উত্তর

লক্ষ্য করুন tail -F-এ বড় হাতের F: -f-এর বিপরীতে এটি ফাইল আবার খোলে, যখন logrotate সেটি বদলে দেয়।

একটি দুর্ঘটনার ধাপে ধাপে বিশ্লেষণ

“রাতে সার্ভিস পড়ে গেছে” — এমন পরিস্থিতি একটি নির্দিষ্ট ক্রমে বিশ্লেষণ করা সুবিধাজনক:

  1. systemctl status myapp — বর্তমান অবস্থা ও লগের শেষের কয়েক লাইন।
  2. journalctl -u myapp --since "03:00" --until "03:30" — পতনের মুহূর্তে সার্ভিস কী লিখেছিল।
  3. journalctl -p err -b — একই সময়ে সিস্টেমের অন্য কোনো ত্রুটি আছে কি না।
  4. journalctl -k --since "03:00" -g "Out of memory|Killed process" — কার্নেলের OOM killer প্রসেসটি বন্ধ করেছে কি না।
  5. অ্যাপ্লিকেশনের নিজের লগ /var/log/myapp/-এ, .gz আর্কাইভসহ।
  6. সার্ভার রিবুট হয়ে থাকলে — journalctl -b -1 -e।

সারসংক্ষেপ

প্রতিদিনের লগ-কাজের জন্য কয়েকটি কমান্ডই যথেষ্ট: সার্ভিসের জন্য journalctl -u, স্রোতের জন্য -f, পরিসর ছাঁটতে --since ও -p err, রিবুট বিশ্লেষণে -b -1। টেক্সট লগ থাকে /var/log-এ, rsyslog সেগুলো সাজায় ও পাঠায়, আর logrotate এবং journalctl --vacuum-* নিশ্চিত করে লগ যেন ডিস্ক না খেয়ে ফেলে। journalctl, ঘূর্ণন ও লোড-বিশ্লেষণ নিয়ে হাতে-কলমে কাজ হয়েছে Linux কোর্সের একটি লেকচারে।

সাধারণ প্রশ্ন

কেন journalctl শুধু শেষ বুটের রেকর্ড দেখায়?

লগ মেমরিতে (/run/log/journal) রাখা হয়েছে। /var/log/journal ডিরেক্টরি বানান, অথবা journald.conf-এ Storage=persistent দিয়ে systemd-journald রিস্টার্ট করুন।

সাধারণ ব্যবহারকারী sudo ছাড়া সিস্টেম লগ কীভাবে পড়বে?

তাকে systemd-journal গ্রুপে যোগ করুন (Debian ও Ubuntu-তে adm): sudo usermod -aG systemd-journal নাম, তারপর আবার লগইন করুন।

অন্য সিস্টেমের, যেমন সংযুক্ত ডিস্কের, journal কি দেখা যায়?

হ্যাঁ, -D ফ্ল্যাগে লগ ডিরেক্টরি দিন: journalctl -D /mnt/var/log/journal। --file ফ্ল্যাগ একটি আলাদা .journal ফাইল পড়ে।

journald থাকলে rsyslog কি লাগে?

বাধ্যতামূলক নয়। পুরনো টুলের জন্য টেক্সট ফাইল দরকার হলে, অথবা কেন্দ্রীয় সার্ভারে লগ পাঠাতে চাইলে এটি কাজে লাগে; অনেক ন্যূনতম ইমেজে এটি আর ইনস্টল করা হয় না।

কোনো সার্ভিসের লগ ফাইলে এক্সপোর্ট করে সহকর্মীকে পাঠাবেন কীভাবে?

journalctl -u নাম --since today --no-pager > service.log চালান — এতে একটি সাধারণ টেক্সট ফাইল তৈরি হবে।

ভিডিওতে বিষয়টি শিখুন

“Linux: с нуля до уверенного администрирования” কোর্সে বিষয়টি অনুশীলনসহ বিস্তারিত শেখানো হয়েছে।

কোর্সে যান