V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
byfar
V2EX  ›  Python

tail -f 文件,结果交给 Python -c 处理, 思路是否可行?

  •  2
     
  •   byfar · 2018-05-25 09:58:06 +08:00 · 4467 次点击
    这是一个创建于 2404 天前的主题,其中的信息可能已经有所发展或是发生改变。

    错误的命令:

    tail -f case.log | python -c "import sys, json, time; print(json.load(sys.stdin)['type']);"
    

    此命令想要的结果: tail -f 一个文件, awk 或其它命令取到 json, 通过管理交给 python 处理. python 解析 json 并打出需要的字段.

    jq 命令可以解决这个问题,不过服务器太多,不好在每台服务上装这个命令。python 却是 linux 都带的,所以舍近求远,看有没其它的解决方法。

    第 1 条附言  ·  2018-05-25 11:53:45 +08:00
    tail -qFn0 caselog.log |  while read line ; do; python -c "import sys, json, time; print(json.loads('$line')['type']);"; done
    

    可以实现此功能,感谢提供思路。

    过分一点,能不能再精简点呢?或者其它思路,因为毕竟是命令行,少打点字想必是极好的

    16 条回复    2018-05-26 10:08:55 +08:00
    AntonChen
        1
    AntonChen  
       2018-05-25 10:30:13 +08:00
    https://gist.github.com/antonchen/0a3c513e2b09b04e2c60b52f96ccb091

    手写的不知道能不能跑,反正是这个思路
    widewing
        2
    widewing  
       2018-05-25 10:33:13 +08:00 via Android
    楼主思路我觉得挺好的啊
    lululau
        3
    lululau  
       2018-05-25 10:37:16 +08:00
    如果每行是一个 JSON 对象,可以这样处理,但是在解析前先 readline
    如果整个日志是一个 JSON 对象的话,要么把 -f 去掉(因为没有意义),要么用流式的 JSON Parser
    不要用 python 写 one-liner,要写 one-liner 用 Perl / Ruby
    predator
        4
    predator  
       2018-05-25 10:40:39 +08:00
    可行,我干过,现在还在跑,没 WAF 的服务器把 nginx 日志 tail 给 php 脚本
    lolizeppelin
        5
    lolizeppelin  
       2018-05-25 10:49:47 +08:00
    如果只是简单过滤 直接 awk 就好

    复杂处理直接整个用 python 实现 tail -f 的功能就好
    greenskinmonster
        6
    greenskinmonster  
       2018-05-25 11:05:45 +08:00   ❤️ 1
    按行处理的话可以这样,配合 supervisord 可以做 service 用

    #!/bin/bash

    tail -qFn0 /var/log/sample.log | \
    while read line ; do
    echo "$line"
    #do whatever you want
    done
    iyaozhen
        7
    iyaozhen  
       2018-05-25 11:16:13 +08:00 via Android
    用 tail -f 和 subprocess 实现过简单解析后推送到下游的脚本,稍微改改应该能满足楼主的需求

    https://github.com/iyaozhen/filebeat.py
    byfar
        8
    byfar  
    OP
       2018-05-25 11:50:12 +08:00
    @AntonChen 收下大佬的思路

    @lululau
    @lolizeppelin
    @iyaozhen
    我的场景,一行一个条日志,其中一小部分是一条 json, 所以会用 awk 或其它切成 json 再管道给后面,不写脚本是因为能一行命令解决的,我就没想写个脚本了。

    @predator

    @widewing
    @greenskinmonster
    赞赞赞,可以实现我想要的
    ```
    tail -qFn0 caselog.log | while read line ; do; python -c "import sys, json, time; print(json.loads('$line')['type']);"; done
    ```
    msg7086
        9
    msg7086  
       2018-05-25 12:36:04 +08:00
    tail -f caselog.log | jq '.type' 这样?
    araraloren
        10
    araraloren  
       2018-05-25 13:29:11 +08:00
    用 python 显的太蹩脚了,这时候还不如 perl

    tail -qFn0 caselog.log | perl -MJSON -nE 'say ((decode_json $_)->{type});'
    byfar
        11
    byfar  
    OP
       2018-05-25 13:40:12 +08:00
    @msg7086
    是的 jq 可以解决

    @araraloren
    是个好思路
    luefei
        12
    luefei  
       2018-05-25 15:40:52 +08:00
    这样处理过 apache 日志 =。=
    Dearest
        13
    Dearest  
       2018-05-25 18:25:02 +08:00
    没看懂 tail -qFn0 里的 n0 参数, 为什么要把 line num 设为 0 呢 这样不就一行都不会输出了吗
    rrfeng
        14
    rrfeng  
       2018-05-25 19:01:28 +08:00 via Android
    不要用 Python,直接正则解决。grep awk sed 都行。
    在这个场景里除非 JSON 结构很复杂导致必须要解析,否则 Python 是最慢的一环。
    byfar
        15
    byfar  
    OP
       2018-05-25 22:27:08 +08:00
    @luefei
    同需求

    @Dearest
    man tail
    ...
    -n number
    The location is number lines.
    ...
    n0 只显示命令执行后追加到文件中的内容
    n100 显示执行命令时最后 100 行,并把命令执行后追加到文件内容显示出来
    解释得不好,手动测试一下便知。这里有没有 n0 影响不大,舍弃命令执行前内容可便于观察。

    @rrfeng
    正解
    123q321
        16
    123q321  
       2018-05-26 10:08:55 +08:00
    @byfar 求大神 QQ
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1078 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 19:08 · PVG 03:08 · LAX 11:08 · JFK 14:08
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.