系統與 程序記錄 只是其中兩個最關鍵的優勢,來自於 systemd。當記錄分散在整個系統中、跨越多個應用程式,並由不同的程序和守護行程(daemon)處理時,要解讀它們可能會是一項挑戰。Systemd 提供了一個集中式的解決方案,將所有核心和使用者空間的程序記錄管理在一個稱為日誌(journal)的編譯媒介中。您可以在我們關於如何使用 systemctl 管理 systemd 服務和單元的教學中了解更多關於 systemd 的資訊。日誌中由服務、initrd、核心等產生的所有訊息都由 journal 守護行程處理。本指南的目的是說明如何使用 journalctl 存取和操作日誌的資料。
基本前提
無論訊息可能源自何處,systemd 的主要宗旨之一就是允許對其進行集中管理。由於許多啟動程序和大部分服務管理都由 systemd 程序處理,因此記錄的編譯和存取方式應該要標準化。journald 將來自任何可用來源的資料收集到一個包羅萬象的工具中,並以二進位格式儲存。這使得資料可以隨時用於動態且簡單的操作。
這種方法有幾個關鍵優勢。透過一個集中收集所有資料的地方,管理員可以篩選並僅顯示他們需要的資料。例如,使用者可以檢視三次系統啟動前的啟動資料。這也意味著可以按順序記錄相關服務的條目,並更有效地追蹤它們之間的通訊問題。
得益於二進位儲存,資料可以根據使用者當時的需求以多種輸出格式顯示。例如,每日記錄可以以標準 syslog 格式檢視。但如果您需要以圖表形式呈現服務中斷的趨勢,則可以將該條目輸出為 JSON 物件,使其適用於圖表繪製服務。當您需要根據情境需求變更格式時,不需要進行轉換,因為資料是二進位的,而不是以純文字寫入磁碟。
根據個人需求,您可以將 systemd 日誌與現有的 syslog 一起實作,或者它可以取代其功能。Systemd 甚至可以補充現有的記錄機制。例如,單一系統上的多個服務可以透過 systemd 日誌將其編譯的資料交織在單一系統上。
設定系統時間
預設情況下,Systemd 將以本地時間顯示結果,這是二進位日誌記錄在檢視記錄時的一項優勢。或者,也可以在 UTC 中檢視它們。因此,在開始使用日誌記錄之前,務必確保時區設定正確。為此,systemd 配備了一個名為 timedatectl 的工具。我們首先透過使用 list-timezones 選項顯示列表,來查看有哪些時區可用:
|
1 |
timedatectl list-timezones |
在找到與您伺服器位置相符的時區後,可以使用 set-timezone 選項來設定時區:
|
1 |
sudo timedatectl set-timezone zone |
要測試並驗證時區現在是否正常顯示,您可以單獨使用 timedatectl 指令,或者加上 'status':

第一行描繪了本地時間。此行應包含您本地區域的正確時間。
一般記錄檢視
journalctl 指令將允許您檢視 journald 守護行程收集的記錄。當您使用 journalctl 時,系統中的每個日誌條目都將顯示在螢幕頁面中,最舊的條目列在最上方。然而,完整的資料列表將長達數萬行。
|
1 |
journalctl |

使用過標準 syslog 記錄的人會覺得這種格式很熟悉,但請務必記住,與 syslog 方法不同,此數據編譯包含來自許多來源的資訊。日誌將包括早期開機程序、initrd 和核心(kernel),以及應用程式標準錯誤。
現在已設定本地時間,所有條目都將以本地時間的時間戳記開始,並且適用於目前系統上儲存的每個日誌,所有邏輯都將透過使用此新資訊來顯示。然而,您並不局限於本地時間。使用 –utc 旗標,您也可以顯示 UTC 時間戳記:
|
1 |
journalctl --utc |
按時間篩選日誌
擁有如此多的數據是非常棒的,但要梳理並吸收它,更不用說在腦海中處理它,可能是一項艱鉅的任務。考慮到這一點,我們來到了 journalctl 功能最重要的部分:篩選。
顯示目前開機的日誌
如果您正在日誌中尋找最新一次重新開機的數據,可以使用帶有 -b 旗標的 journalctl 功能。這將顯示系統最近一次重新開機的所有相關日誌資訊。此命令將允許您尋找並管理與目前工作環境最相關的資訊:
|
1 |
journalctl -b |
如果檢視者選擇不評估每個單獨的條目,journalctl 將顯示一天以上的開機記錄,並在 journalctl 中以方便的「Reboot」分隔線顯示。這有助於在邏輯上區分不同開機工作階段的資訊以供審查:
|
1 2 3 |
. . . -- Reboot -- . . . |
過去的開機資訊
雖然顯示目前的開機資訊通常最有用,但在某些情況下,過去的開機資訊也會有所幫助。Journal 會儲存多次先前開機的資訊,因此 journalctl 可以輕鬆顯示任何時間段的資訊。
某些發行版停用了儲存先前開機資訊的功能,而其他發行版則預設啟用。要啟用持久性開機資訊,可以透過輸入以下內容建立用於儲存日誌的目錄來實現:
|
1 |
sudo mkdir -p /var/log/journal |
或者,您可以按以下方式編輯日誌設定檔:
|
1 |
sudo nano /etc/systemd/journald.conf |
在 [Journal] 區段下將 Storage= 選項設定為「persistent」將啟用持久性記錄:

