Linux系統監控與分析工具Sysdig:安裝與使用

Sysdig是一個超級有用的系統工具,運行在Linux環境上,比 strace、tcpdump、lsof 加起來還強大。Sysdig可用來捕獲系統狀態信息,保存數據並進行過濾和分析。本文主要介紹在Linux上安裝Sysdig的基本步驟,然後以監控某個特定程序的系統調用(system call)爲例來簡單演示一下它的使用。注意,本文中例子的演示環境爲Ubuntu 18.04。

如果你在這個過程中遇到下面這兩個雷,本文也會告訴你解決它們的方法。

The repository 'http://ppa.launchpad.net/t-tujikawa/ppa/ubuntu bionic Release' does not have a Release file.

The repository 'http://ppa.launchpad.net/tualatrix//ppa/ubuntu bionic Release' does not have a Release file.

 

一、在Ubuntu系統上安裝Sysdig(方法與排雷)

首先,Sysdig的安裝方法主要參考官方提供的手冊【1】,在Ubuntu的自動安裝,只要在命令行窗口中輸入下面這行命令即可:

curl -s https://s3.amazonaws.com/download.draios.com/stable/install-sysdig | sudo bash

但是,我使用這行指令之後,得到了如下圖所示的一則錯誤信息:

根據【2】中給出的解答,這主要是因爲Ubuntu系統中存在着錯誤或者陳舊的PPA倉庫,所以如果你也遇到這個問題(當然這種情況並不是一定的),首先就需要查找並移除上述提示中給出的PPA倉庫。具體來說,打開【Software&Updates】,然後選擇【Other Software】選項卡,如下圖所示。

然後把上面那些錯誤信息中提到的PPA 倉庫uncheck掉(如下圖所示),並reload。

接下來,在命令行窗口中使用本文最開始給出的那行用於自動安裝的命令,系統給出如下圖所示的結果,表示你已經成功安裝好SysDig了!

 

二、使用Csysdig進行系統監控和分析

Sysdig是一個命令行工具,但是安裝它的同時,其實還附帶了一個具有交互式用戶界面的實用工具——Csysdig,Csysdig提供了與Sysdig命令行相同的功能。在演示Sysdig的使用之前,不妨先來看看Csysdig的使用。

與Sysdig命令一樣, Csysdig命令可以執行實時監視,並可以將事件捕獲到文件中以供以後分析。Csysdig樣子看起來有點像top,提供了每兩秒刷新一次的更實用的系統數據實時視圖。要查看示例,請在命令行窗口中輸入以下命令:

sudo csysdig

這將打開如下圖所示的界面, 界面顯示受監控主機上的所有用戶和應用程序生成的事件數據。

Csysdig同時支持鼠標點擊和快捷鍵兩種操作。例如,當前系統中運行的程序可能很多,你想快速檢索到某個特定的自己感興趣的程序,可以使用【CTRL+F】。如下圖所示,然後搜索你想匹配的關鍵詞(例如程序名),Csysdig將自動定位到被搜索的程序上。

此外,你可能還注意到在界面的底部有幾個按鈕,提供了不同的功能。對於每個按鈕,按鈕的左側都有相應的鍵盤快捷鍵或熱鍵。按兩次快捷鍵將返回上一個窗口(按第二次返回之前窗口的效果與按下ESC鍵相同,例如按第二次【CTRL+F】或者直接按【ESC】都回回到之前的窗口界面)。最值得注意的按鈕是【Views】,它類似於收集的指標類別Csysdig。其中提供的off the shelf的視圖有29個,包括:進程,系統調用,線程,容器,進程CPU,頁面錯誤,文件和目錄等,如下圖所示:

要退出Csysdig,可以直接使用【CTRL+C】。

當然,Csysdig中還有很多其他功能等待你去發掘與嘗試(例如,如何使用篩選“Filter”功能等)。文獻【3】中提供了更多的一些入門級別的內容,對於有興趣的讀者可以作爲延伸閱讀的材料。

 

三、Sysdig跟蹤程序的系統調用(system calls)

系統調用(system calls)是(以Linux爲範例)學習操作系統時,不可或缺的內容。簡單來說,系統調用是程序與操作系統之間交互的主要手段。系統調用看起來有點像函數調用,例如你用objdump(或者IDA pro)查看程序的彙編代碼時,系統調用常常以“call _XXX”這樣的形式出現。但實際上,系統調用要比普通的函數調用更復雜一些,因爲但凡用到system calls時,都需要進行一個user mode與kernel mode之間的切換(這基本上應該是大學裏操作系統上所需要講授的內容)。

 

