V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
wuzhizuiguo
V2EX  ›  Linux

Linux 根据关键字查看大文件日志,grep: memory exhausted

  •  
  •   wuzhizuiguo · 7 天前 · 2197 次点击
    日志文件 10G,原来一直用 cat /root/logs/a.out |grep -C 10 "关键词", 日志文件小的时候很快, 刚想查一下,提示 grep: memory exhausted.
    文件太大,下载到本地,notepad 也打不开.
    想用 tail -n 50000 /root/logs/a.out |grep "关键字", 随着行数增加,还是找不到数据,最后也报了 memory exhausted
    使用 less, 提示 may be a binary file. See it anyway? yes 乱码, 按网上设置后,还是打不开.
    请教下大佬们 大日志文件, 根据关键词 怎么定位附近的日志?
    37 条回复    2021-01-19 12:07:09 +08:00
    Jooooooooo
        1
    Jooooooooo   7 天前
    直接 grep

    不要 cat

    grep '关键词' 文件
    wuzhizuiguo
        2
    wuzhizuiguo   7 天前
    @Jooooooooo 还是... grep: memory exhausted
    wangbenjun5
        3
    wangbenjun5   7 天前
    1 楼正解,你用 cat 相当于要把所有数据载入到内存里面,除非你的机器有 10G 的内存,直接 grep 就可
    SuperManNoPain
        4
    SuperManNoPain   7 天前
    你要是下载到本地, 本地机器配置可以的话, windows 可以用 gitbash 进行 less 或者 grep 操作, 曲线救国吧,
    wuzhizuiguo
        5
    wuzhizuiguo   7 天前
    @SuperManNoPain 文件太大了(比下动作片还慢),本地也没有 10G 内存 会影响查看吗? (后面实在不行我准备试试)
    Jirajine
        6
    Jirajine   7 天前 via Android
    @wuzhizuiguo grep/ripgrep 都是流式操作的,多大的文件也不会占很多内存。
    dajj
        7
    dajj   7 天前   ❤️ 1
    还是命令行用的不对。 grep 不熟练

    # 查找关键词所在行及其上下各 10 行的内容
    grep 关键词 -B 10 -A 10 文件 | tee r.txt
    xuboying
        8
    xuboying   7 天前 via Android
    怀疑文件内某些行巨长,导致一行一行读也超载了。
    Lee2019
        9
    Lee2019   7 天前
    grep 我记得是按行读的,原则上不会有这个问题
    难道是你的日志某些行特别大吗?
    ulimit -a 看看是不是限制的内存太小,适当放大一些再试试
    wuzhizuiguo
        10
    wuzhizuiguo   7 天前
    @dajj 还是不行.. grep: memory exhausted
    wuzhizuiguo
        11
    wuzhizuiguo   7 天前
    @xuboying 对,是有很长的一行(多行)
    wuzhizuiguo
        12
    wuzhizuiguo   7 天前
    @Lee2019
    core file size (blocks, -c) 0
    data seg size (kbytes, -d) unlimited
    scheduling priority (-e) 0
    file size (blocks, -f) unlimited
    pending signals (-i) 127979
    max locked memory (kbytes, -l) 64
    max memory size (kbytes, -m) unlimited
    open files (-n) 65535
    pipe size (512 bytes, -p) 8
    POSIX message queues (bytes, -q) 819200
    real-time priority (-r) 0
    stack size (kbytes, -s) 8192
    cpu time (seconds, -t) unlimited
    max user processes (-u) 127979
    virtual memory (kbytes, -v) unlimited
    file locks (-x) unlimited
    dajj
        13
    dajj   7 天前
    @wuzhizuiguo 那就到达我知识的盲区了
    lululau
        14
    lululau   7 天前
    3L 瞎说,6L 正解

    估计是有些行太太太长了
    fuis
        15
    fuis   7 天前   ❤️ 1
    个人建议日志 tar 下载回来,用 UltraEdit 查看。
    privil
        16
    privil   7 天前   ❤️ 1
    论日志截断的重要性。
    liuxu
        17
    liuxu   7 天前
    tail -n 50000 > tmp.log

    看看你的 50000 有多大
    wuzhizuiguo
        18
    wuzhizuiguo   7 天前
    @liuxu 50000 12.23MB
    wuzhizuiguo
        19
    wuzhizuiguo   7 天前
    @fuis 准备日志去掉不必要的长数据行, 部分缺少的参数 加到阿里云日志里去. 下载使用 UltraEdit. grep 也确实不怎么用过..
    liuxu
        20
    liuxu   7 天前
    @wuzhizuiguo 12MB 不至于会出问题,在 grep xxx tmp.log 看看会不会报错
    calmzhu
        21
    calmzhu   7 天前 via Android   ❤️ 1
    5w 才 12m 。说明单行不大。或者大行未出现在后 5w 行。

    wc -l a.out 如果能统计出行数。那么单行不至于超过内存错误。用 grep 贴出完整命令。如果仍然报内存错误。那很可能就是中间存在某些行特别大。

    最省事的用 python/go 打开文件。不载入文件内容,而是手动控制偏移量进行没行计数。统计一下最大行的字符数。根据编码换算成字节大小。找到最大一行看看是不是过大。

    如果是顺便加个查找功能,不一次读一行就行了。


    或者用 dd 命令把文件切成 10 个约 1G 的再来 grep.这个不严谨,可能把超级行切断。但是可以试试看看结果再说
    ETiV
        22
    ETiV   7 天前
    先把 -C 参数去掉试试,保留上下文的话,内存占用肯定多

    另外加一个 --line-buffered,遇到匹配的行就立即输出
    helloworld000
        23
    helloworld000   7 天前
    用 vim 打开在 vim 里找?
    AmitabhaPk
        24
    AmitabhaPk   7 天前
    分成小块文件再检索不行么
    faqqcn
        25
    faqqcn   7 天前
    论日志采集平台的重要性
    zlowly
        26
    zlowly   7 天前
    如果是行超长,可以加多个管道 fold -w 4000 之类的强制换行,或者干脆 cut,tr 之类的强制行截取。
    fuis
        27
    fuis   7 天前
    @wuzhizuiguo 相信我,UE 是看大日志最好用的,其他什么七七八八 vim fold dd 一概都是没看过大日志的
    yzbythesea
        28
    yzbythesea   7 天前
    论日志 Json 化重要性。
    Meltdown
        29
    Meltdown   7 天前 via Android
    grep -a 试试
    lvzhiqiang
        30
    lvzhiqiang   6 天前
    将日志拆分吧,有拆分工具,split 。 或者如果格式化过的的话,要么就全部导入到 ELK 试试。
    hanxiV2EX
        31
    hanxiV2EX   6 天前 via Android
    应该从根源解决,日志文件按时间或大小进行拆分。
    php8
        32
    php8   6 天前 via Android
    @wangbenjun5 pipe 写入有容量控制,未读数据超出 buffer 大小写入会阻塞,先 cat 再 grep 多两次 memcpy,多用几 MB 内存,1000G 的文件也不会因此内存不够
    wuzhizuiguo
        33
    wuzhizuiguo   5 天前
    好的,谢谢各位大佬的帮助. 现在选择了 不定时清理日志(体积小,但是以往的结果就不能查了... 也怕几个日志大了 空间不够了)
    最终汇总下.
    小日志文件, 查看末尾几行 tail -n 500 /root/logs/a.out;
    有关键词时, cat /root/logs/a.out |grep -C 10 "关键字" , 定位"关键字"上下 10 行内容 (文件大时,grep: memory exhausted)
    或者 grep -C 10 "关键字" /root/logs/a.out (遇到我这种有超长行的, 也会 memory exhausted)
    坛友提到的 vim 打开, 这个我在其他帖子看到, 大文件也不能这样做.
    如果是 末行几行, 例如 几万行内(从时间推算), 可以用 tail -n 30000 /root/logs/a.out > tmp.out 去截取日志, 变小了,然后再去查询关键字. (行数太大,也会报错)
    tar 把文件下载回来, 用 UltraEdit 查看(不过太大了 下载也是个问题..,生成的日志 UltraEdit 中文乱码 )
    或者分割文件, 变小了再查看.
    日志可以按时间分开,每天一个文件等.
    jaliemoon
        34
    jaliemoon   4 天前
    sed -n '/2019-10-15 10:[0-9][0-9]:[0-9][0-9]/,/2019-10-15 11:[0-9][0-9]:[0-9][0-9]/'p server.log >/app/jboss/jboss-5.1.0.GA/server/ngr/log/20191015.log
    sed -n '/2020-12-09 02:[0-9][0-9]:[0-9][0-9]/,/2020-12-09 03:[0-9][0-9]:[0-9][0-9]/'p server.log >20201209server2.log
    我遇到大日志都是直接取时间区间拷贝下来看,不知道楼主能不能用上
    wuzhizuiguo
        35
    wuzhizuiguo   2 天前
    @jaliemoon 以后可能用得着 现在我们日志基本不带时间...
    grep -C 10 "关键字" /root/logs/a.out 可能会报 Binary file matches, 用 grep -a "关键字" /root/logs/a.out , 如果再想查询上下 N 行(10 行), grep -aC 10 "关键字" /root/logs/a.out
    aibangjuxin
        36
    aibangjuxin   1 天前
    logrotate 研究下。另外不要 cat 直接 grep 好几层都给这么回复的。
    aibangjuxin
        37
    aibangjuxin   1 天前
    印象中好像 fgrep 比 grep 快点 匹配规则不一样。
    关于   ·   帮助文档   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1218 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 22:34 · PVG 06:34 · LAX 14:34 · JFK 17:34
    ♥ Do have faith in what you're doing.