啟用此功能後,journalctl 會提供某些命令,協助您將這些開機記錄指定為劃分單位。要檢視 journald 中已記錄的開機,您可以使用 journalctl 的 –list-boots option 選項:
|
1 |
journalctl --list-boots |
![]()
如圖所示,每次開機都將列在各自的行中,第一欄按從最舊到最新的順序反映先前的開機。如果需要更絕對的參考,第二欄包含開機識別碼。之後,列出了兩個時間規格。第一欄或第二欄的資訊可用於顯示特定開機的日誌資訊。例如,您可以將 -b 旗標與相對開機指標 -1 結合使用,以檢視倒數第二次重新開機的資訊:
|
1 |
journalctl -b -1 |
同樣地,第二欄的開機 ID 也可以用這種方式使用:
|
1 |
journalctl -b 54342de612174d269b66f1d5eb098abb |
時間範圍
透過 ID 查看開機記錄是其中一個選項,但通常更有用的是能夠透過過去的時間範圍來引用先前的開機記錄,而該時間範圍不一定需要與特定的開機次數對齊。例如,在處理不常重啟的長期運行伺服器時,這就非常實用。時間限制的篩選可以使用任意的時間限制來進行。這將僅顯示落在特定時間範圍內的重啟資訊。此時間範圍的參數是使用 –since 和 –until 選項來指定的。時間選項有多種可用格式。絕對時間值格式如下:
|
1 |
YYYY-MM-DD HH:MM:SS |
因此,如果您想查看自 2015 年 1 月 10 日下午 5:15 以來的所有開機記錄,請輸入以下命令:
|
1 |
journalctl --since "2015-01-10 17:15:00" |
如果省略了任何組成部分,則有內建的預設值。此外,如果省略了日期,則預設為當前日期。如果缺少時間部分,則預設為午夜 (00:00:00)。如果您在時間部分省略了秒數,它們將預設為該分鐘的起始點 (00):
|
1 |
journalctl --since "2015-01-10" --until "2015-01-11 03:00" |
日誌系統可以理解與時間相關的快捷方式,例如「today」(今天)、「tomorrow」(明天)、「yesterday」(昨天)和「now」(現在)。像 ago 這樣的單字,結合前置限定符「-」和「+」,可以用來構建句子類型的命令:
|
1 |
journalctl --since yesterday |
如果您收到服務中斷的通知(該中斷始於 9:00),並且想要檢查截至一小時前的日誌記錄,您可以使用以下命令來執行此操作:
|
1 |
journalctl --since 09:00 --until "1 hour ago" |
顯而易見,定義一個彈性的時間範圍來查看所需的條目是非常簡單的。
依感興趣的訊息篩選
除了透過時間限制來篩選日誌之外,還可以根據感興趣的服務組件來篩選數據。Systemd 提供了幾種方法來做到這一點。
依單元
可以說最實用的篩選參數是依感興趣的單元。要依單元進行篩選,可以使用 -u 選項。例如,如果您希望查看與 Nginx 單元相關的所有日誌,請輸入以下命令:
|
1 |
journalctl -u nginx.service |
在實際情況下,您會希望將此功能與時間篩選器結合使用,以便顯示感興趣的行。如果您想檢查上述服務以及它今天的運行狀況,可以執行以下操作:
|
1 |
journalctl -u nginx.service --since today |
當利用日誌系統編譯來自多個單元(特別是協作單元)的記錄之能力時,這特別有用。如果 Nginx 程序連接到 PHP-FPN 單元以進行動態內容處理,則可以透過指定這兩個單元來按時間順序合併條目:
|
1 |
journalctl -u nginx.service -u php-fpm.service --since today |
這可以極大地幫助記錄程式之間的互動,並使偵錯系統(而非單個程序)變得更加容易。
依群組 ID、程序或使用者
許多服務會啟動大量的子程序(child processes)來執行特定工作。如果已知特定程序的 ID,也可以透過指定 _PID 欄位來進行篩選。如果感興趣的 PID 是 8088,可以執行以下操作:
|
1 |
journalctl _PID=8088 |
您可能還想查看來自特定群組或特定使用者的日誌條目。這可以透過使用 _GID 和 _UID 篩選器來實現。如果網頁伺服器在 www-data 使用者下運行,以下命令可以找到所需的 ID:
|
1 |
id -u www-data |

