如何使用Journalctl查看並操作Systemd日誌

內容簡介

作爲最具吸引力的優勢,systemd擁有強大的處理與系統日誌記錄功能。在使用其它工具時,日誌往往被分散在整套系統當中,由不同的守護進程及進程負責處理,這意味着我們很難跨越多種應用程序對其內容進行解讀。

相比之下,systemd嘗試提供一套集中化管理方案,從而統一打理全部內核及用戶級進程的日誌信息。這套系統能夠收集並管理日誌內容,而這也就是我們所熟知的journal。

Journal的實現歸功於journald守護進程,其負責處理由內核、initrd以及服務等產生的信息。在今天的教程中,我們將探討如何使用journalctl工具,並在其幫助下訪問並操作journal內部的數據。

總體思路

Systemd journal的深層驅動力在於以集中方式管理對來自任意來源的日誌信息。由於大部分引導進程都是由systemd進程處理的,因此我們有理由以標準化方式實現日誌的收集與訪問。其中jornald守護進程會收集全部來源的數據並將其以二進制格式加以存儲,從而輕鬆實現動態操作。

這種作法能夠實現多種收益。通過單一工具與數據交互,管理員能夠以動態方式顯示日誌數據。另外,我們也可以輕鬆查看歷史引導數據,或者將日誌條目同其它相關服務加以結合,從而 完成通信問題調試。

將日誌數據以二進制形式存儲還意味着這些數據可根據需求隨時以二進制輸出格式顯示。例如,大家可以通過標準syslog格式查看日誌以實現日常管理,並在需要使用圖形服務時將各條目作爲JSON對象交由圖形化服務處理。由於數據不會以純文本形式被寫入磁盤,因此我們無需進行任何格式轉換。

大家可以將systemd journal與現有syslog方案配合使用,也可利用其替代現有syslog功能,具體取決於實際需求。儘管systemd journal足以涵蓋大部分管理工作需求,但其同時也能夠補充現有日誌記錄機制。例如,大家可以建立一套集中式syslog服務器,從而對來自多臺服務器的數據進行編譯;或者,我們也能夠利用systemd journal將來自多項服務的日誌彙總在單一系統當中。

設置系統時間

使用二進制journal的一大好處在於,它能夠以UTC或者本地時間顯示日誌記錄。在默認情況下,systemd會以本地時間顯示結果。

有鑑於此,在我們開始使用journal之前,首先要確保時區得到正確設置。Systemd套件中還提供一款timedatectl工具,專門用於解決此類問題。

首先,利用list-timezones選項查看可用時區:

timedatectl list-timezones
  • 1
  • 2

結果將列出系統上可用的全部時區。而後選擇與服務器所在地相匹配的項目,並使用set-timezone選項加以設置:

sudo timedatectl set-timezone zone
  • 1
  • 2

爲了確保我們的設備使用正確的時間,可單獨使用timedatectl命令或者添加status選項。顯示結果如下:

timedatectl status

Local time: Thu 2015-02-05 14:08:06 EST
Universal time: Thu 2015-02-05 19:08:06 UTC
    RTC time: Thu 2015-02-05 19:08:06
   Time zone: America/New_York (EST, -0500)
 NTP enabled: no
NTP synchronized: no
RTC in local TZ: no
  DST active: n/a
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

第一行所示應爲正確時間。

基礎日誌查看

要查看journald守護進程收集到的日誌,可使用journalctl命令。

在單獨使用時,系統中的每個journal條目都會被顯示在單一pager中供我們瀏覽。條目時間越早,排列越靠前:

journalctl

