首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python 学习手册
Python Cookbook
Python 基础教程
Python Sites
PyPI - Python Package Index
http://www.simple-is-better.com/
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
V2EX  ›  Python

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

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

    错误的命令:

    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
        1
    AntonChen   2018-05-25 10:30:13 +08:00


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

    复杂处理直接整个用 python 实现 tail -f 的功能就好
        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
        7
    iyaozhen   2018-05-25 11:16:13 +08:00 via Android
    用 tail -f 和 subprocess 实现过简单解析后推送到下游的脚本,稍微改改应该能满足楼主的需求

    https://github.com/iyaozhen/filebeat.py
        8
    byfar   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
    ```
        9
    msg7086   2018-05-25 12:36:04 +08:00
    tail -f caselog.log | jq '.type' 这样?
        10
    araraloren   2018-05-25 13:29:11 +08:00
    用 python 显的太蹩脚了,这时候还不如 perl

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

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

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

    @rrfeng
    正解
        16
    123q321   2018-05-26 10:08:55 +08:00
    @byfar 求大神 QQ
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   4477 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 24ms · UTC 06:15 · PVG 14:15 · LAX 23:15 · JFK 02:15
    ♥ Do have faith in what you're doing.