使用該 ID,您就可以查看符合條件的日誌結果:
|
1 |
journalctl _UID=33 --since today |
Systemd 提供了許多可用於篩選的欄位。某些欄位是由 journald 根據記錄時從系統收集的資訊來套用的,而其他欄位則是由目前正在記錄的程序傳遞過來的。
前置限定詞 _PID 表示該資訊是在記錄時從系統收集的。日誌(journal)會在記錄過程中自動記錄並為 PID 建立索引,以便稍後進行篩選。要了解可用的日誌欄位,您可以輸入:
|
1 |
man systemd.journal-fields |
我們將在稍後的指南中討論其中的一些內容,但現在,我們將先介紹與這些欄位相關的其他一些實用選項。如果您想查看特定日誌欄位的所有可用值,可以使用 -F 選項。如果您想查看 systemd 日誌中包含哪些群組 ID(group ID),可以執行以下操作:
|
1 |
journalctl -F _GID |

這可以透過提供日誌群組 ID 欄位所儲存的完整值清單,來協助建立篩選條件。
依組件路徑
也可以透過提供路徑位置來進行篩選。如果該路徑指向可執行檔,則當 journalctl 中的條目涉及該可執行檔時,就會顯示這些條目。如果感興趣的可執行檔是「bash」,您可以輸入:
|
1 |
journalctl /bin/bash |
雖然有時無法做到,但如果該可執行檔的單元(unit)可用,它可以產生一種更清晰且包含更多資訊的篩選方法。
顯示核心訊息
通常在 dmesg 輸出中找到的核心訊息也可以從日誌中檢索。為了僅顯示這些訊息,我們在命令中使用 -k 或 -dmesg 旗標:
|
1 |
journalctl -k |
預設情況下會顯示當前開機的訊息,但也可以像前面提到的那樣使用選擇旗標來指定先前的開機。如果您正在尋找五次開機前的訊息,輸入以下內容將為您提供所需的結果:
|
1 |
journalctl -k -b 5 |
依優先等級
系統管理員通常偏好依優先等級進行篩選。低優先等級的記錄雖然通常有助於檢視,但可能會令人困惑且包含許多干擾,從而降低分析時的易讀性。在 journalctl 中使用 -p 選項將僅顯示指定優先等級的訊息,並篩選掉任何其他優先等級。如果您希望顯示錯誤等級或以上的條目,請輸入以下內容:
|
1 |
journalctl -p err -b |
該命令將返回所有被標記為錯誤(error)、警報(alert)、緊急(emergency)或嚴重(critical)的訊息,日誌使用的是標準 syslog 訊息等級。優先等級是根據數值定義的,從最高到最低排序:
- 0: emerg
- 1: alert
- 2: crit
- 3: err
- 4: warning
- 5: notice
- 6: info
- 7: debug
上述任何一項都可以與 -p 選項交替使用。選擇上述任何一個優先等級將篩選出該等級及以上的所有優先等級。
修改日誌中的顯示
除了使用篩選來選擇條目之外,我們還有其他修改輸出的方法,以調整 journalctl 的顯示來滿足我們的需求。
截斷/展開輸出
我們可以透過調整 journalctl 縮小或展開資料來調整輸出的檢視。journalctl 的預設設定是顯示完整條目,將較長的條目延伸到螢幕右側。您可以透過向右方向鍵滾動來檢視完整條目。使用者可能希望截斷輸出,在超出螢幕的行上以省略號表示。對此,可以使用 –no-full 選項:
|
1 |
journalctl --no-full |

或者,您也可以使用 -a 旗標,允許顯示所有內容,不論其長度或是否包含不可列印字元:
|
1 |
journalctl -a |
輸出至標準輸出
Journalctl 預設會將輸出顯示在分頁器中,但如果您希望使用文字編輯工具來處理數據,您可能需要將輸出生成到標準輸出選項。您可以使用 –no-pager 選項來實現此目的:
|
1 |
journalctl --no-pager |
根據使用者的需求,這可以重定向到磁碟上的檔案或處理公用程式。
輸出格式
當數據以更易於閱讀的格式呈現時,通常更容易進行解析。日誌提供了多種顯示選項,使用 -o 限定符後跟特定的格式。
如果您希望將日誌條目輸出為 JSON 格式,可以按照以下方式進行:
|
1 |
journalctl -b -u nginx -o json |
![]()
這種策略在解析公用程式時特別有用。json-pretty 格式在將數據結構傳遞給 JSON 取用端之前,能更好地顯示數據結構:
|
1 |
journalctl -b -u nginx -o json-pretty |