-- Logs begin at Tue 2015-02-03 21:48:52 UTC, end at Tue 2015-02-03 22:29:38 UTC. --
Feb 03 21:48:52 localhost.localdomain systemd-journal[243]: Runtime journal is using 6.2M (max allowed 49.
Feb 03 21:48:52 localhost.localdomain systemd-journal[243]: Runtime journal is using 6.2M (max allowed 49.
Feb 03 21:48:52 localhost.localdomain systemd-journald[139]: Received SIGTERM from PID 1 (systemd).
Feb 03 21:48:52 localhost.localdomain kernel: audit: type=1404 audit(1423000132.274:2): enforcing=1 old_en
Feb 03 21:48:52 localhost.localdomain kernel: SELinux: 2048 avtab hash slots, 104131 rules.
Feb 03 21:48:52 localhost.localdomain kernel: SELinux: 2048 avtab hash slots, 104131 rules.
Feb 03 21:48:52 localhost.localdomain kernel: input: ImExPS/2 Generic Explorer Mouse as /devices/platform/
Feb 03 21:48:52 localhost.localdomain kernel: SELinux:  8 users, 102 roles, 4976 types, 294 bools, 1 sens,
Feb 03 21:48:52 localhost.localdomain kernel: SELinux:  83 classes, 104131 rules

. . .
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

大家可以一頁頁進行翻看,不過如果系統運行時間較長,那麼systemd中的日誌也將成千上萬,這也證明了journal數據庫中可觀的數據量。

其格式與標準的syslog日誌非常相似。然而,其收集數據的來源較syslog要豐富得多。其中包含有來自先前引導進程、內核、initrd以及應用程序標準錯誤與輸出的日誌。這一切都可在journal中查看到。

大家可能還注意到,全部時間戳都以本地時間爲準。由於已經爲系統正確設置了本地時間,所以顯示的時間戳也都準確無誤。

如果大家希望以UTC顯示時間戳,則可使用–utc標記:

journalctl --utc
  • 1
  • 2

按時間進行journal過濾

瀏覽大量數據當然有其作用,但信息量過於龐大則會讓我們很難甚至根本不可能找到真正重要的內容。因此,journalctl提供了極爲關鍵的過濾選項。

顯示當前引導進程下的日誌

其中最常用的就是-b標記了,其將顯示全部最近一次重新引導後收集到的journal條目。

journalctl -b
  • 1
  • 2

通過這種方式,我們能夠識別並管理源自當前環境下的信息。

如果不使用這項功能,而且顯示的引導數量超過一天,那麼journalctl會在在系統關閉處插入說明:

. . .

-- Reboot --

. . .
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

這種方式能夠幫助我們有效區分來自不同引導會話的信息。

過往引導記錄

大家通常只需要查看當前引導環境下的信息,但有時候查看過往引導記錄也非常必要。Journal能夠保存大量過往引導信息,從而允許journalctl輕鬆顯示相關內容。

有些版本會在默認情況下保存過往引導信息,而有些則默認禁用這項功能。要啓用此功能,可以使用以下功能以創建用於存儲journal信息的目錄:

- sudo mkdir -p /var/log/journal
  • 1
  • 2

或者直接編輯journal配置文件:

- sudo nano /etc/systemd/journald.conf
  • 1
  • 2

在[Journal]區段下將Storage=選項設定爲“persistent”以啓用持久記錄:

/etc/systemd/journald.conf

. . .
[Journal]
Storage=persistent
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

當啓用保存過往引導信息功能後,journalctl會提供額外命令以幫助大家將各引導記錄作爲獨立單元操作。要查看Journald中已經記錄的引導信息,可使用–list-boots選項:

journalctl --list-boots

-2 caf0524a1d394ce0bdbcff75b94444fe Tue 2015-02-03 21:48:52 UTCTue 2015-02-03 22:17:00 UTC
-1 13883d180dc0420db0abcb5fa26d6198 Tue 2015-02-03 22:17:03 UTCTue 2015-02-03 22:19:08 UTC
 0 bed718b17a73415fade0e4e7f4bea609 Tue 2015-02-03 22:19:12 UTCTue 2015-02-03 23:01:01 UTC
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

這裏每次引導都將顯示爲一行。第一列可用於在journalctl中引用該次引導。如果大家需要更爲準確的引用方式,則可在第二列中找到引導ID。末尾記錄的兩次時間爲當次引導的開始與結束時間。

要顯示這些引導中的具體信息,則可使用第一或者第二列提供的信息。

例如,要查看上次引導的journal記錄,則可使用-1相對指針配合-b標記:

journalctl -b -1
  • 1
  • 2

另外,也可以使用引導ID:

journalctl -b caf0524a1d394ce0bdbcff75b94444fe
  • 1
  • 2

時間窗

按照引導環境查看日誌條目當然非常重要,但我們往往還需要使用與系統引導無關的時間窗作爲瀏覽基準。這種情況在長期運行的服務器當中較爲常見。

大家可以利用–since與–until選項設定時間段,二者分別負責說明給定時間之前與之後的記錄。

時間值可以多種格式輸出。對於絕對時間值,大家可以使用以下格式:

YYYY-MM-DD HH:MM:SS
  • 1
  • 2

例如,我們可以通過以下命令查看全部2015年1月10日下午5:15之後的條目:

journalctl --since "2015-01-10 17:15:00"
  • 1
  • 2

如果以上格式中的某些組成部分未進行填寫,系統會直接進行默認填充。例如,如果日期部分未填寫,則會直接顯示當前日期。如果時間部分未填寫,則缺省使用“00:00:00”(午夜)。第二字段亦可留空,默認值爲“00”:

journalctl --since "2015-01-10" --until "2015-01-11 03:00"
  • 1
  • 2

另外,journal還能夠理解部分相對值及命名簡寫。例如,大家可以使用“yesterday”、“today”、“tomorrow”或者“now”等表達。另外,我們也可以使用“-”或者“+”設定相對值,或者使用“ago”之前的表達。

獲取昨天數據的命令如下:

journalctl –since yesterday

要獲得早9:00到一小時前這段時間內的報告,可使用以下命令:

journalctl --since 09:00 --until "1 hour ago"
  • 1
  • 2

如大家所見,時間窗的過濾機制非常靈活且易用。

按信息類型過濾

現在我們要探討如何利用感興趣的服務或者組件類型實現過濾。Systemd journal同樣提供多種方式供大家選擇。

按單元

最常用的此類過濾方式當數按單元過濾了。我們可以使用-u選項實現這一效果。

例如,要查看系統上全部來自Nginx單元的日誌,可使用以下命令:

journalctl -u nginx.service
  • 1
  • 2

一般來講,我們可能需要同時按單元與時間進行信息過濾。例如,檢查今天某項服務的運行狀態:

journalctl -u nginx.service --since today
  • 1
  • 2

我們還可以充分發揮journal查看多種單元信息的優勢。例如,如果我們的Nginx進程接入某個PHP-FPM單元以處理動態內容,則可將這兩個單元合併並獲取按時間排序的查詢結果:

journalctl -u nginx.service -u php-fpm.service --since today
  • 1
  • 2

這種能力對於不同程序間交互及系統調試顯然非常重要。

按進程、用戶或者羣組ID

由於某些服務當中包含多個子進程,因此如果我們希望通過進程ID實現查詢,也可以使用相關過濾機制。

這裏需要指定_PID字段。例如,如果PID爲8088,則可輸入:

journalctl _PID=8088
  • 1
  • 2

有時候我們可能希望顯示全部來自特定用戶或者羣組的日誌條目,這就需要使用_UID或者_GID。例如,如果大家的Web服務器運行在www-data用戶下,則可這樣找到該用戶ID:

id -u www-data

33
  • 1
  • 2
  • 3
  • 4

接下來,我們可以使用該ID返回過濾後的journal結果:

journalctl _UID=33 --since today
  • 1
  • 2

Systemd journal擁有多種可實現過濾功能的字段。其中一些來自被記錄的進程,有些則由journald用於自系統中收集特定時間段內的日誌。

之前提到的_PID屬於後一種。Journal會自動記錄並檢索進程PID,以備日後過濾之用。大家可以查看當前全部可用journal字段:

man systemd.journal-fields
  • 1
  • 2

下面來看針對這些字段的過濾機制。-F選項可用於顯示特定journal字段內的全部可用值。

例如,要查看systemd journal擁有條目的羣組ID,可使用以下命令:

journalctl -F _GID

32
99
102
133
81
84
100
0
124
87
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

其將顯示全部journal已經存儲至羣組ID字段內的值,並可用於未來的過濾需求。

按組件路徑

我們也可以提供路徑位置以實現過濾。

如果該路徑指向某個可執行文件,則journalctl會顯示與該可執行文件相關的全部條目。例如,要找到與bash可執行文件相關的條目:

journalctl /usr/bin/bash
  • 1
  • 2

一般來講,如果某個單元可用於該可執行文件,那麼此方法會更爲明確且能夠提供更好的相關信息(與子進程相關的條目等)。但有時候,這種作法則無法奏效。

顯示內核信息

內核信息通常存在於dmesg輸出結果中,journal同樣可對其進行檢索。要只顯示此類信息,可添加-k或者–dmesg標記:

journalctl -k
  • 1
  • 2

默認情況下,其會顯示當前引導環境下的全部內核信息。大家也可以使用常規的引導選擇標記對此前的引導記錄進行查詢。例如,要查詢五次之前引導環境的信息:

journalctl -k -b -5
  • 1
  • 2

按優先級

管理員們可能感興趣的另一種過濾機制爲信息優先級。儘管以更爲詳盡的方式查看日誌也很有必要,不過在理解現有信息時,低優先級日誌往往會分散我們的注意力並導致理解混亂。

大家可以使用journalctl配合-p選項顯示特定優先級的信息,從而過濾掉優先級較低的信息。

例如,只顯示錯誤級別或者更高的日誌條目:

journalctl -p err -b
  • 1
  • 2

這將只顯示被標記爲錯誤、嚴重、警告或者緊急級別的信息。Journal的這種實現方式與標準syslog信息在級別上是一致的。大家可以使用優先級名稱或者其相關量化值。以下各數字爲由最高到最低優先級:

  • 0: emerg
  • 1: alert
  • 2: crit
  • 3: err
  • 4: warning
  • 5: notice
  • 6: info
  • 7: debug

以上爲可在-p選項中使用的數字或者名稱。選定某一優先級會顯示等級與之等同以及更高的信息。

修改journal顯示內容

到這裏,過濾部分已經介紹完畢。我們也可以使用多種方式對輸出結果進行修改,從而調整journalctl的顯示內容。

截斷或者擴大輸出結果

我們可以縮小或者擴大輸出結果,從而調整journalctl的顯示方式。

在默認情況下,journalctl會在pager內顯示各條目,並通過右箭頭鍵訪問其信息。

如果大家希望截斷輸出內容,向其中插入省略號以代表被移除的信息,則可使用–no-full選項:

journalctl --no-full

. . .

Feb 04 20:54:13 journalme sshd[937]: Failed password for root from 83.234.207.60...h2
Feb 04 20:54:13 journalme sshd[937]: Connection closed by 83.234.207.60 [preauth]
Feb 04 20:54:13 journalme sshd[937]: PAM 2 more authentication failures; logname...ot
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

大家也可以要求其顯示全部信息,無論其是否包含不可輸出的字符。具體方式爲添加-a標記:

journalctl -a
  • 1
  • 2

標準輸出結果

默認情況下,journalctl會在pager內顯示輸出結果以便於查閱。如果大家希望利用文本操作工具對數據進行處理,則可能需要使用標準格式。在這種情況下,我們需要使用–no-pager選項:

journalclt --no-pager
  • 1
  • 2

這樣相關結果即可根據需要被重新定向至磁盤上的文件或者處理工具當中。

輸出格式

如果大家需要對journal條目進行處理,則可能需要使用更易使用的格式以簡化數據解析工作。幸運的是,journal能夠以多種格式進行顯示,只須添加-o選項加格式說明即可。

例如,我們可以將journal條目輸出爲JSON格式:

journalctl -b -u nginx -o json

{ "__CURSOR" : "s=13a21661cf4948289c63075db6c25c00;i=116f1;b=81b58db8fd9046ab9f847ddb82a2fa2d;m=19f0daa;t=50e33c33587ae;x=e307daadb4858635", "__REALTIME_TIMESTAMP" : "1422990364739502", "__MONOTONIC_TIMESTAMP" : "27200938", "_BOOT_ID" : "81b58db8fd9046ab9f847ddb82a2fa2d", "PRIORITY" : "6", "_UID" : "0", "_GID" : "0", "_CAP_EFFECTIVE" : "3fffffffff", "_MACHINE_ID" : "752737531a9d1a9c1e3cb52a4ab967ee", "_HOSTNAME" : "desktop", "SYSLOG_FACILITY" : "3", "CODE_FILE" : "src/core/unit.c", "CODE_LINE" : "1402", "CODE_FUNCTION" : "unit_status_log_starting_stopping_reloading", "SYSLOG_IDENTIFIER" : "systemd", "MESSAGE_ID" : "7d4958e842da4a758f6c1cdc7b36dcc5", "_TRANSPORT" : "journal", "_PID" : "1", "_COMM" : "systemd", "_EXE" : "/usr/lib/systemd/systemd", "_CMDLINE" : "/usr/lib/systemd/systemd", "_SYSTEMD_CGROUP" : "/", "UNIT" : "nginx.service", "MESSAGE" : "Starting A high performance web server and a reverse proxy server...", "_SOURCE_REALTIME_TIMESTAMP" : "1422990364737973" }

. . .
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

這種方式對於工具解析非常重要。大家也可以使用json-pretty格式以更好地處理數據結構:

journalctl -b -u nginx -o json-pretty

{
"__CURSOR" : "s=13a21661cf4948289c63075db6c25c00;i=116f1;b=81b58db8fd9046ab9f847ddb82a2fa2d;m=19f0daa;t=50e33c33587ae;x=e307daadb4858635",
"__REALTIME_TIMESTAMP" : "1422990364739502",
"__MONOTONIC_TIMESTAMP" : "27200938",
"_BOOT_ID" : "81b58db8fd9046ab9f847ddb82a2fa2d",
"PRIORITY" : "6",
"_UID" : "0",
"_GID" : "0",
"_CAP_EFFECTIVE" : "3fffffffff",
"_MACHINE_ID" : "752737531a9d1a9c1e3cb52a4ab967ee",
"_HOSTNAME" : "desktop",
"SYSLOG_FACILITY" : "3",
"CODE_FILE" : "src/core/unit.c",
"CODE_LINE" : "1402",
"CODE_FUNCTION" : "unit_status_log_starting_stopping_reloading",
"SYSLOG_IDENTIFIER" : "systemd",
"MESSAGE_ID" : "7d4958e842da4a758f6c1cdc7b36dcc5",
"_TRANSPORT" : "journal",
"_PID" : "1",
"_COMM" : "systemd",
"_EXE" : "/usr/lib/systemd/systemd",
"_CMDLINE" : "/usr/lib/systemd/systemd",
"_SYSTEMD_CGROUP" : "/",
"UNIT" : "nginx.service",
"MESSAGE" : "Starting A high performance web server and a reverse proxy server...",
"_SOURCE_REALTIME_TIMESTAMP" : "1422990364737973"
}

. . .
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

以下爲可用於顯示的各類格式:

  • cat: 只顯示信息字段本身。
  • export: 適合傳輸或備份的二進制格式。
  • json: 標準JSON,每行一個條目。
  • json-pretty: JSON格式,適合人類閱讀習慣。
  • json-sse: JSON格式,經過打包以兼容server-sent事件。
  • short: 默認syslog類輸出格式。
  • short-iso: 默認格式,強調顯示ISO 8601掛鐘時間戳。
  • short-monotonic: 默認格式,提供普通時間戳。
  • short-precise: 默認格式,提供微秒級精度。
  • verbose: 顯示該條目的全部可用journal字段,包括通常被內部隱藏的字段。

這些選項允許大家以最適合需求的格式顯示journal條目。

活動進程監控

Journalctl命令還能夠幫助管理員以類似於tail的方式監控活動或近期進程。這項功能內置於journalctl當中,允許大家在無需藉助其它工具的前提下實現訪問。

顯示近期日誌

要顯示特定數量的記錄,大家可以使用-n選項,具體方式爲tail -n。

默認情況下,其會顯示最近十條記錄:

journalctl -n
  • 1
  • 2

大家可以在-n之後指定要查看的條目數量:

journalctl -n 20
  • 1
  • 2

追蹤日誌

要主動追蹤當前正在編寫的日誌,大家可以使用-f標記。方式同樣爲tail -f:

journalctl -f
  • 1
  • 2

Journal維護

存儲這麼多數據當然會帶來巨大壓力,因此我們還需要了解如何清理部分陳舊日誌以釋放存儲空間。

瞭解現有磁盤使用量

大家可以利用–disk-usage標記查看journal的當前磁盤使用量:

journalctl --disk-usage

Journals take up 8.0M on disk.
  • 1
  • 2
  • 3
  • 4

刪除舊有日誌

如果大家打算對journal記錄進行清理,則可使用兩種不同方式(適用於systemd 218及更高版本)。

如果使用–vacuum-size選項,則可硬性指定日誌的總體體積,意味着其會不斷刪除舊有記錄直到所佔容量符合要求:

sudo journalctl --vacuum-size=1G
  • 1
  • 2

另一種方式則是使用–vacuum-time選項。任何早於這一時間點的條目都將被刪除。

例如,去年之後的條目才能保留:

sudo journalctl --vacuum-time=1years
  • 1
  • 2

限定Journal擴展

大家可以配置自己的服務器以限定journal所能佔用的最高容量。要實現這一點,我們需要編輯/etc/systemd/journald.conf文件。

以下條目可用於限定journal體積的膨脹速度:

  • SystemMaxUse=: 指定journal所能使用的最高持久存儲容量。
  • SystemKeepFree=: 指定journal在添加新條目時需要保留的剩餘空間。
  • SystemMaxFileSize=: 控制單一journal文件大小,符合要求方可被轉爲持久存儲。
  • RuntimeMaxUse=: 指定易失性存儲中的最大可用磁盤容量(/run文件系統之內)。
  • RuntimeKeepFree=: 指定向易失性存儲內寫入數據時爲其它應用保留的空間量(/run文件系統之內)。
  • RuntimeMaxFileSize=: 指定單一journal文件可佔用的最大易失性存儲容量(/run文件系統之內)。

通過設置上述值,大家可以控制journald對服務器空間的消耗及保留方式。

總結

到這裏,systemd journal對系統及應用數據的收集與管理機制就介紹完畢了。其出色的靈活性源自將廣泛的元數據自動記錄至集中化日誌之內。另外,journalctl命令則顯著簡化了journal的使用方式,從而讓更多管理員得以利用它完成面向不同應用組件的分析與相關調試工作。

本文來源自DigitalOcean Community。英文原文:How To Use Journalctl to View and Manipulate Systemd Logs By Justin Ellingwood

翻譯:diradw

發佈了17 篇原創文章 · 獲贊 2 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章