繁体   English   中英

如何在不重新启动守护程序的情况下读取和截断snmptrapd日志文件

[英]How to read and truncate the snmptrapd log file without restarting the daemon

我做了一个执行nagios检查的python脚本。 该脚本的功能非常简单,它仅解析日志并匹配一些信息,用于构造nagios检查输出。 该日志是一个snmptrapd日志,它记录了来自其他服务器的陷阱,并将它们记录在/var/log/snmptrapd直到我用脚本解析了它们。 为了拥有最新的陷阱,我每次读取日志后都会从python中删除日志。 为了保留信息,我做了一个cron作业,它以比nagios检查间隔小的时间间隔将日志内容复制到另一个日志中。 我不明白的是为什么日志增长如此之多(我的意思是消息日志的信息量要小1000倍)。 根据我在日志中看到的内容,有很多特殊字符,例如^@ ,我认为这是通过操作pyton中的文件来完成的,但是看到我奥尔尼有3周的使用经验我似乎无法找出问题所在。

脚本代码如下:

import sys, os, re

validstring = "OK"
filename = "/var/log/snmptrapd.log"

if os.stat(filename)[6] == 0:
        print validstring
        sys.exit()

else:
        f = open(filename,"r")
        sharestring = ""
        line1 = []
        patte0 = re.compile("[0-9]+-[0-9]+-[0-9]+")
        patte2 = re.compile("NG: [a-zA-Z\s=0-9]+.*")
        for line in f:
                line1 = line.split(" ")
                if re.search(patte0,line1[0]):
                        sharestring = sharestring + line1[1] + " "
                        continue
                result2 = re.search(patte2,line)
                if result2:
                        result22 = result2.group()
                        result22 = result22.replace("NG:","")
                        sharestring = sharestring + result22 + " "
        f.close()
        f1 = open(filename,"w")
        f1.close()
        print sharestring
        sys.exit(2)

日志如下:

2012-07-11 04:17:16 Some IP(via UDP: [this is an ip]:port) TRAP, SNMP v1, community somestring
    SNMPv2-SMI::enterprises.OID Some info which is not necesarry
    SNMPv2-MIB::sysDescrOID = STRING: info which i'm matching

我很确定这与我擦除文件的方式有关,但我无法弄清楚。 如果您有任何想法,我将非常感兴趣。 谢谢。

作为有关大小的信息,我有93行(所以说Vim),对数占用161K,这并不好,因为行很短。

好的,它与我读取和删除文件的方式无关。 snmptrapd守护程序中有什么在我擦除日志文件时执行的操作。 我已经修改了代码,现在我在打开文件之前将SIGSTOP发送到snmptrapd reight,然后对文件进行了修改,然后在完成后发送SIGCONT,但似乎我遇到了同样的行为。 新代码看起来像(不同部分):

else:
    command = "pidof snmptrapd"
    p=subprocess.Popen(shlex.split(command),stdout=subprocess.PIPE)
    pidstring = p.stdout.readline()
    patte1 = re.compile("[0-9]+")
    pidnr = re.search(patte1,pidstring)
    pid = pidnr.group()
    os.kill(int(pid), SIGSTOP)
    time.sleep(0.5)
    f = open(filename,"r+")
    sharestring = ""

                  sharestring = sharestring + result22 + " "
    f.truncate(0)
    f.close()
    time.sleep(0.5)
    os.kill(int(pid), SIGCONT)
    print sharestring

我正在考虑停止守护进程擦除文件,然后以适当的权限重新创建它并启动守护进程。

我认为您不能,但是您可以尝试以下方法

截断文件

f1 = open(filename, 'w')
f1.close()

是删除文件内容的一种不良副作用,如果其他应用程序打开了该文件,则可能会导致不希望的副作用,具体取决于底层操作系统。

使用文件对象方法truncate()

truncate([size])

截断文件的大小。 如果存在可选的size参数,则文件将被截断为(最多)该大小。 尺寸默认为当前位置。 当前文件位置未更改。 请注意,如果指定的大小超过文件的当前大小,则结果取决于平台:可能的情况是文件可能保持不变,增大为指定大小(好像是零填充的)或使用未定义的新内容增大到指定的大小。 可用性:Windows,许多Unix变体。

可能唯一的确定性方法是

在脚本开始处停止snmptrapd进程,使用适当的os module功能remove ,然后重新创建文件,并在脚本末尾重新启动snmptrapd守护程序。

os.remove(path)

删除(删除)文件路径。 如果path是目录,则引发OSError;否则,将引发OSError。 请参阅下面的rmdir()删除目录。 这与下面记录的unlink()函数相同。 在Windows上,尝试删除正在使用的文件会引发异常。 在Unix上,目录条目已删除,但分配给文件的存储空间不再可用,直到不再使用原始文件为止。

共享资源问题

您可能会遇到以下问题:两个进程试图在没有某种锁定机制的情况下为写入单个文件而奋斗,并且文件上发生了不确定的事情。 我敢打赌,您可以发送SIGINT或类似于守护进程的内容,并让它重新读取文件或其他内容,请查看文档。

在没有排他锁定的情况下操作共享资源,尤其是文件资源将会很麻烦,尤其是在文件系统缓存和数据的应用程序缓存中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM