Distributions
› Ubuntu
› Fedora
› CentOS
中文资源站
› 网易开源镜像站
lzjamao
V2EX  ›  Linux

tail -f 打印有延迟,有更好实时打印 log 的工具么?

  •  
  •   lzjamao · Dec 5, 2017 · 8410 views
    This topic created in 3254 days ago, the information mentioned may be changed or developed.

    tail -s 设置 X 秒扫描文本(单位秒),

    但是,我的程序 1 秒内,有大量 IO 输出操作,另外加上 IO 延迟。有好多 LOG 输出延迟,影响看 LOG 的逻辑思路。

    希望能满足后台启动程序的条件下,有更好实时显示 LOG 的方法

    Supplement 1  ·  Dec 5, 2017
    // 程序启动各种 Engine 
    int Application::Init() 
    { 
        // Engine,打印各种 LOG
    
        // Loop在最后执行 
        this->Loop()
    } 
    
    // 更新各种 Engine 逻辑 
    void Application::Loop() 
    { 
        while(true) 
        { 
            printf("loop") 
            Engine.Loop(); 
            // .... 
            sleep(1) 
        } 
    } 
    

    逻辑上,Application::Init先于Application::Loop执行,那么Application::Init内触发LOG,应早于Application::Loopprint("loop")打印。 tail -f 实际情况系,Application::Init后小部的LOG,在比较固定地打印7次左右的printf("loop")才出现,

    Supplement 2  ·  Dec 5, 2017
    虽然可以去掉 printf("loop"),先绕过问题。
    但是,这个问题难免再次出现,影响开发。

    另外,感谢各位的回答
    Supplement 3  ·  Dec 5, 2017

    相同的程序,我对比加或不加nohup启动程序 log打印区别

    不加nohup: 所有Application::Init里触发的log,都符合逻辑打印显示 加nohup: Application::Init里逻辑靠后(但在this->Loop前),小部分LOG,在几次printf("loop")后,才出现。此 时,vim log文体内容也是”小部分LOG,在几次printf("loop")后“

    为了贴出log的对比,我加回了print("loop"),问题是.....什么就好了呀!!!!!我晕😀

    36 replies  •  2017-12-08 15:56:43 +08:00
    QAPTEAWH
    QAPTEAWH
    Dec 5, 2017
    1
    你确定延迟不是在写入端产生的么...
    GuiPulp
    GuiPulp
    Dec 5, 2017
    2
    你居然对一个用了 20 多年的命令产生了怀疑
    YMB
    YMB
    Dec 5, 2017
    3
    你居然对一个用了 20 多年的命令产生了怀疑
    privil
    privil
    Dec 5, 2017
    4
    大量的 IO 输出,你想想人眼能看过来么,我就问……不过 tail -f 的问题我总觉得在于 ssh 传输的延迟上面
    xlrtx
    xlrtx
    Dec 5, 2017
    5
    记得 python 有 buffer, 可以加-u
    lzjamao
    lzjamao
    OP
    Dec 5, 2017
    6
    @QAPTEAWH 对比用 nohup 与不用的情况下,有些 LOG 在 nohup 下延迟 7、8 秒才出现
    phttc
    phttc
    Dec 5, 2017
    7
    一个大池子,,,写入端 以 10L 每秒的速度 倒水,,而你读取端 每秒只能消化 5L,,,你说的延迟,,是你终端来不及输出,,并不会阻塞写入端的行为
    lzjamao
    lzjamao
    OP
    Dec 5, 2017
    8
    @privil 对比用 nohup 与不用的情况下,有些 LOG 在 nohup 下延迟 7、8 秒才出现
    lzjamao
    lzjamao
    OP
    Dec 5, 2017
    9
    @phttc 我认同终端可能不及输出的可能,我用的是 xshell,局域网内 ssh
    lzjamao
    lzjamao
    OP
    Dec 5, 2017
    10
    @phttc 有更好的 倒水=》接水 做法么?
    b821025551b
    b821025551b
    Dec 5, 2017
    11
    大量 IO,那不得刷屏么,我只好奇眼睛能看过来?
    shoaly
    shoaly
    Dec 5, 2017
    12
    我就是楼上提到的 "眼睛看不过来的那种人" , 所以我一般都是直接用 vim 日志, 然后 :e 手动刷新...
    Victor215
    Victor215
    Dec 5, 2017
    13
    你可以测试一下你的硬盘 io 性能,是不是 io 有问题
    time dd if=/dev/zero of=/test.dbf bs=32k count=1000
    Victor215
    Victor215
    Dec 5, 2017
    14
    @shoaly 日志能用 vim 打开,说明日志量不大啊
    acoder2013
    acoder2013
    Dec 5, 2017
    15
    @Victor215 tail -f 的内容才输出到 vim。。。
    lonenol
    lonenol
    Dec 5, 2017
    16
    看啥日志需要这么实时...
    vus520
    vus520
    Dec 5, 2017
    17
    你居然对一个用了 20 多年的命令产生了怀疑
    privil
    privil
    Dec 5, 2017
    18
    @Victor215 日志轮转完每天的大小还用 vim 看的,打开比较快,要是有大日志肯定上 ELK 啥的了
    vincenttone
    vincenttone
    Dec 5, 2017
    19
    既然是局域网内 ssh,不考虑网络延迟,tail
    vincenttone
    vincenttone
    Dec 5, 2017
    20
    @vincenttone tail 应该是个死循环拿的,应该是写日志那头的延迟。
    一般来讲,写日志不会产生就往里写,不然磁盘的 io 受不了,一般都是弄一个 buffer,buffer 满了且碰到了换行再往文件里 flush,然后继续指导进程退出做最后一次 flush。所以到底多久 flush 一次,取决于你的日志的量,如果是量很大的 log,条数也多,flush 也更频繁一些,不然最后那点日志可能要等进程退出才给 flush。
    chcx
    chcx
    Dec 5, 2017
    21
    本地磁盘 tailf 延迟 7-8s,你确定?
    文件几十 G ?不是初次 tailf ?
    Tony8Finet
    Tony8Finet
    Dec 5, 2017
    22
    印象中有些程式会依 stdout 是否为 tty 模式,而决定是否要缓冲输出。是否是这样才会在 pipe 到 "tail -f" 时有所延迟?

    最好是贴出你有问题的完整语句,或是追踪上游程式的输出行为,才好判断。
    WhoMercy
    WhoMercy
    Dec 5, 2017 via Android
    23
    接上面倒水比出水快的:开多个水龙头
    用 grep 过滤部分 log,多个终端显示不同标识的 log。
    (都是同类 log 加随机标识或 ts )
    lzjamao
    lzjamao
    OP
    Dec 5, 2017
    24
    @chcx 有两段逻辑,Application::Init</br>

    ```
    // 程序启动各种 Engine
    int Application::Init()
    {
    // Engine,打印各种 LOG


    }
    ```

    ```
    // 更新各种 Engine 逻辑
    Application::Loop()
    {
    while(true)
    {
    printf("loop")
    Engine.Loop();
    // ....
    sleep(1)
    }
    }
    ```
    lzjamao
    lzjamao
    OP
    Dec 5, 2017
    25
    @lzjamao 忽略此回复,看追帖
    extreme
    extreme
    Dec 5, 2017 via iPhone❤️1
    26
    printf()…

    个人感觉很有可能是 stdio 的 I/O buffer 导致的,可以尝试调用 output 函数后调用 fflush()。
    extreme
    extreme
    Dec 5, 2017 via iPhone
    27
    最好能确认下 Engine LOG 的输出方式,用的是哪些函数。

    理论上不是 tail 的问题,应该是 OUTPUT Buffer 的问题。
    shiny
    shiny
    PRO
    Dec 5, 2017❤️1
    28
    以前写 Python 的时候也遇到过这个问题,flush 刷下就好了。
    bbsteel
    bbsteel
    Dec 5, 2017 via Android
    29
    lz 一目百行的能力让人叹服
    phoneli
    phoneli
    Dec 5, 2017
    30
    试试加一个 fflush
    jasontse
    jasontse
    Dec 5, 2017 via iPad
    31
    用内核提供的 inotify,再延迟就是你输出的问题。
    lzjamao
    lzjamao
    OP
    Dec 5, 2017
    32
    @extreme 好的我看看,感谢你的回复
    lzjamao
    lzjamao
    OP
    Dec 5, 2017
    33
    @shiny 好的我看看,感谢你的回复
    jy01264313
    jy01264313
    Dec 6, 2017❤️1
    34
    如果你是用 nohup 启动的命令,本身 stdout 是有缓存在的,可以试试 stdbuf -o0 nohup xxx &
    lzjamao
    lzjamao
    OP
    Dec 8, 2017
    35
    @jy01264313 get it!!! :thumbsup:
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1430 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 61ms · UTC 22:30 · PVG 06:30 · LAX 14:30 · JFK 17:30
    ♥ Do have faith in what you're doing.