linux java大日志二分法读取

本文介绍了一个Python2脚本,用于在日志文件中快速定位特定时间范围内的日志,通过二分查找法提高效率。作者分享了如何使用`SearchLog`类进行行首定位和时间戳搜索,适用于排查问题时定位异常日志。
摘要由CSDN通过智能技术生成

昨天同事遇到排查问题困难,异常日志没有收集在elk上,因此我推荐他根据时间进行抛出的日志定位,发现日志筛选过久,目前没有发现有什么快速定位的命令,故而使用python2进行日志定位

py2_javalogsearch.py

#!/usr/bin/python2
#coding:utf-8
#修改自https://www.cnblogs.com/liaojiafa/p/5184750.html
#linux上一般都是默认Python2
import os
import time
import sys

class SearchLog(object):

    def __init__(self, file_name):
        self.fp = open(file_name)
        self.fp.seek(0, os.SEEK_END)
        self.size = self.fp.tell()
        self.fp.seek(0, os.SEEK_SET)

    #匹配规则
    def Search_cmp(self, timestamp, line):
        return cmp(timestamp,line[0:len(timestamp)])
            
    #定位行首
    def Search_LineHead(self):#定义一个匹配每行开头的方法
        while self.fp.tell() > 0:
            self.fp.seek(-1, os.SEEK_CUR)#把文件内容的指针在当前位置往前挪一位
            val = self.fp.read(1)# 读取该指针位置的内容
            if val == '\n':#匹配该指针内容的值是否等于换行符,等于就跳出循环
                break
            self.fp.seek(-1, os.SEEK_CUR)#不等于就就继续往前挪一位查找

    #二分法查找行
    def Search_TimeStamp(self, timestamp, start_p = 0):
        fp_start = start_p
        fp_end = self.size
        while fp_start < fp_end:#判断指针开始位置是否小于结束位置
            mid = fp_start + (fp_end-fp_start)/2#找出中间值(利用二分法)
            self.fp.seek(mid, os.SEEK_SET)#通过seek定位到中间值
            self.Search_LineHead()
            line = self.fp.readline()
            val = self.Search_cmp(timestamp, line)#调用该方法能够匹配时间戳,返回值为0那么就说明找到了时间戳
            if val == 0:
                return True
            elif val == 1:
                fp_start = self.fp.tell()#如果等于1,说明当前内容的时间戳比输入的时间戳大
            else:
                fp_end = mid#如果等于其他的,说明当前内容的时间戳比输入的时间戳小,
    #找开始时间
    def Search_FirstStamp(self, timestamp, start_p = 0):

        first_point = -1
        val = self.Search_TimeStamp(timestamp, start_p)

        if val == True:
            point = self.fp.tell()#这里的逻辑是这样的==>
            while point > 0:#如果search_timestamp这个方法匹配到了时间戳,并且指针恒大于0的话,指针就在当前位置往前挪,直到匹配到换行符,再把这行通过readlie()方法整行独取出来。
                self.fp.seek(-1, os.SEEK_CUR)#此时再去匹配每行的开头是否等于时间戳,如果等于的话,那么就把指针从文件内容开头移动到匹配到时间戳的这行,标记这行为要查找的时间戳出现的第一行。
                self.Search_LineHead()
                point = self.fp.tell()
                line = self.fp.readline()
                # print line
                if self.Search_cmp(timestamp,line) <=0:#继续往上搜索
                    self.fp.seek(point, os.SEEK_SET)
                    continue
                first_point = self.fp.tell()
                break

        return first_point

    def Search_EndStamp(self, timestamp, start_p = 0):

        last_point = -1
        val = self.Search_TimeStamp(timestamp, start_p)
        if val == True:#道理同上,不过这个的就反转过来,用来查找要查找的时间戳的最后一行。
            last_point = self.fp.tell()
            while last_point < self.size:
                line = self.fp.readline()
                if self.Search_cmp(timestamp,line) >=0: #往下搜索
                    last_point = self.fp.tell()
                    continue
                # print line
                self.fp.seek(last_point, os.SEEK_SET)
                break

            return last_point

    #导出中间行
    def Search_Dump(self, s_p, e_p):#把查找到的内容写入日志
        self.fp.seek(s_p, os.SEEK_SET)
        dumpname="lastSearch.log"
        f_log=open(dumpname,'wb')
        while self.fp.tell() < e_p:
            print self.fp.readline(),
            f_log.write(self.fp.readline())
        f_log.close()
        print "dump in "+dumpname

    def Search_DeInit(self):
        self.fp.close()

if __name__ == '__main__':
    if len(sys.argv)!=4:
        print '用法:\n\t本脚本 开始时间 结束时间 日志路径\n例子:\n\tpython '+sys.argv[0]+' "2021-04-14 15:26" "2021-04-14 15:29" /opt/logs/*/log/all.log'
    else:
        time_s = time.time()
        obj = SearchLog(sys.argv[3])
        s_point = obj.Search_FirstStamp(sys.argv[1])
        if s_point > -1:
            e_point = obj.Search_EndStamp(sys.argv[2], s_point)
        if s_point > -1:
            print s_point , e_point
            obj.Search_Dump(s_point, e_point)
        else:
            print "not find"
        print "use time",time.time()-time_s,"s"
        obj.Search_DeInit()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值