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

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

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

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

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


    }
    ```

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

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

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