首頁>技術>

1. 前言

對大部分的人來說,解決 Bug 都是依靠關鍵字去日誌去定位問題!

在除錯情況下,我們可以實時在控制檯檢視日誌;但對於部署到伺服器上的應用,日誌都存放在伺服器某個目錄下,沒法透過本地檢視到

這種情況下,就需要我們先登入伺服器,然後進入到日誌目錄資料夾,最後透過日誌檔案去定位問題;如果涉及到 K8s 容器,可能還需要使用 kubectl 命令進入到服務對應的容器中,進入到日誌目錄,才能開始定位問題,這一切顯得非常繁瑣且低效

本篇文章介紹一款 Python 依賴庫:pexpect,作為一款命令列自動化工具,它可以幫助我們一鍵獲取日誌,快速定位問題!

2. pexpect 介紹

pexpect 是 Python 語言實現的類 Expect 的一種實現,透過產生子應用程式並控制它們,透過期望模式對子應用程式的輸出做出相應處理

它主要對人機對話進行模擬,來實現一些自動化的場景

比如:用來和 SSH、FTP、PASSWD、Telnet 等命令列程式進行自動化互動

在使用之前,我們先安裝依賴包

# 安裝依賴庫pip3 install pexpect

3. 實戰一下

我們以從伺服器 K8S 容器獲取日誌為例進行講解

3-1.SSH 登入

首先,初始化使用 pexpect 模擬 SSH 遠端登入伺服器

import pexpectPROMPT = ['# ', '>>> ', '> ', '\$ ']def login_with_pexpect(): """ 登入-pexpect :return: """ # 埠號 port = ** # 使用者名稱 user = ** # 密碼 pwd = ** # ip地址 ip = ** ssh_cmd = "ssh -p {} {}@{}".format(port,user,ip) # 指定登入命令,拿到程式操作控制代碼 child = pexpect.spawn(ssh_cmd, timeout=60, encoding='utf-8') # 提示輸入密碼的字元出現,否則超時 ret = child.expect([pexpect.TIMEOUT, '[P|p]assword: '], timeout=10) # 匹配成功後,輸入密碼,執行登陸操作 if ret == 1: # 傳送密碼 child.sendline(pwd) child.expect(PROMPT) return child else: print('登入失敗!')

其中

pexpect.spawn() :用於執行一個程式,並返回一個操作控制代碼

該方法常見的 3 個引數如下:

第一個引數是待執行的命令第二個引數指定超時時間,程式執行後的輸出檢查,如果指定時間內沒有匹配到結果,就會拋異常第三個引數用於設定編碼格式

child.expect() :對輸出結果,利用正則表示式進行關鍵字匹配

程式碼中的含義是在 10s 內等待出現關鍵字 '[P|p]assword: '

最後,如果匹配的結果為 1,使用 sendline() 方法傳送帶回車符的字串,模擬密碼的輸入,完成登入操作

3-2.封裝傳送命令

接下來,我們將操作控制代碼傳送命令進行一次封裝,並獲取返回結果

def send_command(child, cmd, expected_content=None, timeout=10): """ 傳送一條命令,並列印結果 :param expected_content: :param child: :param cmd: :return: """ # 傳送一條命令 if expected_content is None: expected_content = ["#"] child.sendline(cmd) # 期望有命令列提示字元出現 child.expect(expected_content, timeout=timeout) # 將之前的內容都輸出 result = child.before return result

需要指出的是,child.before 用於獲取到匹配到關鍵字為止,快取裡面已有的全部資料

3-3.進入容器 pod 日誌目錄

使用上面的方法,透過 kubectl 進入到對應的容器日誌目錄

# 登入pod容器exec_enter_pod = 'kubectl -n %s exec -it %s bash' % (env, pod_name)# 進入容器send_command(child, exec_enter_pod)# 進入到日誌目錄send_command(child, "cd logs", expected_content='tomcat/logs#')

3-4.獲取日誌內容

最後我們只需要組成獲取日誌的命令

比如:使用 grep/tail 命令組成一個提取日誌檔案的命令

然後使用控制代碼物件傳送這條命令

最後,對返回內容進行清洗即可

4. 最後

文中使用 pexpect 實現了一個非常簡單的場景

事實上,大部分人機對話自動化互動都可以由它來實現,比如,下載日誌、實時配置、遠端打包下載等

25
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 前端效能最佳化清單,超詳細,一篇文章足矣,建議看完(1)