Python 如何根据打印时间获取最后一个错误字符串?

Python 如何根据打印时间获取最后一个错误字符串?,python,Python,我有一个自动更新的日志文件,如下所示: ... [23:32:19.586] PULL START [23:32:19.637] PULL RESP NONE [23:32:22.576] Rx - +CMS ERROR: 29 [23:32:22.686] STAT - TRY 2 [23:32:22.797] Tx - AT+CMGF=1 [23:32:23.008] Rx - OK [23:32:23.017] Tx - at+cmgs="number" [23:32:23.428] Rx

我有一个自动更新的日志文件,如下所示:

...
[23:32:19.586] PULL START
[23:32:19.637] PULL RESP NONE
[23:32:22.576] Rx - +CMS ERROR: 29
[23:32:22.686] STAT - TRY 2
[23:32:22.797] Tx - AT+CMGF=1
[23:32:23.008] Rx - OK
[23:32:23.017] Tx - at+cmgs="number"
[23:32:23.428] Rx - >
[23:32:23.438] Tx - message
[23:32:24.675] PULL START
[23:32:24.714] PULL RESP NONE
[23:32:26.663] Rx - +CMS ERROR: 29
[23:32:26.681] STAT - 68$$"+CMS ERROR: 29"
[23:32:26.695] SEND - RESPONSE, TRANS ID = xxxxxxxx, RESP CODE = xx, MESSAGE = +CMS ERROR: 29
[
    '+CMS ERROR: 8',
    '+CMS ERROR: 28',
    '+CMS ERROR: 29',
    '+CMS ERROR: 50',
    '+CMS ERROR: 226',
]
我有一个要比较的列表,如下所示:

...
[23:32:19.586] PULL START
[23:32:19.637] PULL RESP NONE
[23:32:22.576] Rx - +CMS ERROR: 29
[23:32:22.686] STAT - TRY 2
[23:32:22.797] Tx - AT+CMGF=1
[23:32:23.008] Rx - OK
[23:32:23.017] Tx - at+cmgs="number"
[23:32:23.428] Rx - >
[23:32:23.438] Tx - message
[23:32:24.675] PULL START
[23:32:24.714] PULL RESP NONE
[23:32:26.663] Rx - +CMS ERROR: 29
[23:32:26.681] STAT - 68$$"+CMS ERROR: 29"
[23:32:26.695] SEND - RESPONSE, TRANS ID = xxxxxxxx, RESP CODE = xx, MESSAGE = +CMS ERROR: 29
[
    '+CMS ERROR: 8',
    '+CMS ERROR: 28',
    '+CMS ERROR: 29',
    '+CMS ERROR: 50',
    '+CMS ERROR: 226',
]
我只想做的是,如果日志文件的最后一行有string+CMS错误:XX并且与列表中的一行匹配,我想终止与日志相关的程序

请注意,只要程序正在运行,日志文件就会一直随机更新,我的程序会每秒钟重新检查日志文件。如果更新日志文件上打印的最后一行不包含列表上的任何字符串,则不会终止任何程序


在python中有可能做到这一点吗?比如使用正则表达式之类的?请提供帮助。

您可以使用将文件转换为数组列表以获取文件的最后一行来执行此操作。你可以把它放在一个循环中,这样它就可以自动更新 我为这个示例选择错误号8

from os import stat

filename = 'log.txt'

statinfo = os.stat(filename)

size = int(str(statinfo.st_size).replace('L', ''))

with open(filename, 'r') as f:
    array_list = fin.seek(size/2) #the will read half of the incase the file size is and you want fast way to read your file
    array_list = array_list.readlines()
    if '+CMS ERROR: 8' in array_list[len(array_list)-1]:
        #Your Code Here

这个剧本有三个主要部分

读取并解析日志 有条件地终止进程 每x秒重复一次 第一部分很简单。让我们称之为应该行动

def应采取以下行动: 错误=['+CMS错误:8', “+CMS错误:28”, “+CMS错误:29”, “+CMS错误:50”, “+CMS错误:226”] 使用openpath/to/logfile.log作为f: 对于f中的行: 通过 在“错误中的错误”的行中返回anyerror 第二部分也不错。让我们称之为表演吧

第三部分产生了一些问题,但最终也不是很糟糕。有很多方法可以做到这一点,最好是将其安排在应用程序之外。taskschd.msc是在Windows上执行此操作的最佳方式,而cron通常是最佳方式

在应用程序中这样做,有些比其他更好。我将让您从这些解决方案中进行选择,并建议您使用操作系统来安排脚本每x秒运行一次

导入子流程 上面的两个代码块 如果uuuu name uuuuu==\uuuuuuuu main\uuuuuuuu: 如果你应该采取行动: 行为
你想不停地看这个文件?与Unix命令tail-f的功能完全相似?在编写代码指针之前,我建议为这项工作选择合适的工具。交外办理如果您想要一个过程中解决方案,请查看。如果您从子过程中轻松阅读,请考虑

中的任何解决方案。 同时,如果您每次都必须重新打开该文件,请首先查找到底,以提高效率:

with open('mylog.txt') as logf:
  logf.seek(-1024, 2)    # 2 = magic number to say "from end of file"
  last_line = logf.readlines()[-1]
  for exit_error in exit_error_strings:
    if exit_error in last_line:
      raise SystemExit    # just exit
现在,假设没有任何日志行超过1024个字符。如果这不是一个安全的假设,那么显然选择一个安全的值,或者根据需要添加额外的逻辑

关于正则表达式,它们的计算和内存通常比您想象的要昂贵,但如果您进行了测量,您还可以执行以下操作:

import re

exit_error_re = re.compile(r'\+CMS ERROR: \d\d')
...

if exit_error_re.search(last_line):
  # do something

显然,根据您的需要设置正则表达式。

您使用的是什么操作系统?用shell脚本和cron实现这一点似乎要容易得多。我使用的是windows server 2008 R2,没有理由在这里使用f.readlines,特别是因为这个文件听起来会很长。完全没有理由执行f.close,因为一旦您离开该块,它将立即关闭。我同意@AdamSmith,它将一直更新,直到第二天凌晨00:00:000创建新文件为止。@Adam4HD您在这里创建了一个语法错误您忘了关闭您的int。。。但无论如何,这不是一个好办法。为什么要读取文件的一半?@AdamSmith可以使读线运行更快,因为我们不需要文件的其余部分