Как прочитать и усечь файл журнала snmptrapd без перезапуска демона

Я сделал скрипт Python, который выполняет проверку nagios. Функциональность скрипта довольно проста: он просто анализирует журнал и сопоставляет некоторую информацию, которая используется для создания вывода проверки nagios. Журнал представляет собой журнал snmptrapd, который записывает ловушки с других серверов и регистрирует их в /var/log/snmptrapd после ведьмы я просто разбираю их по сценарию. Для получения последних ловушек я стираю журнал с python каждый раз после прочтения. Чтобы сохранить информацию, я выполнил задание cron, которое копирует содержимое журнала в другой журнал с интервалом времени, немного меньшим, чем интервал проверки nagios. Я не понимаю, почему журнал так сильно растет (я имею в виду журнал сообщений, в котором, я думаю, в 1000 раз больше информации, меньше). Из того, что я видел в журнале, есть много специальных символов, таких как ^@ и я думаю, что это сделано тем, как я манипулирую файлом из питона, но, видя, что у меня с ним всего три недели опыта, я не могу понять проблему.

Код скрипта следующий:

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), и журнал занимает 161 КБ, и это не хорошо, потому что строки довольно короткие.

ОК, это никак не связано с тем, как я читаю и стираю файл. Есть что-то в демоне snmptrapd, который делает это, когда я стираю его файл журнала. Я изменил свой код, и теперь я отправляю SIGSTOP в правку snmptrapd, прежде чем открыть файл, и я делаю свои изменения в файле, а затем я отправляю 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

Я думаю о том, чтобы остановить демон, удалив файл, а затем заново создать его с соответствующими разрешениями и запустить демон.

1 ответ

Я не думаю, что вы можете, но вот несколько вещей, чтобы попробовать

Усечение файла

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

является хакерским побочным эффектом удаления содержимого файла и, вероятно, будет вызывать нежелательные побочные эффекты в зависимости от базовой ОС, если другие приложения открывают этот файл.

Использование метода File Object truncate()

truncate([size])

Обрезать размер файла. Если указан необязательный аргумент размера, файл усекается до (максимально) этого размера. Размер по умолчанию соответствует текущей позиции. Текущая позиция файла не изменяется. Обратите внимание, что если указанный размер превышает текущий размер файла, результат зависит от платформы: возможны следующие варианты: файл может остаться неизменным, увеличить его до указанного размера, как если бы он был заполнен нулями, или увеличить до указанного размера с неопределенным новым содержимым. Доступность: Windows, много вариантов Unix.

Вероятно, единственный детерминистский способ сделать это

остановить snmptrapd процесс в начале сценария, используйте надлежащие os module функция remove а затем воссоздать файл и перезапустить snmptrapd демон в конце скрипта.

os.remove(path)

Удалить (удалить) путь к файлу. Если путь является каталогом, OSError повышается; см. rmdir() ниже, чтобы удалить каталог. Это идентично функции unlink(), описанной ниже. В Windows попытка удалить используемый файл приводит к возникновению исключения; в Unix запись каталога удаляется, но хранилище, выделенное для файла, становится недоступным, пока исходный файл больше не используется.

Общий ресурсный концерн

У вас все еще могут быть проблемы с двумя процессами, пытающимися бороться за запись в один файл без какого-либо механизма блокировки и с недетерминированными вещами, происходящими с файлом. Могу поспорить, вы можете отправить SIGINT или что-то похожее на ваш процесс демона и заставьте его перечитать файл или что-то еще, проверьте документацию.

Манипулирование общими ресурсами, особенно файловыми ресурсами без эксклюзивной блокировки, будет проблематичным, особенно при кэшировании файловой системы и данных приложений.

Другие вопросы по тегам