您好,登錄后才能下訂單哦!
作為最具吸引力的優勢, 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
結果將列出系統上可用的全部時區。而后選擇與服務器所在地相匹配的項目,并使用set-timezone選項加以設置:
sudo timedatectl set-timezone zone
為了確保我們的設備使用正確的時間,可單獨使用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
第一行所示應為正確時間。
要查看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 . . .
大家可以一頁頁進行翻看,不過如果系統運行時間較長,那么systemd中的日志也將成千上萬,這也證明了journal數據庫中可觀的數據量。
其格式與標準的syslog日志非常相似。然而,其收集數據的來源較syslog要豐富得多。其中包含有來自先前引導進程、內核、initrd以及應用程序標準錯誤與輸出的日志。這一切都可在journal中查看到。
大家可能還注意到,全部時間戳都以本地時間為準。由于已經為系統正確設置了本地時間,所以顯示的時間戳也都準確無誤。
如果大家希望以UTC顯示時間戳,則可使用–utc標記:
journalctl --utc
瀏覽大量數據當然有其作用,但信息量過于龐大則會讓我們很難甚至根本不可能找到真正重要的內容。因此,journalctl提供了極為關鍵的過濾選項。
其中最常用的就是-b標記了,其將顯示全部最近一次重新引導后收集到的journal條目。
journalctl -b
通過這種方式,我們能夠識別并管理源自當前環境下的信息。
如果不使用這項功能,而且顯示的引導數量超過一天,那么journalctl會在在系統關閉處插入說明:
. . . -- Reboot -- . . .
這種方式能夠幫助我們有效區分來自不同引導會話的信息。
大家通常只需要查看當前引導環境下的信息,但有時候查看過往引導記錄也非常必要。Journal能夠保存大量過往引導信息,從而允許journalctl輕松顯示相關內容。
有些版本會在默認情況下保存過往引導信息,而有些則默認禁用這項功能。要啟用此功能,可以使用以下功能以創建用于存儲journal信息的目錄:
sudo mkdir -p /var/log/journal
或者直接編輯journal配置文件:
sudo nano /etc/systemd/journald.conf
在[Journal]區段下將Storage=選項設定為“persistent”以啟用持久記錄:
/etc/systemd/journald.conf . . . [Journal] Storage=persistent
當啟用保存過往引導信息功能后,journalctl會提供額外命令以幫助大家將各引導記錄作為獨立單元操作。要查看Journald中已經記錄的引導信息,可使用–list-boots選項:
journalctl --list-boots -2 caf0524a1d394ce0bdbcff75b94444fe Tue 2015-02-03 21:48:52 UTC—Tue 2015-02-03 22:17:00 UTC -1 13883d180dc0420db0abcb5fa26d6198 Tue 2015-02-03 22:17:03 UTC—Tue 2015-02-03 22:19:08 UTC 0 bed718b17a73415fade0e4e7f4bea609 Tue 2015-02-03 22:19:12 UTC—Tue 2015-02-03 23:01:01 UTC
這里每次引導都將顯示為一行。第一列可用于在journalctl中引用該次引導。如果大家需要更為準確的引用方式,則可在第二列中找到引導ID。末尾記錄的兩次時間為當次引導的開始與結束時間。
要顯示這些引導中的具體信息,則可使用第一或者第二列提供的信息。
例如,要查看上次引導的journal記錄,則可使用-1相對指針配合-b標記:
journalctl -b -1
另外,也可以使用引導ID:
journalctl -b caf0524a1d394ce0bdbcff75b94444fe
按照引導環境查看日志條目當然非常重要,但我們往往還需要使用與系統引導無關的時間窗作為瀏覽基準。這種情況在長期運行的服務器當中較為常見。
大家可以利用–since與–until選項設定時間段,二者分別負責說明給定時間之前與之后的記錄。
時間值可以多種格式輸出。對于絕對時間值,大家可以使用以下格式:
YYYY-MM-DD HH:MM:SS
例如,我們可以通過以下命令查看全部2015年1月10日下午5:15之后的條目:
journalctl --since "2015-01-10 17:15:00"
如果以上格式中的某些組成部分未進行填寫,系統會直接進行默認填充。例如,如果日期部分未填寫,則會直接顯示當前日期。如果時間部分未填寫,則缺省使用“00:00:00”(午夜)。第二字段亦可留空,默認值為“00”:
journalctl --since "2015-01-10" --until "2015-01-11 03:00"
另外,journal還能夠理解部分相對值及命名簡寫。例如,大家可以使用“yesterday”、“today”、“tomorrow”或者“now”等表達。另外,我們也可以使用“-”或者“+”設定相對值,或者使用“ago”之前的表達。
獲取昨天數據的命令如下:
journalctl –since yesterday
要獲得早9:00到一小時前這段時間內的報告,可使用以下命令:
journalctl --since 09:00 --until "1 hour ago"
如大家所見,時間窗的過濾機制非常靈活且易用。
現在我們要探討如何利用感興趣的服務或者組件類型實現過濾。Systemd journal同樣提供多種方式供大家選擇。
最常用的此類過濾方式當數按單元過濾了。我們可以使用-u選項實現這一效果。
例如,要查看系統上全部來自 Nginx 單元的日志,可使用以下命令:
journalctl -u nginx.service
一般來講,我們可能需要同時按單元與時間進行信息過濾。例如,檢查今天某項服務的運行狀態:
journalctl -u nginx.service --since today
我們還可以充分發揮journal查看多種單元信息的優勢。例如,如果我們的Nginx進程接入某個 PHP-FPM 單元以處理動態內容,則可將這兩個單元合并并獲取按時間排序的查詢結果:
journalctl -u nginx.service -u php-fpm.service --since today
這種能力對于不同程序間交互及系統調試顯然非常重要。
由于某些服務當中包含多個子進程,因此如果我們希望通過進程ID實現查詢,也可以使用相關過濾機制。
這里需要指定_PID字段。例如,如果PID為8088,則可輸入:
journalctl _PID=8088
有時候我們可能希望顯示全部來自特定用戶或者群組的日志條目,這就需要使用_UID或者_GID。例如,如果大家的Web服務器運行在www-data用戶下,則可這樣找到該用戶ID:
id -u www-data 33
接下來,我們可以使用該ID返回過濾后的journal結果:
journalctl _UID=33 --since today
Systemd journal擁有多種可實現過濾功能的字段。其中一些來自被記錄的進程,有些則由journald用于自系統中收集特定時間段內的日志。
之前提到的_PID屬于后一種。Journal會自動記錄并檢索進程PID,以備日后過濾之用。大家可以查看當前全部可用journal字段:
man systemd.journal-fields
下面來看針對這些字段的過濾機制。-F選項可用于顯示特定journal字段內的全部可用值。
例如,要查看systemd journal擁有條目的群組ID,可使用以下命令:
journalctl -F _GID 32 99 102 133 81 84 100 124 87
其將顯示全部journal已經存儲至群組ID字段內的值,并可用于未來的過濾需求。
我們也可以提供路徑位置以實現過濾。
如果該路徑指向某個可執行文件,則journalctl會顯示與該可執行文件相關的全部條目。例如,要找到與bash可執行文件相關的條目:
journalctl /usr/bin/bash
一般來講,如果某個單元可用于該可執行文件,那么此方法會更為明確且能夠提供更好的相關信息(與子進程相關的條目等)。但有時候,這種作法則無法奏效。
內核信息通常存在于dmesg輸出結果中,journal同樣可對其進行檢索。要只顯示此類信息,可添加-k或者–dmesg標記:
journalctl -k
默認情況下,其會顯示當前引導環境下的全部內核信息。大家也可以使用常規的引導選擇標記對此前的引導記錄進行查詢。例如,要查詢五次之前引導環境的信息:
journalctl -k -b -5
管理員們可能感興趣的另一種過濾機制為信息優先級。盡管以更為詳盡的方式查看日志也很有必要,不過在理解現有信息時,低優先級日志往往會分散我們的注意力并導致理解混亂。
大家可以使用journalctl配合-p選項顯示特定優先級的信息,從而過濾掉優先級較低的信息。
例如,只顯示錯誤級別或者更高的日志條目:
journalctl -p err -b
這將只顯示被標記為錯誤、嚴重、警告或者緊急級別的信息。Journal的這種實現方式與標準syslog信息在級別上是一致的。大家可以使用優先級名稱或者其相關量化值。以下各數字為由最高到最低優先級:
0: emerg 1: alert 2: crit 3: err 4: warning 5: notice 6: info 7: debug以上為可在-p選項中使用的數字或者名稱。選定某一優先級會顯示等級與之等同以及更高的信息。
到這里,過濾部分已經介紹完畢。我們也可以使用多種方式對輸出結果進行修改,從而調整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...h3 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
大家也可以要求其顯示全部信息,無論其是否包含不可輸出的字符。具體方式為添加-a標記:
journalctl -a
默認情況下,journalctl會在pager內顯示輸出結果以便于查閱。如果大家希望利用文本操作工具對數據進行處理,則可能需要使用標準格式。在這種情況下,我們需要使用–no-pager選項:
journalclt --no-pager
這樣相關結果即可根據需要被重新定向至磁盤上的文件或者處理工具當中。
如果大家需要對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" } . . .
這種方式對于工具解析非常重要。大家也可以使用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" } . . .
以下為可用于顯示的各類格式:
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
大家可以在-n之后指定要查看的條目數量:
journalctl -n 20
要主動追蹤當前正在編寫的日志,大家可以使用-f標記。方式同樣為tail -f:
journalctl -f
存儲這么多數據當然會帶來巨大壓力,因此我們還需要了解如何清理部分陳舊日志以釋放存儲空間。
大家可以利用–disk-usage標記查看journal的當前磁盤使用量:
journalctl --disk-usage Journals take up 8.0M on disk.
如果大家打算對journal記錄進行清理,則可使用兩種不同方式(適用于systemd 218及更高版本)。
如果使用–vacuum-size選項,則可硬性指定日志的總體體積,意味著其會不斷刪除舊有記錄直到所占容量符合要求:
sudo journalctl --vacuum-size=1G
另一種方式則是使用–vacuum-time選項。任何早于這一時間點的條目都將被刪除。
例如,去年之后的條目才能保留:
sudo journalctl --vacuum-time=1years
大家可以配置自己的服務器以限定journal所能占用的最高容量。要實現這一點,我們需要編輯/etc/systemd/journald.conf文件。
以下條目可用于限定journal體積的膨脹速度:
SystemMaxUse=
: 指定journal所能使用的最高持久存儲容量。
SystemKeepFree=
: 指定journal在添加新條目時需要保留的剩余空間。
SystemMaxFileSize=
: 控制單一journal文件大小,符合要求方可被轉為持久存儲。
RuntimeMaxUse=
: 指定易失性存儲中的最大可用磁盤容量(/run文件系統之內)。
RuntimeKeepFree=
: 指定向易失性存儲內寫入數據時為其它應用保留的空間量(/run文件系統之內)。
RuntimeMaxFileSize=
: 指定單一journal文件可占用的最大易失性存儲容量(/run文件系統之內)。
通過設置上述值,大家可以控制journald對服務器空間的消耗及保留方式。
總結
到這里,systemd journal對系統及應用數據的收集與管理機制就介紹完畢了。其出色的靈活性源自將廣泛的元數據自動記錄至集中化日志之內。另外,journalctl命令則顯著簡化了journal的使用方式,從而讓更多管理員得以利用它完成面向不同應用組件的分析與相關調試工作。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。