我正在为Web应用程序编写一个日志文件查看器,为此我想通过日志文件的行分页.文件中的项目是基于行的,底部是最新项目.
所以我需要一种tail()
方法,可以n
从底部读取行并支持偏移量.我想出的是这样的:
def tail(f, n, offset=0):
"""Reads a n lines from f with an offset of offset lines."""
avg_line_length = 74
to_read = n + offset
while 1:
try:
f.seek(-(avg_line_length * to_read), 2)
except IOError:
# woops. apparently file is smaller than what we want
# to step back, go to the beginning instead
f.seek(0)
pos = f.tell()
lines = f.read().splitlines()
if len(lines) >= to_read or pos == 0:
return lines[-to_read:offset and -offset or None]
avg_line_length …
Run Code Online (Sandbox Code Playgroud) 简而言之:我想为我的程序安装两个控制台.一个用于活动用户输入.另一个用于纯日志输出. (工作代码包括已接受的答案在下面的问题文本中,在"编辑-3"部分下面.在"编辑-1"部分和"编辑-2"部分是功能解决方法.)
为此,我有一个主命令行Python脚本,它应该只为日志输出打开一个额外的控制台.为此,我打算将日志输出重定向到第二个控制台的stdin,该日志输出将打印在主脚本的控制台上,我将其作为子进程启动.(我使用subprocess,因为我没有找到任何其他方法来打开第二个控制台.)
问题是,似乎我能够发送到第二个控制台的stdin - 但是,在第二个控制台上没有任何内容被打印出来.
以下是我用于实验的代码(在Windows 10下的PyDev上使用Python 3.4).该函数writing(input, pipe, process)
包含将生成的字符串复制到pipe
via子进程打开的控制台的as 传递的stdin的部分.函数writing(...)通过类运行writetest(Thread)
.(我留下了一些代码,我注释掉了.)
import os
import sys
import io
import time
import threading
from cmd import Cmd
from queue import Queue
from subprocess import Popen, PIPE, CREATE_NEW_CONSOLE
REPETITIONS = 3
# Position of "The class" (Edit-2)
# Position of "The class" (Edit-1)
class generatetest(threading.Thread):
def __init__(self, queue):
self.output = queue
threading.Thread.__init__(self)
def run(self):
print('run generatetest')
generating(REPETITIONS, self.output)
print('generatetest done')
def getout(self):
return self.output
class …
Run Code Online (Sandbox Code Playgroud) 我们有几个应用服务器和一个中央监控服务器.
我们目前正在从监控服务器运行带有"tail -f"的ssh,以便从应用服务器实时流式传输多个文本日志文件.
除了整个方法的脆弱性之外,问题在于杀死ssh进程有时会使僵尸尾部进程落后.我们使用-t来创建伪终端,但它仍然有时会留下僵尸进程,而且-t显然也会导致我们正在使用的作业调度产品出现问题.
作为一个廉价而肮脏的解决方案,直到我们能够获得正确的集中式日志记录(Logstash和RabbitMQ,希望如此),我希望编写一个简单的Python包装器,它将启动ssh和"tail -f",仍然捕获输出,但是将PID存储到磁盘上的文本文件中,以便我们可以在以后根据需要终止相应的尾部进程.
我最初尝试使用subprocess.Popen,但后来实际上实时获取"tail -f"输出问题(然后需要重定向到文件) - 显然会有一些阻塞/缓冲问题.
一些消息来源似乎建议使用pexpect,或pxssh或类似的东西.理想情况下,我只想使用Python,如果可能的话,它包含了库 - 但是,如果库真的是唯一的方法,那么我对此持开放态度.
有没有一个简单的方法让Python用"tail -f"启动ssh,实时将输出打印到本地STDOUT(这样我可以重定向到本地文件),并将PID保存到文件中杀了以后?或者即使我不使用ssh with tail -f,仍然可以在(近)实时流式传输远程文件,包括将PID保存到文件中?
干杯,维克多
编辑:只是为了澄清 - 我们希望在我们终止SSH进程时尾部进程死亡.
我们想从监控服务器启动ssh和"tail -f",然后在我们Ctlr-C那时,远程盒子上的尾部进程也应该死掉 - 我们不希望它留下来.通常使用-t的ssh应该修复它,但由于我不理解的原因,它不完全可靠,并且它不能很好地与我们的作业调度一起使用.
因此,使用屏幕来保持进程的另一端不是我们想要的.
这对我来说可能是一个愚蠢的运动,但它提出了一些有趣的问题.我的聊天客户端有一个日志文件目录,我希望每当其中一个更改时就会通过notify-osd通知我.
我编写的脚本基本上使用os.popen在每个文件上运行linux tail命令以获取最后一行,然后根据字典查看每行上次运行的行.如果该行更改,则使用pynotify向我发送通知.
这个脚本实际上运行得很好,除了它使用了大量的cpu(可能是因为它在每次循环运行时运行尾部大约16次,对于通过sshfs挂载的文件.)
看起来像这将是一个很好的解决方案,但我不明白如何实现对多个文件.
这是我写的脚本.请原谅我缺乏评论和糟糕的风格.
编辑:澄清一下,这是桌面上的所有Linux.