1. 程式人生 > >使用AutoHotkey分析日誌檔案,得到分析報告。

使用AutoHotkey分析日誌檔案,得到分析報告。

使用 AutoHotkey 分析日誌檔案,得到分析報告。

由程式自動生成的日誌檔案一般有固定的格式,而且檔案大小通常比較大。當需要分析這樣的日誌檔案,需要用肉眼在成千上萬條記錄裡面尋找異常,那將是大海撈針,十分費力費時。由於這樣的日誌檔案具有固定格式,我們可以過濾掉不關心的記錄,留下有用的記錄。我們可以通過程式來實現這種過濾,但是代價十分高,因為每種日誌檔案的格式並不一樣,不可能每遇到一種日誌就寫一個程式吧!這時, AutoHotkey 就可以大顯身手了,利用它的檔案讀寫功能,簡單快捷,無需編譯,隨時可以修改,隨時可以執行。下面展示一下,用 AutoHotkey 分析日誌的方法:

需求:

一個 PDF TXT 的程式,會產生一個結果日誌,記錄了每個 PDF 檔案轉換的結果。記錄格式如下:


這個程式運行了一天一夜之後,該日誌檔案達到 1M 大小,記錄達到 10000 多行。當我想檢視有多少記錄因某幾種原因而轉換失敗時,發現大部分記錄都是轉換成功,失敗的也大部分是因為某一個我並不關心的原因。而這些記錄,嚴重干擾了我尋找重要的記錄,因此我想把不關心的記錄過濾掉,比如將所有轉換成功的記錄行去掉,但提取其檔案的 ID ,最後將所有轉換成功的檔案 ID 歸類到一些,寫到檔案最尾部。而關心的內容則不過濾掉,顯示在檔案的前面,如下圖所示:

這張圖裡把不關心的記錄歸類在一起了,其他的記錄則原樣保留以便分析。下面開始介紹

AutoHotkey 的實現指令碼程式,看看需要多少文字!

AutoHotkey 實現指令碼:

一、首先,寫兩個處理字串的函式,方便提取 PDF 正文 ID

StrLeft2Sub( ) 在給定的字串中尋找某個子串,將其左邊的文字擷取返回。如:

StrLeft2Sub( String, “@”) 返回的值為 cwin

類似地 StrRight2Sub( String, “@” ) 返回值為 live.cn

二、接下來,寫一個開啟檔案的對話方塊,讓使用者選擇需要轉換的檔案,儲存到變數 var_SelectedFile

這條語句的效果如下:

三、選擇好需要生成報告的日誌檔案之後,得到生成的報告的檔名。

如: temp.log 生成的報告名為 temp_rpt.log

四、下面讀取所選擇的日誌檔案(假設為 temp.log ),並且將分析的結果寫到 ( 假設為 temp_rpt.log )

讀取文字檔案有三種方法:

1、 FileRead, OutputVar, Filename
直接將整個檔案讀取到記憶體中,當日志文件較大時,這樣很浪費記憶體。

2、 FileReadLine, OutputVar, Filename, LineNum
一次讀取一行文字,需要指定行數。該命令開啟檔案,讀取一行文字,之後就關閉檔案了。當要遍歷一個行數很多的文字檔案時,這種方法不適合。

3、 Loop, Read, InputFile [, OutputFile]
同時開啟輸入和輸出檔案,然後迴圈遍歷輸入檔案,直到處理完畢,關閉檔案。在遍歷過程中,檔案保持開啟,檔案處理效率較高。我們選擇這種方式處理日誌檔案。

這段程式碼遍歷所選擇的檔案,每次讀取一行文字到 A_LoopReadLine 。第一行中的 %var_SelectedFile% 即是變數所選擇的檔案路徑, %var_outfile% 則是輸出檔案的路徑。 Var_SelectedFile var_outfile 是儲存檔案路徑的變數,在其前後加 % 號,表示取變數的值。

var_sub := StrRight2Sub( A_LoopReadLine, "] :" )

將讀取出來的一行字串,擷取時間後面的字串儲存到變數 var_sub 中,為提取正文 ID 作準備。

下面是完整的分析日誌的程式碼:

說明一下:

1 、“ ifinstring var_sub, 轉換成功 ”的含義是:如果字串 var_sub 中包含了文字“轉換成功”

2 var_sucess = %var_sucess%%var_id% 將正文 ID 的值增加到 var_sucess 變數中

3 FileAppend, %A_LoopReadLine%`n Loop 迴圈中的 FileAppend 命令,將沒有被過濾掉的行原樣輸出到 var_outfle 檔案中。

4 if var_sucess <> 表示 if ( var_sucess != “” )

5 Loop 迴圈外的 FileAppend 命令,將歸類好的成功轉換的正文 ID 字串 var_sucess 附加到指定檔案的末尾。注意,在這裡要指明附加的目標檔案為 %var_outfile%

好了,指令碼寫完了,可以直接運行了!怎麼樣,是不是很簡捷呀!