V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
fanfank
V2EX  ›  DevOps

推荐大家一个对日志文件进行二分查找的工具

  •  2
     
  •   fanfank · 2016-04-05 15:46:10 +08:00 · 4649 次点击
    这是一个创建于 2943 天前的主题,其中的信息可能已经有所发展或是发生改变。
    例如我要从 NGINX 日志或者其它业务日志中搜索一个关键字 xxx ,如果你知道这个关键字所在的大致时间区间,例如今天上午的 10 点到今天上午的 11 点 11 分,那么你可以这么搜:
    timecat -s "2016-04-05 10:00:00" -e "2016-04-05 11:11:00" access.log | grep "xxx"

    -s 和-e 分别是时间区间的起始时间和终止时间,只要是通用的时间日期格式都能识别,例如"2016/Apr/05 10:00:00",或者直接一个时间戳"1459821600"等都可以。

    为什么要做这么一个工具呢?配合线上运维工具能够很快地进行日志的关键字搜索,大大降低线上机器消耗的磁盘 IO 以及 CPU ,尤其是对动辄几个 G 的日志文件,定位速度都极其快。

    日志搜索的方案很多,统一收集后跑任务去计算,或者用流式处理等都是可选方案。但是这个工具最大的优势在于即拿即用,没有额外的机器资源以及相关的其它运维需求。
    对于创业公司早期(其实甚至到中期后期都是很好的选择之一),或者自己做项目有日志定位及搜索需求的,这个工具都十分给力。

    唯一要求就是你的环境中装了 Python 2.7+(暂不支持 Python 3 )
    地址: https://github.com/fanfank/timecat
    第 1 条附言  ·  2016-04-05 20:34:12 +08:00
    我看了回复中不少人也提到了其它的 shell 工具例如 sed , awk , grep ;也提到了比较中量级 /重量级的应用 splunk ,或者 ELK(elasticsearch + logstash/heka + kibana)等

    对于前者( sed, awk, grep ): timecat 在性能上比它们要好,前提是你指定的时间区间比整个日志中包含的时间区间要小不少,例如你的日志是 1 个小时的,你指定了 10 分钟的区间,或者你的日志是 1 天的,你指定 1 个小时的搜索范围,这些 timecat 都明显在用时、 IO 、 CPU 消耗上占明显优势

    对于后者( splunk, spark, elk...): timecat 最大的优势是轻量级,只要机器上有 python2.7.x 就可以,而且 timecat 完全不需要额外的集群去查找你的线上日志。例如你有个 A 业务分布在 10 台机器上,我可以写个脚本到 10 台机器上执行 timecat 命令然后 grep 就可以了,如果你用这些相对『重』一点的工具,你可能需要在这 10 台机器上部署日志收集 agent ,然后另外找几台流式日志处理机器(例如 5 台?),再找几台机器做存储( HBase ?),也可以。这种做法适合你的机器资源唾手可得的情况,例如我要申请 20 台机器做日志检索或者数据处理,公司立刻把机器批给你,那没问题。但是退一步讲,即便你拿到了这些机器做了流式计算、中心式收集并建立索引,仍然有一个很大劣势就是日志处理的延迟,这一秒产生的日志可能要过 2~3 分钟才能搜索到(这个已经非常快了,更多情况下可能要 5~10 分钟甚至更久)

    timecat 只是做日志搜索功能的一个辅助工具,不能把它完全和日志搜索这个事情等同起来

    希望大家多多 challenge
    11 条回复    2016-04-06 03:41:25 +08:00
    iambic
        1
    iambic  
       2016-04-05 17:52:03 +08:00
    大部分的服务应该都能做到对日志按小时切割吧,比如 nginx 这种。
    suduo1987
        2
    suduo1987  
       2016-04-05 18:14:20 +08:00 via iPhone
    为什么不用正则表达式?
    upupxjg
        3
    upupxjg  
       2016-04-05 19:07:12 +08:00
    sed 不就行了么
    vus520
        4
    vus520  
       2016-04-05 19:22:40 +08:00
    for i in $( seq 1 10); do sed ${i}0000p xxx.log ; done

    楼主说得太多了
    fanfank
        5
    fanfank  
    OP
       2016-04-05 20:13:40 +08:00
    @iambic 对,按日志切分也会非常大,日志文件也可能非常大,尤其是最前面做 Load balance 的机器。实时搜索速度是很重要的,尤其你可能需要使用 logid 去关联整个调用链,数十个日志文件,即便切分过,每个都全量去 grep 耗时会比较长
    fanfank
        6
    fanfank  
    OP
       2016-04-05 20:15:30 +08:00
    @vus520 grep 、 awk 、 timecat 的 benchmark 参见这个地址中的第 4 部分,我就是怕发太多了没人看所以没有在这里贴 benchmark : http://blog.reetsee.com/archives/502
    fanfank
        7
    fanfank  
    OP
       2016-04-05 20:17:19 +08:00
    @suduo1987 对日志文件中的每一行都用正则去判断(例如用 grep )是非常耗资源的, benchamark 参见: http://blog.reetsee.com/archives/502
    hustlike
        8
    hustlike  
       2016-04-05 20:17:24 +08:00
    为什么不用 splunk ……
    fanfank
        9
    fanfank  
    OP
       2016-04-05 20:36:47 +08:00
    @hustlike 我在这个帖子的追加内容中补充了一下, splunk 我不太了解,是不是和 ELK 等工具差不多的日志解决方案?如果是的话那起码它需要额外的机器资源,或者需要在线上服务的机器中部署收集日志的 agent 或在业务代码 /框架中发送消息到日志收集器,体量上相对大一点
    Mutoo
        10
    Mutoo  
       2016-04-05 21:03:26 +08:00
    之前对一个 500G 的基于时间排序的文本文件处理(千万行)也是自己写了一个二分查找,平均定位次数只要 log(10000000)/log(2) = 23 次就能定位到数据。效率是非常好的。
    jedihy
        11
    jedihy  
       2016-04-06 03:41:25 +08:00
    @suduo1987 正则搜大文本搜好几年。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2631 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 04:34 · PVG 12:34 · LAX 21:34 · JFK 00:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.