來看兩個C語言程序,它們都是helloworld程序的實現:

helloworld_1.c

#include<stdio.h>

int main(){
    printf("Hello World!\n");
    return 0;
}

helloworld_2.c

#include <unistd.h>

int main(){
    write(1, "Hello World!\n", 13);
    return 0;
}

在Linux下編譯並運行上述兩個程序,所得之結果是相同的,即在屏幕上輸出“Hello World!”字符串。然後,你可以使用strace,它是Linux環境下的一款程序調試工具,用來監察一個應用程序所使用的系統調用。例如在命令行窗口中輸入:

strace ./helloworld1.out
strace ./helloworld2.out

從輸出結果來看,你會發現二者都調用了write這個system call。當你編寫一個helloworld程序時,你會用到printf()函數,它來自libc。但printf()內部其實是通過對函數write()的調用(和封裝)實現的。函數write()來自glibc(即The GNU C Library)。這裏的glibc是GNU發佈的libc庫,即C運行庫。glibc 和 libc 都是 Linux 下的 C 函數庫。區別在於,libc 是 Linux 下的 ANSI C 函數庫;glibc 是 Linux 下的 GUN C 函數庫。由於 Linux 是用 C 語言寫的,所以 Linux 的一些操作是用 C 語言實現的,因此,GUN 組織開發了一個 C 語言的庫以便讓我們更好的利用 C 語言開發基於 Linux 操作系統的程序,於是也就有了glib。它也是Linux系統中最底層的API,幾乎其它任何運行庫都會依賴於glibc。程序員通常不必關心繫統調用(system calls),因爲there are functions in the GNU C Library to do virtually everything that system calls do. These functions work by making system calls themselves. 也就是說glibc中的函數,例如write(),會implicitly使用系統調用write(注意我用是否加括號來區別二者,但你應該明白glibc中的write()函數work by making system call write itself)。如果你想跳過這層封裝從而避免隱式的調用(there are times when you want to make a system call explicitly),對此,glibc裏面還提供了syscall()這個函數,它同樣被聲明在頭文件unistd.h中。

 

下面嘗試用Sysdig來跟蹤程序“helloworld1.out”的system calls。這時我們需要通過設置參數“proc.name”方法來進行過濾(當然這不是唯一的過濾方法),從而只跟蹤單個進程。例如在命令行窗口A中輸入:

sudo sysdig proc.name=helloworld1.out

然後在另外一個命令行窗口B中運行“helloworld1.out”程序,則命令行窗口A中會輸出如下結果:

這也就是該程序涉及的系統調用。這裏需要注意的是,“proc.name”後面跟的是進程名稱。通常,Linux系統內部使用的是進程ID,它是一個整數。而Linux系統中設置進程名稱時,The name can be up to 16 bytes long, including the terminating null byte. If the length of the string, including the terminating null byte, exceeds 16 bytes, the string is silently truncated. 也就是說,這裏的進程名稱不能超過15個字符(不包括結尾的空字符)。否則,Sysdig將無法找到目標進程。有興趣的讀者,可以嘗試把“helloworld1.out”改成“helloworld123.out”看看會發生什麼變化。

當然,把所有內容都輸出到屏幕上,可能不利於日後分析(如果內容很長的話),所以我們可以把信息存到文件裏,例如:

sudo sysdig -w sysdig-trace-file.scap proc.name=helloworld1.out

如果需要讀取已經保存起來的記錄,則可以使用下面的命令:

sudo sysdig -r sysdig-trace-file.scap

Sysdig還可以用來監控很多有意思的東西,例如在頭文件unistd.h中,聲明瞭函數chdir(),這其實是對系統調用chdir的封裝。該系統調用的作用是切換當前進程的工作目錄。所以,如果你在一個命令行窗口A中執行下面的指令,那麼所有切換目錄的行爲都會被報告出來:

sysdig evt.type=chdir

如下圖所示,另開一個命令行窗口B:

如果在命令行窗口B中切換工作目錄,那麼命令行窗口A中將實時監控並輸出相應的系統調用:

Sysdig的功能是非常強大的,這裏演示的不過是其九牛之一毛,僅做拋磚引玉之用。有興趣的讀者可以參閱其官方文檔以瞭解更多。


參考文獻

【1】How to Install Sysdig for Linux

【2】Ask_Ubuntu上的討論帖

【3】入門系列之使用Sysdig監視您的Ubuntu 16.04系統

【4】The Fascinating World of Linux System Calls

【5】Examples: cool things you can do with sysdig commands

 

【本文完】

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章