您可以使用幾種格式進行顯示:
- cat:僅顯示訊息欄位本身。
- export:適用於傳輸或備份的二進位格式。
- json:標準 JSON,每行一個條目。
- json-pretty:格式化為更易於人類閱讀的 JSON
- json-sse:包裝為與伺服器傳送事件相容的 JSON 格式輸出
- short:預設的 syslog 樣式輸出
- short-iso:預設格式,並增加了顯示 ISO 8601 牆上時鐘時間戳記的功能。
- short-monotonic:帶有單調時間戳記的預設格式。
- short-precise:具有微秒精度的預設格式
- verbose:顯示該條目可用的每個日誌欄位,包括通常在內部隱藏的欄位。
上述選項允許日誌以您偏好的格式顯示。
活動程序監控
日誌允許存取監控活動或近期活動的功能,而無需使用其他工具。您可以使用帶有「tail」功能的 journalctl 指令來執行此操作。
-
顯示近期日誌
顯示 -n 選項(其運作方式與 tail -n 指令完全相同),將允許顯示特定數量的記錄:
|
1 |
journalctl -n |
您希望顯示的條目數量可以透過在 -n 限定符後指定特定數字來設定:
|
1 |
journalctl -n 20 |
-
追蹤日誌
您還可以使用 -f 旗標,在日誌寫入系統時主動追蹤它們。這與 tail -f 指令的運作方式相同:
|
1 |
journalctl -f |
日誌維護
日誌確實會佔用空間。這值得探討,可能需要清除一些較舊的日誌以釋放空間。
尋找目前的磁碟使用量
–disk-usage 旗標可以幫助識別日誌目前在磁碟上佔用了多少空間:
|
1 |
journalctl --disk-usage |

刪除舊日誌
使用 systemd 版本 218(及後續版本),您可以透過兩種不同的方式縮減日誌。一種是 –vacuum-size 選項。這可以透過指定大小來縮減日誌。換句話說,較舊的條目將從日誌中清除,直到佔用的空間達到要求的參數:
|
1 |
sudo journalctl --vacuum-size=1G |
–vacuum-time 選項可以透過指定截止時間來縮減日誌佔用的空間,超過該時間的任何條目都將被刪除,而在指定時間之後建立的條目則會被保留。如果您只想保留過去一年的條目,可以使用:
|
1 |
sudo journalctl --vacuum-time=1years |
限制日誌膨脹
您也可以限制日誌佔用的空間量。這可以透過編輯 /etc/systemd.journald.conf 檔案來完成。可以使用以下任何方法來限制日誌的增長:
- SystemMaxUse=:表示允許日誌在永續儲存中使用的最大磁碟空間。
- SystemKeepFree=:表示在永續儲存中新增日誌實體時,應保留多少剩餘空間。
- SystemMaxFileSize=: 指定在持久性儲存空間中,日誌檔案在進行輪替前允許增長到的最大容量。
- RuntimeMaxUse=: 指定在揮發性儲存空間(在 /run 檔案系統內)中允許使用的最大磁碟空間。
- RuntimeKeepFree=: 當將資料寫入揮發性儲存空間時,此參數指定必須保留給其他用途的空間大小(在 /run 檔案系統內)。
- RuntimeMaxFileSize=: 指定在揮發性儲存空間(在 /run 檔案系統內)中,單個日誌檔案在需要進行輪替前可以佔用的最大空間。
這些選項都有助於控制日誌所佔用的儲存空間。需要注意的重要一點是,SystemMaxFileSize 和 RuntimeMaxFileSize 選項將以已封存的檔案為目標來達到指定的限制。在解讀清理(vacuuming)操作後的檔案數量時,務必記住這一點。
結論
顯而易見,systemd 日誌是一個非常實用的工具,其大部分優勢源於日誌’的集中化特性以及記錄的大量中介資料。透過使用 journalctl 指令,可以充分利用日誌的豐富功能,從而提供一種更簡單的方法來對應用程式元件進行關聯性除錯,以及進行廣泛的系統分析。
祝您運算愉快!
留言
目前尚無留言。成為第一個留言的人吧。