1. 程式人生 > 其它 >python-日誌分析小工具

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))