【问题标题】:How to write a code handle logging as argv?如何编写代码将日志记录为 argv?
【发布时间】:2021-11-15 10:33:35
【问题描述】:

在终端中,如果我执行

docker run -it --rm --name consumer --link zookeeper:zookeeper --link kafka:kafka       \
debezium/kafka:1.1 watch-topic -a bankserver1.bank.holding > C:/Users/User/python_test  \
/holding_pivot.txt

日志结果会像这样写入文件holding_pivot.txt

WARNING: Using default BROKER_ID=1, which is valid only for non-clustered installations.
Using ZOOKEEPER_CONNECT=172.17.0.3:2181
Using KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://172.17.0.6:9092
Using KAFKA_BROKER=172.17.0.4:9092
Contents of topic bankserver1.bank.holding:
{"schema":{"type":"struct","fields":[{"type":"struct","fiel...
{"schema":{"type":"struct","fields":[{"type":"struct","file...

我想要一个 python 文件在写入文件日志之前处理它(我不想要一个从日志中读取的 python 文件(因为我必须区分哪一行已经被读取和处理,哪一行没有))

代码的过程是这样的

RESULT -> Python 文件(句柄)-> 写入日志文件。

主要问题:哪个 Python 库支持它?你能给我一个示例代码吗?

我看到一个这样的文件:

docker run -it --rm --name consumer --link zookeeper:zookeeper --link kafka:kafka \
debezium/kafka:1.1 watch-topic -a bankserver1.bank.holding \
| grep --line-buffered '^{' | pipe > ./stream.py > ./holding_pivot.txt

====================== 更新======================= 根据@piertoni,我添加了这个

docker run -it --rm --name consumer --link zookeeper:zookeeper --link /
kafka:kafka  debezium/kafka:1.1 watch-topic -a bankserver1.bank.holding /
| python C:/Users/User/python_test/test_pipe.py > C:/Users/User/python_test /
/holding_pivot.txt

这是我的尝试test_pipe.py

#!/usr/bin/env python3 -u
# Note: the -u denotes unbuffered (i.e output straing to stdout without buffering data and then writing to stdout)

#!/usr/bin/env python3
import fileinput
import json
import os
import sys
from datetime import datetime

for line in sys.stdin:
    with open('log.txt', 'a') as wr:
        wr.write("Pipe success")

with open('log.txt', 'a') as wr:
    wr.write("Pipe success")

with fileinput.input() as f:
    for line in f:
        with open('log.txt', 'a') as wr:
            wr.write(f"Argument List: {str(line)}")

但是,log.txt 文件中没有写入任何内容(我只需要 python 文件可以读取初始管道的结果)。

【问题讨论】:

  • 如果我理解正确,您希望将结果通过管道传输到 python 脚本?如果这是正确的检查这个答案:stackoverflow.com/questions/66225702/…
  • 感谢@piertoni,但它仍然无法正常工作,请查看我在帖子中的更新。还有其他建议吗?
  • '它不工作':什么不工作?你希望代码做什么?它实际上是做什么的?
  • 为什么,顺便说一下,你的 python 脚本的标准输出重定向到一个文件,因为你的 python 脚本实际上从未向标准输出写入任何内容?
  • 我是否认为您希望您的 python 脚本充当管道数据的 过滤器?所以它从标准输入读取,与行做一些事情,然后写入标准输出?

标签: python


【解决方案1】:

这确实与linked question 完全相同,但为了使事情完全明确,以下是使用 python 编写流过滤器的方法:

您需要从标准输入读取处理然后写入标准输出。前者可以通过多种方式完成,但最简单的是使用fileinput。后者也可以通过多种方式完成,但如果需要,我个人只会使用print 和明确的sys.stdout.flush()。因此将它们放在一起:

import fileinput
import sys

with fileinput.input() as f:
    for line in f:
        line = line.title() # filter your lines here
        print(line, end="")
        sys.stdout.flush()
dir | python test.py # try this first, to check it works
docker_cmd | python test.py # try this second
docker_cmd | python test.py > log.txt # send the output to the log.

请注意,要么您将标准输出发送到带有 shell 重定向的文件您在 python 中处理文件写入(除非您计划将不同的内容打印到标准输出而不是您编写的到文件,这似乎不是这种情况)。

缓冲

缓冲可能意味着两件事:终端缓冲流和python自己的缓冲。 -u(至少在 python 3.9 中)不会取消缓冲标准输入。 this question 中讨论了一些取消缓冲的技术。使用 strace 运行确认您确实可以取消缓冲输入(至少在我的系统上)所以这样的事情应该避免所有 python 的 缓冲:

import sys

while line x:= sys.stdin.buffer.raw.readline():
    print("line".decode())

这在我的系统上比迭代标准输入要慢,大概是因为decode。你可以试试:

import os
u_stdin = os.fopen(sys.stdin.fileno(), "r", buffering=1)

为您提供行缓冲的文本标准输入流。显然,破坏迭代标准输入对象的bug with .next 已得到修复。但是,如果 terminal 正在缓冲管道,那么这一切都不是好事。在 linux 上我可以unbufferThis question 提出了一种方法,可能让事情为你工作。

如果您能够提供可重现的缓冲命令,我可以进一步测试。我可以使用man ssh | 等(或tail -f,同时附加到文件)获得缓冲流,但无法重现读取失败。

最后,我假设你的 docker cmd 真的输出到 stdout?不是,比如说,stderr?如果在 docker 命令中添加 2>&1 以将 stderr 发送到 stdout,会发生什么情况?你能设置一个在几秒钟内运行完成的 docker 命令,这样你就可以测试 python 从不读取任何内容?缓冲应该会减慢读取速度,但它应该阻止数据通过。

【讨论】:

  • 感谢您的贡献,但日志中没有任何内容。您提供的示例代码运行良好。我认为问题在于 docker 的输出是流式传输的(如果有任何影响,请继续给出结果),而不是 1 次输出。
  • @ChauLoi 啊;对不起。也许它那么一个缓冲问题。你可以在没有 docker 的情况下重现它吗?您是否有unbuffer 可用于强制不缓冲流(以防终端正在这样做?)。我也会用笔记更新。缓冲
  • @ChauLoi 我也可以确认 second 命令不能正常工作,即它不打印任何内容吗?
猜你喜欢
  • 1970-01-01
  • 2022-07-06
  • 2020-08-16
  • 1970-01-01
  • 2016-06-11
  • 2022-08-17
  • 2019-11-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多