簡體   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