15_日志排查:5 分鐘定位 Linux 系統故障
日志排查:5 分鐘定位 Linux 系統故障
Linux 系統的 “日志” 就像 “黑匣子”—— 當服務崩潰、硬件報錯、網絡中斷時,所有關鍵信息都藏在日志里。很多新手排查故障時會 “四處亂找”,浪費大量時間;其實掌握journalctl、dmesg等工具,結合日志分析技巧,5 分鐘內就能定位大部分問題。今天這篇文章,帶你從 “日志工具使用” 到 “實戰故障定位”,再到 “多服務器日志收集”,形成完整的日志排查能力。
一、基礎工具:搞定日志 “查看” 與 “輪轉”
排查故障前,先掌握兩個核心工具:journalctl(查看 systemd 日志,覆蓋系統與服務)和logrotate(日志輪轉,避免日志撐爆磁盤),這是日志排查的 “基本功”。
1. journalctl:systemd 日志的 “全能查看器”
大部分現代 Linux(Ubuntu 16.04+、CentOS 7+)用 systemd 管理服務,對應的日志統一存在journalctl中,涵蓋系統啟動、服務運行、內核報錯等信息,無需記住多個日志文件路徑。
(1)核心用法:3 個高頻場景
| 需求 | 命令 | 關鍵參數解讀 |
|---|---|---|
| 查看某服務日志(如 Nginx) | journalctl -u nginx |
-u:指定服務單元(unit),只顯示該服務的日志 |
| 實時追蹤日志(類似 tail -f) | journalctl -u nginx -f |
-f:實時跟隨日志輸出,新日志會自動刷新 |
| 按時間篩選日志(近 1 小時) | journalctl -u nginx --since "1 hour ago" |
--since/--until:按時間范圍篩選,支持 “10min ago”“2024-10-25 14:00” 等格式 |
(2)進階篩選:快速定位關鍵日志
排查故障時,常需要按 “錯誤級別”“關鍵字” 篩選,減少無效信息:
\# 1. 只看Nginx的錯誤日志(優先級err及以上:err/warning/crit/alert/emerg)
journalctl -u nginx -p err # -p:指定優先級(priority)
\# 2. 搜索包含“failed”關鍵詞的Nginx日志(大小寫不敏感)
journalctl -u nginx -i | grep "failed" # -i:grep忽略大小寫
\# 3. 查看某時間段內的內核日志(內核日志用\_-kernel.service單元)
journalctl -u \_-kernel.service --since "2024-10-25 14:00" --until "2024-10-25 14:30"
(3)避坑:journalctl 日志不持久化
默認情況下,journalctl日志只保存在內存中,重啟后丟失。若需持久化(長期保存日志),需手動配置:
\# 1. 創建日志存儲目錄
sudo mkdir -p /var/log/journal
\# 2. 重啟systemd-journald服務
sudo systemctl restart systemd-journald
\# 3. 驗證:重啟后 journalctl -u nginx 仍能看到之前的日志
2. logrotate:日志輪轉的 “自動管家”
應用日志(如 Nginx、MySQL)會持續增長,若不處理,可能幾小時就占滿磁盤(比如 10GB 的訪問日志)。logrotate能自動 “切割日志、壓縮歸檔、刪除舊日志”,是日志管理的必備工具。
(1)核心配置:理解 logrotate 規則
logrotate的配置文件分兩類:
-
全局配置:
/etc/logrotate.conf(定義默認規則,如默認保留 4 份輪轉日志); -
應用配置:
/etc/logrotate.d/目錄下(針對單個應用,如/etc/logrotate.d/nginx,優先級高于全局配置)。
(2)實戰:配置 Nginx 日志輪轉
以 Nginx 日志(/var/log/nginx/access.log和error.log)為例,編寫輪轉配置:
\# 1. 創建Nginx的logrotate配置文件
sudo vim /etc/logrotate.d/nginx
\# 2. 寫入以下配置(逐行解讀)
/var/log/nginx/\*.log { # 匹配Nginx的所有.log文件
  daily # 輪轉周期:每天1次(可選weekly/monthly)
  rotate 7 # 保留7份歸檔日志(超過7天的自動刪除)
  compress # 歸檔日志用gzip壓縮(節省磁盤空間)
  delaycompress # 延遲壓縮:只壓縮前一天的日志(避免正在寫的日志被壓縮)
  missingok # 若日志文件不存在,不報錯(避免手動刪除日志后輪轉失敗)
  notifempty # 若日志為空,不執行輪轉
  create 0640 www-data www-data # 新建日志文件的權限、所有者、所屬組(匹配Nginx運行用戶)
  sharedscripts # 所有日志文件輪轉后,只執行一次postrotate腳本
  postrotate # 輪轉后執行的腳本(Nginx需重新打開日志文件,否則繼續寫舊日志)
  if \[ -f /var/run/nginx.pid ]; then
  kill -USR1 \`cat /var/run/nginx.pid\` # 發送USR1信號,Nginx重新打開日志
  fi
  endscript
}
(3)驗證:測試 logrotate 配置是否生效
配置后,無需等待 “每天輪轉”,可手動觸發測試:
\# 1. 測試配置(無報錯說明配置正確)
sudo logrotate -d /etc/logrotate.d/nginx # -d:dry run,只模擬,不實際執行
\# 2. 強制執行輪轉(實際切割日志)
sudo logrotate -f /etc/logrotate.d/nginx # -f:force,強制輪轉
\# 3. 驗證結果:查看Nginx日志目錄,會生成access.log.1.gz(歸檔壓縮的舊日志)和新的access.log
ls -l /var/log/nginx/
二、實戰排障:5 分鐘定位兩類高頻故障
掌握工具后,結合 “系統服務故障” 和 “硬件故障” 兩個場景,演示如何快速定位問題。
實戰 1:Nginx 服務崩潰 —— 從日志找原因
場景:執行sudo systemctl start nginx,提示 “Job for nginx.service failed because the control process exited with error code.”,需 5 分鐘內定位崩潰原因。
步驟 1:1 分鐘看 systemd 日志(初步定位)
先用journalctl查看 Nginx 服務的錯誤日志,獲取關鍵線索:
journalctl -u nginx -p err --no-pager # --no-pager:不分頁,直接顯示所有錯誤日志
常見錯誤日志與原因:
-
日志 1:
nginx: [emerg] bind() to ``0.0.0.0:80`` failed (98: Address already in use)→ 原因:80 端口被其他進程占用(如 Apache);
-
日志 2:
nginx: [emerg] invalid parameter "worker_processes" in /etc/nginx/nginx.conf:2→ 原因:Nginx 配置文件語法錯誤(第 2 行
worker_processes參數無效); -
日志 3:
nginx: [emerg] open() "/var/log/nginx/error.log" failed (13: Permission denied)→ 原因:Nginx 運行用戶(www-data)無日志文件寫入權限。
步驟 2:2 分鐘查 Nginx 專屬日志(精準定位)
systemd 日志可能不夠詳細,需查看 Nginx 自己的錯誤日志(路徑在/etc/nginx/nginx.conf中定義,默認/var/log/nginx/error.log):
\# 查看錯誤日志的最后20行(最新錯誤)
tail -n 20 /var/log/nginx/error.log
舉例:若日志顯示2024/10/25 14:30:00 [crit] 1234#0: *5 open() "/var/www/html/index.html" failed (2: No such file or directory),說明 Nginx 配置的網站根目錄/var/www/html下缺少index.html文件,導致訪問時崩潰。
步驟 3:2 分鐘驗證并解決問題
-
若為端口占用:用
lsof -i :80找到占用進程(如PID=567的apache2),sudo kill -9 567關閉后,重啟 Nginx; -
若為配置錯誤:用
nginx -t檢查配置語法(sudo nginx -t),根據提示修改/etc/nginx/nginx.conf,再重啟; -
若為權限問題:執行
sudo chown -R www-data:www-data /var/log/nginx/,賦予 Nginx 用戶權限。
驗證:sudo systemctl start nginx,sudo systemctl status nginx顯示 “active (running)”,故障解決。
實戰 2:硬件報錯 —— 用 dmesg 解讀內核日志
場景:服務器頻繁卡頓,偶爾藍屏,懷疑硬件故障(如磁盤壞道、內存錯誤),需通過內核日志排查。
步驟 1:1 分鐘查看 dmesg 實時內核日志
dmesg用于查看內核日志(包括硬件初始化、驅動報錯、磁盤 / 內存故障),默認輸出所有日志,需按 “錯誤關鍵詞” 篩選:
\# 查看包含“error”“warn”“fail”關鍵詞的內核日志(忽略大小寫)
dmesg | grep -iE "error|warn|fail"
步驟 2:3 分鐘解讀常見硬件故障日志
(1)磁盤壞道(最常見)
日志特征:包含 “bad sector”“I/O error”“sdX”(X 為磁盤編號,如 sda):
\[1234.567890] sd 0:0:0:0: \[sda] Add. Sense: Unrecovered read error - auto reallocate failed
\[1234.567900] sd 0:0:0:0: \[sda] CDB: Read(10): 28 00 00 12 34 56 00 00 08 00
\[1234.567910] blk\_update\_request: I/O error, dev sda, sector 123456 op 0x0:(READ) flags 0x80700 phys\_seg 1 prio class 0
→ 解讀:sda磁盤的 123456 扇區有壞道,讀取失敗;
→ 解決:立即備份/dev/sda上的數據,用fsck /dev/sda1修復壞道,若頻繁報錯,更換磁盤。
(2)內存錯誤
日志特征:包含 “memory error”“EDAC”“MC0”(內存控制器):
\[7890.123456] EDAC MC0: UE error count (addr 0x12345678): 1
\[7890.123460] EDAC MC0: CE error count: 0
\[7890.123465] EDAC MC0: UE error (synd 0x12345678, addr 0x12345678, layer Memory, gran 64B)
→ 解讀:內存地址0x12345678出現不可糾正錯誤(UE),可能導致程序崩潰或藍屏;
→ 解決:用memtest86+工具檢測內存(需重啟從 U 盤啟動),確認故障內存插槽后,更換內存條。
步驟 3:1 分鐘保存 dmesg 日志(便于后續分析)
dmesg 日志在重啟后會清空,需保存到文件:
\# 保存當前dmesg日志到文件
dmesg > /var/log/dmesg\_20241025.log
\# 后續可通過該文件分析歷史硬件報錯
cat /var/log/dmesg\_20241025.log | grep "sda"
三、進階方案:多服務器遠程日志收集
當管理 10 臺、100 臺 Linux 服務器時,逐臺登錄看日志效率極低 —— 需搭建 “遠程日志收集系統”,讓所有服務器的日志統一發送到 “日志服務器”,實現 “集中查看、快速檢索”。
這里推薦用rsyslog(Linux 默認預裝,配置簡單)搭建基礎遠程日志系統,適合中小規模服務器(大規模可用 ELK 棧,后續進階)。
1. 步驟 1:配置 “日志服務器”(接收日志)
假設日志服務器 IP 為192.168.1.100,負責接收其他服務器的日志:
\# 1. 編輯rsyslog配置文件
sudo vim /etc/rsyslog.conf
\# 2. 開啟UDP/TCP接收模塊(取消以下兩行注釋,任選一種協議,UDP簡單,TCP可靠)
module(load="imudp") # 加載UDP接收模塊
input(type="imudp" port="514") # 監聽514端口(rsyslog默認端口)
\# module(load="imtcp") # 加載TCP接收模塊
\# input(type="imtcp" port="514")
\# 3. 配置日志存儲規則(所有遠程日志保存到/var/log/remote/目錄,按服務器IP分類)
\$template RemoteLog,"/var/log/remote/%FROMHOST-IP%/%PROGRAMNAME%.log" # 模板:按IP和程序名存日志
\*.\* ?RemoteLog # 所有級別(\*.\*)的日志,按模板存儲
\# 4. 重啟rsyslog服務
sudo systemctl restart rsyslog
\# 5. 開放防火墻端口(允許514端口的UDP/TCP流量)
sudo ufw allow 514/udp # Ubuntu
\# sudo firewall-cmd --add-port=514/udp --permanent && sudo firewall-cmd --reload # CentOS
2. 步驟 2:配置 “客戶端服務器”(發送日志)
假設客戶端服務器 IP 為192.168.1.101,需將日志發送到192.168.1.100:
\# 1. 編輯rsyslog配置文件
sudo vim /etc/rsyslog.conf
\# 2. 添加日志發送規則(所有日志通過UDP發送到日志服務器)
\*.\* @192.168.1.100:514 # @表示UDP,@@表示TCP,端口514
\# 若只發送Nginx日志,可更精準:
\# :programname,isequal,"nginx" @192.168.1.100:514
\# 3. 重啟rsyslog服務
sudo systemctl restart rsyslog
3. 步驟 3:驗證遠程日志收集
\# 1. 在客戶端服務器生成測試日志(觸發日志發送)
logger "test remote log from 192.168.1.101" # logger命令用于生成自定義日志
\# 2. 在日志服務器查看是否收到日志
ls -l /var/log/remote/192.168.1.101/ # 會看到logger.log文件
cat /var/log/remote/192.168.1.101/logger.log # 能看到測試日志內容,說明配置成功
進階:大規模場景推薦 ELK 棧
若服務器超過 50 臺,rsyslog的檢索能力不足,可搭建 ELK 棧(Elasticsearch+Logstash+Kibana):
-
Logstash:收集日志并格式化;
-
Elasticsearch:存儲日志并支持全文檢索;
-
Kibana:可視化日志(圖表、儀表盤),支持按 IP、時間、關鍵詞快速篩選。
四、避坑指南:3 個日志排查常見誤區
1. 誤區 1:只看 systemd 日志,忽略應用專屬日志
表現:Nginx 啟動失敗,只看journalctl -u nginx,沒看/var/log/nginx/error.log,錯過配置文件語法錯誤的詳細提示。
正確做法:systemd 日志看 “服務狀態”,應用專屬日志看 “具體錯誤細節”,兩者結合才能快速定位。
2. 誤區 2:logrotate 配置后不測試,日志撐爆磁盤
表現:配置 Nginx 日志輪轉后,未手動測試,實際輪轉時因 “權限不足” 失敗,導致access.log漲到 100GB 占滿磁盤。
正確做法:配置后必執行sudo logrotate -d /etc/logrotate.d/nginx(模擬測試)和sudo logrotate -f ...(強制執行),驗證輪轉是否正常生成歸檔日志。
3. 誤區 3:遠程日志收集不開放防火墻端口
表現:客戶端配置好 rsyslog,日志服務器卻收不到日志,排查半天發現防火墻未開放 514 端口。
正確做法:配置遠程日志時,先在日志服務器執行sudo netstat -tuln | grep 514,確認 rsyslog 已監聽 514 端口,再開放防火墻端口(UDP/TCP)。
總結:5 分鐘日志排查核心流程
-
服務故障:
1 分鐘
journalctl -u 服務名 -p err看系統日志 → 2 分鐘tail -n 20 應用日志路徑看細節 → 2 分鐘驗證解決; -
硬件故障:
1 分鐘
dmesg | grep -i error找報錯 → 3 分鐘解讀日志定位硬件(磁盤 / 內存) → 1 分鐘保存日志并處理; -
多服務器:
用
rsyslog搭建遠程收集,中小規模夠用;大規模用 ELK 棧,實現可視化檢索。
掌握這套流程,你就能從 “日志小白” 變成 “故障排查高手”,大部分 Linux 故障都能在 5 分鐘內定位,不再因 “找不到原因” 而焦慮。

浙公網安備 33010602011771號