python-日誌分析小工具
一、涉及知識點
【1】with open(file) as f:方法
(1)檔案讀取;該方法可以try catch報錯,並且不需要close關閉檔案
【2】讀取檔案行方法:
(1)f.readline():直接按行讀取,會讀取出來空行(\n)
(2)f.read().splitlines():先讀取所有資料,按行切割,後續用if line:可以排除掉空行
【3】find()方法:
(1)能找到字串的開始位置,如果要切割兩個字串之間的資料,需要加上第一個字串的長度
【4】str型別轉換成浮點型資料:
(1)需要注意字串是否有空行、換行等,如果有空行、換行會轉換失敗,需要先處理後再進行轉化
【5】字串前面的字母含義:
(1)u''----表示後面字串以 Unicode 格式 進行編碼,一般用在含有中文字串前面,防止因為原始碼儲存格式問題,導致再次使用時出現亂碼。
(2)r''----表示字串去掉轉義字元,例如 r'aaa\n' 輸出 aaa\n;例如'aaa\n' 輸出 aaa 換行
(3)f''----表示字串中的表示式用大括號 {} 包起來,它會將變數或表示式計算後的值替換進去:sql = f'insert into test(prod_code,prod_name) values({line})'
(4)b''----表示字串型別是bytes型別
【6】字串百分號作用:u'0ms-100ms: %s個,%.2f%%' % (num_100,num_100/totle_num*100)
(1)%s--替代字串;%d--替代整數;%f 浮點型
(2)第二個% 表示替代前面的位置,如果替代的資料有多個,則用()括起來:'%s %d' % (a,b)
(3)第三個% 是用來轉義作用
二、實現步驟:
【1】建立四個列表
【2】開啟檔案,讀取每行資料
【3】如果行內容不為空,查詢字串1,加上字串1的長度
【4】查詢字元2位置,切割字串,獲取字串1和字串2之間的目標字串
【5】轉換字串型別為浮點型
【6】判斷浮點型資料的大小,放入到list列表中
【7】計算
三、具體實現
# 一、需求: # web後臺系統日誌檔案記錄了每個服務請求的處理時間 # 開發一個工具,統計處理時間在 # 0-100ms # 100ms-500ms # 500ms-1s # >1s # 的請求各有多少,百分比為多少 # 二、日誌格式: # 0118_11:32:36 !! op takes 0.02299999064 seconds : function:GET /api/mgr/sq_mgr/ # 三、分析: # 1、取出日誌檔案中每一次處理請求的時間,存入相應的容器內(list) # 2、計算每個時間段容器(list)中處理時間的個數,並計算百分比 # 四、虛擬碼: # 1、建立四個list 對應儲存不同的響應時間段 # 1.1取出時間字串 # 1.1.1 先找到要擷取欄位的前一個值的位置:idx1 # 1.1.2 找到idx1後面的第一個空格的位置:idx2 # 這段日誌【idx1:idx2】---兩個座標之間就是要獲取的欄位 # 1.2判斷值,放入對應容器內 # 2、讀入日誌檔案readlines每行內容,依次存入列表 # 建立四個list list100 = [] list100_500 = [] list500_1000 = [] list1000=[] # 開啟檔案讀取(預設是讀)(為什麼用with open方法---該方法可以try catch報錯,並且不需要關閉close檔案) with open('/Users/panshaoying/Desktop/database/data/logtest.log') as f: # 全部讀取出來,然後切割每一行資料(如果這邊用f.readlines()讀取資料,如果有空行,則空行也會被讀取出來,後續資料處理會有問題) lines = f.read().splitlines() # 如果讀取的行不為空 for line in lines: if line: # 找到op takes 的位置,find方法找到的是字串的開始位置,所以要增加字串的長度 dx1 = line.find('takes ') + len('takes ') # 找到目標欄位的後一個位置 dx2 = line.find(' seconds') # 字串擷取,從dx1開始到dx2(不包含dx2)位置的字串 responsetimestr = line[dx1:dx2].strip() # print(type(responsetimestr)) # print(responsetimestr) # # 獲得的欄位是字串,要進行資料大小判斷,需要將字串轉換成浮點型資料 rts = float(responsetimestr) # 將獲取到的資料放到對應的list內 if rts < 0.1: list100.append(rts) elif 0.1 <= rts < 0.5: list100_500.append(rts) elif 0.5 <= rts < 1: list500_1000.append(rts) elif 1 <= rts: list1000.append(rts) # print(list100) # print(list100_500) # print(list500_1000) # print(list1000) # 計算每個列表的長度,就是每個列表內有多少個數據 num_100 = len(list100) num_100_500 = len(list100_500) num_500_1000 = len(list500_1000) num_1000 = len(list1000) # 計算總數,轉換成float,等下除法的時候精度更大 totle_num = float(num_100 + num_100_500 + num_500_1000 + num_1000) # 計算百分比 # u''----表示後面字串以 Unicode 格式 進行編碼,一般用在含有中文字串前面,防止因為原始碼儲存格式問題,導致再次使用時出現亂碼。 # r''----表示字串去掉轉義字元,例如 r'aaa\n' 輸出 aaa\n;例如'aaa\n' 輸出 aaa 換行 # f''----表示字串中的表示式用大括號 {} 包起來,它會將變數或表示式計算後的值替換進去:sql = f'insert into test(prod_code,prod_name) values({line})' # b''----表示字串型別是bytes型別 # %s--替代字串;%d--替代整數;%f 浮點型 # 第二個% 表示替代前面的位置,如果替代的資料有多個,則用()括起來 # 第三個% 是用來轉義作用 print(u'0ms-100ms: %s個,%.2f%%' % (num_100,num_100/totle_num*100)) print(u'100ms-500ms: %s個,%.2f%%' % (num_100_500,num_100_500/totle_num*100)) print(u'num_500_1000ms: %s個,%.2f%%' % (num_500_1000,num_500_1000/totle_num*100)) print(u'num_1000ms: %s個,%.2f%%' % (num_1000,num_1000/totle_num*100))