python 日誌監控與分析

一、linecache模塊

我之所以寫這個,主要是我需要分析日誌文件,但是我不想用到那個實時的日誌文件分析,而是定時分析日誌文件,故需要反覆的使用一個文件進行讀取操作,優先考慮這種方式把文件對象當成緩存,下次就不需要從頭開始讀取了。相比open()那種方法要快N倍,它是你讀取文件的效率之源。

linecache模塊的作用是將文件內容讀取到內存中,進行緩存,而不是每次都要從硬盤中讀取,這樣效率提高很多,又省去了對硬盤IO控制器的頻繁操作。

模塊linecache(行-緩存),這對於讀取內容非常多的文件,效果甚好,而且它還可以讀取指定的行內容。

linecache模塊函數講解
# -*- coding: utf-8 -*-
#python 27
 
import linecache
'''
>>> help(linecache)
Help on module linecache:
FUNCTIONS
    checkcache = extended_linecache_checkcache(filename=None, orig_checkcache=<function checkcache>)
        Extend linecache.checkcache to preserve the <pyshell#...> entries
 
        Rather than repeating the linecache code, patch it to save the
        <pyshell#...> entries, call the original linecache.checkcache()
        (skipping them), and then restore the saved entries.
 
        orig_checkcache is bound at definition time to the original
        method, allowing it to be patched.
 
    clearcache()
        Clear the cache entirely.
 
    getline(filename, lineno, module_globals=None)
 
DATA
    __all__ = ['getline', 'clearcache', 'checkcache']
'''
 
#從名爲filename的文件中得到第lineno行。這個函數從不會拋出一個異常–產生錯誤時它將返回”(換行符將包含在找到的行裏)。
 
#linecache.getline(filename,lineno)
#查找特定行(第一行)的數據,返回一個字符串
filename='1.txt'
re= linecache.getline(filename,1)
print re.strip()#因爲本身帶有換行符
 
#得到所有行數據,返回一個list
re= linecache.getlines(filename)
print re
 
#獲取多少行的數據
re= linecache.getlines(filename)[0:4]
print re
 
#更新文件名爲filename的緩存。如果filename文件更新了,使用這個函數可以更新linecache.getlines(filename)返回的列表
linecache.updatecache(filename)
 
#清理緩存
linecache.clearcache()

1 )、 linecache.getline(filename, lineno[, module_globals]) ,這個方法從filename也就是文件中讀取內容,得到第 lineno行,注意沒有去掉換行符,它將包含在行內。
2 )、 linecache.clearcache() ,清除現有的文件緩存。
3 )、 linecache.checkcache([filename]) ,參數是文件名,作用是檢查緩存內容的有效性,可能硬盤內容發生了變化,更新了,如果不提供參數,將檢查緩存中所有的項。

# coding=utf-8

import os
import linecache

def get_content(path):
    '''讀取緩存中文件內容,以字符串形式返回'''
    if os.path.exists(path):
        content = ''
        cache_data = linecache.getlines(path)
        for line in range(len(cache_data)):
            content += cache_data[line]
        return content
    else:
        print('the path [{}] is not exist!'.format(path))

def main():
    path = 'c:\\test.txt'
    content = get_content(path)
    print(content)

if __name__ == '__main__':
    main()

二、實時監控獲取日誌文件的增量內容進行分析

import time
 
def run(log_path):
    count = 0
    position = 0
 
    with open(log_path, mode='r', encoding='utf8') as f1:
        while True:
            line = f1.readline().strip()
            if line:
                count += 1
                analysis_log(line)     # 自定義分析函數
                print("count %s line %s" % (count, line))
 
            cur_position = f1.tell()  # 記錄上次讀取文件的位置
 
            if cur_position == position:
                time.sleep(0.1)
                continue
            else:
                position = cur_position
                time.sleep(0.1)
 
 
if __name__ == "__main__":
    log_path = "./nohup.log"
    run(log_path)

三、Linux服務器CPU、內存、磁盤空間、負載情況查看

# -*- coding:utf-8 -*- - 
import os, time

last_worktime=0
last_idletime=0

def get_cpu():
        global last_worktime, last_idletime
        f=open("/proc/stat","r")
        line=""
        while not "cpu " in line: line=f.readline()
        f.close()
        spl=line.split(" ")
        worktime=int(spl[2])+int(spl[3])+int(spl[4])
        idletime=int(spl[5])
        dworktime=(worktime-last_worktime)
        didletime=(idletime-last_idletime)
        rate=float(dworktime)/(didletime+dworktime)
        last_worktime=worktime
        last_idletime=idletime
        if(last_worktime==0): return 0
        return rate

def get_mem_usage_percent():
    try:
        f = open('/proc/meminfo', 'r')
        for line in f:
            if line.startswith('MemTotal:'):
                mem_total = int(line.split()[1])
            elif line.startswith('MemFree:'):
                mem_free = int(line.split()[1])
            elif line.startswith('Buffers:'):
                mem_buffer = int(line.split()[1])
            elif line.startswith('Cached:'):
                mem_cache = int(line.split()[1])
            elif line.startswith('SwapTotal:'):
                vmem_total = int(line.split()[1])
            elif line.startswith('SwapFree:'):
                vmem_free = int(line.split()[1])
            else:
                continue
        f.close()
    except:
        return None
    physical_percent = usage_percent(mem_total - (mem_free + mem_buffer + mem_cache), mem_total)
    virtual_percent = 0
    if vmem_total > 0:
        virtual_percent = usage_percent((vmem_total - vmem_free), vmem_total)
    return physical_percent, virtual_percent

def usage_percent(use, total):
    try:
        ret = (float(use) / total) * 100
    except ZeroDivisionError:
        raise Exception("ERROR - zero division error")
    return ret

statvfs = os.statvfs('/')

total_disk_space = statvfs.f_frsize * statvfs.f_blocks
free_disk_space = statvfs.f_frsize * statvfs.f_bfree
disk_usage = (total_disk_space - free_disk_space) * 100.0 / total_disk_space
disk_usage = int(disk_usage)
disk_tip = "硬盤空間使用率(最大100%):"+str(disk_usage)+"%"
print(disk_tip)

mem_usage = get_mem_usage_percent()
mem_usage = int(mem_usage[0])
mem_tip = "物理內存使用率(最大100%):"+str(mem_usage)+"%"
print(mem_tip)

cpu_usage = int(get_cpu()*100)
cpu_tip = "CPU使用率(最大100%):"+str(cpu_usage)+"%"
print(cpu_tip)

load_average = os.getloadavg()
load_tip = "系統負載(三個數值中有一個超過3就是高):"+str(load_average)
print(load_tip)

其它:
pyinotify監控文件內容變化: https://blog.51cto.com/guoshiwei/2124306
watchdog 文件變化監控:https://blog.csdn.net/cracker_zhou/article/details/50704640

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