博客 / 詳情

返回

同事查日誌太慢,我現場教他一套 awk、tail、grep、sed 組合拳

昨天臨下班,生產環境出現了一個偶發的報錯預警。

旁邊的同事正~~準備排查,只見他輸入命令 cat application.log ,一個 2GB 大小文本啊,日誌嘩嘩刷啥也看不清,crtl + c 也停不下來了,最後輕輕的關閉連接,又重新打開了一個~

後端開發來説,熟練掌握 Linux 的日誌分析命令是基本功,整理幾一些基於 taillessgrepsedawk 的日誌查詢場景,希望能幫你快速定位問題。

同名公眾號:程序員小富,歡迎關注

tail

很多新手習慣用 cat,但對於大文件,cat 會導致屏幕刷屏,還容易把終端卡死。tail 才是實時監控的神器。

真實場景 A:服務發版啓動監控

每次發版重啓服務時,我們都需要確認 Spring Boot 是否啓動成功,或者有沒有初始化報錯。

# -f (follow):實時追加顯示文件尾部內容
tail -f logs/application.log

真實場景 B:配合測試復現 Bug

測試同學説:我現在點一下按鈕,你看看後台有沒有報錯。

此時不需要看歷史日誌,只需要盯着最新的輸出。

# 只看最後 200 行,並保持實時刷新,避免被歷史日誌干擾
tail -n 200 -f logs/application.log

less

如果需要查看之前的日誌,推薦使用 less。不同於 vim 會一次性加載整個文件佔用大量內存,less 是按需加載,打開幾個 G 的文件也極其流暢,且支持向後回溯。

真實場景:追查某筆客訴訂單

運營反饋:剛才 10 點左右,訂單號 ORD12345678 支付失敗了。

你需要從日誌末尾開始,往前反向查找這個訂單號。

less logs/application.log

進入界面後的操作流:

  1. Shift + G 先跳到日誌最末尾(因為報錯通常發生在最近)。
  2. ?ORD12345678 輸入問號+訂單號,向上反向搜索
  3. n:如果當前這行不是關鍵信息,按 n 繼續向上找上一次出現的位置。
  4. Shift + F 如果看着看着,日誌又更新了,按這個組合鍵可以讓 less 進入類似 tail -f 的實時滾動模式;按 Ctrl + C 退回瀏覽模式。

grep

grep 是最常用的搜索命令,但在實際業務中,簡單的關鍵詞搜索往往不夠用。

真實場景 A:還原報錯現場(關鍵)

只看到 NullPointerException 這一行往往無法定位問題,我們需要知道報錯前的請求參數是什麼,報錯後的堆棧信息是什麼。

此時必須配合 -C (Context) 參數。

# 搜索異常關鍵字,並顯示該行 "前後各 20 行"
grep -C 20 "NullPointerException" logs/application.log

真實場景 B:全鏈路追蹤 TraceId

微服務我們通常會通過 TraceId 串聯請求。日誌文件可能發生了滾動(Rolling),變成了 app.logapp.log.1app.log.2

我們需要在所有日誌文件中搜索同一個 TraceId。

# 搜索當前目錄下所有以 app.log 開頭的文件
grep "TraceId-20251219001" logs/app.log*

真實場景 C:統計異常頻次

老闆問:“Redis 超時異常今天到底發生了多少次?是偶發還是大規模?”

不需要數數,直接統計行數。

# -c (count):只統計匹配的行數
grep -c "RedisConnectionException" logs/application.log

真實場景 D:排除干擾噪音

排查問題時,日誌裏充斥着大量無關的 INFO 心跳日誌或健康檢查日誌,嚴重干擾視線。

# -v (invert):顯示不包含 "HealthCheck" 的所有行
grep -v "HealthCheck" logs/application.log

sed

有時候日誌非常大,例如有 10GB,grep 搜出來的內容依然過多。如果我們明確知道生產事故發生在 14:00 到 14:05 之間,該怎麼辦?

下載整個日誌不現實,sed 可以幫我們把這段時間的日誌單獨出來,保存成一個小文件慢慢分析。

真實場景:導出事故時間窗口的日誌

# 語法:sed -n '/開始時間/,/結束時間/p' 源文件 > 目標文件
# 注意:時間格式必須和日誌裏的格式完全一致
sed -n '/2025-12-19 14:00/,/2025-12-19 14:05/p' logs/application.log > error_segment.log

這樣你就得到了一個只有幾 MB 的 error_segment.log,這時候再下載到本地分析,或者發給同事,都非常方便。

Awk

awk 擅長處理列數據,對於格式規範的日誌,如 Nginx 訪問日誌、Apache 日誌,它可以直接在服務器上生成簡報。

真實場景 A:遭到攻擊,查找惡意 IP

服務突然報警 CPU 飆升,懷疑遭到 CC 攻擊或爬蟲抓取,我們需要分析 Nginx 日誌,找出訪問量最高的 IP。

假設日誌格式第一列是 IP:

# 1. awk '{print $1}':提取第一列(IP)
# 2. sort:排序,把相同的 IP 排在一起
# 3. uniq -c:去重並統計每個 IP 出現的次數
# 4. sort -nr:按次數(n)倒序(r)排列
# 5. head -n 10:取前 10 名

awk '{print $1}' access.log | sort | uniq -c | sort -nr | head -n 10

真實場景 B:找出響應最慢的接口

Nginx 日誌中通常記錄了響應時間,假設在最後一列,我們想把響應時間超過 1 秒的請求找出來。

# $NF 代表最後一列
# 打印所有響應時間大於 1 秒的 URL(假設 URL 在第 7 列)
awk '$NF > 1.000 {print $7, $NF}' access.log

總結

舉的例子都是我常用的,建議把這幾個命令刻在腦子裏或者收藏本文,下次遇到生產問題,對着場景直接複製粘貼就ok了。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.