Подтвердить что ты не робот

Python: отдельные процессы регистрируются в одном файле?

Предоставляет ли библиотека Python logging сериализованное ведение журнала для двух (или более) отдельных процессов python, регистрирующихся в одном файле? Из документов (которые я прочитал) не ясно видно.

Если да, то о чем на совершенно разных машинах (где общий файл журнала будет существовать при экспорте NFS, доступном для обоих).

4b9b3361

Ответ 1

Нет, он не поддерживается. Из python logbook cookbook:

Хотя ведение журнала является потокобезопасным и протоколирование в один файл из поддерживается поддержка нескольких потоков в одном процессе, запись в один файл из нескольких процессов не поддерживается, потому что нет стандартный способ сериализации доступа к одному файлу через несколько процессов в Python.

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

Ответ 2

Одно из решений этой проблемы заключается в создании процесса регистрации, который прослушивает сокет в одном потоке, который только выводит все, что он получает

Цель состоит в том, чтобы захватить очередь сокетов в качестве арбитражного механизма.

#! /usr/bin/env python

import sys
import socket
import argparse

p = argparse.ArgumentParser()
p.add_argument("-p", "--port", help="which port to listen on", type=int)
p.add_argument("-b", "--backlog", help="accept backlog size", type=int)
p.add_argument("-s", "--buffersize", help="recv buffer size", type=int)
args = p.parse_args()

port = args.port if args.port else 1339
backlog = args.backlog if args.backlog else 5
size = args.buffersize if args.buffersize else 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', port))
s.listen(backlog)
print "Listening on port ", port, 'backlog size', backlog, 'buffer size', size, '\n'
while 1:
    try:
        (client, address) = s.accept()
        data = client.recv(size)
        print data
    except:
        client.close()

И проверить это:

#! /usr/bin/env python

import sys
import socket
import argparse

p = argparse.ArgumentParser()
p.add_argument("-p", "--port", help="send port", action='store', default=1339, type=int)
p.add_argument("text", help="text to send")
args = p.parse_args()

if not args.quit and not args.text:
    p.print_help()
else:
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect(('', args.port))
        s.send(args.text)
    except:
        s.close()

Затем используйте его следующим образом:

stdbuf -o L ./logger.py -b 10 -s 4096 >>logger.log 2>&1 &

и отслеживать последние действия с помощью:

tail -f logger.log

Каждая запись регистрации из любого заданного процесса будет испускаться атомарно. Добавление этого в стандартную систему регистрации не должно быть слишком сложным. Использование сокетов означает, что несколько компьютеров могут также ориентироваться на один журнал, размещенный на выделенной машине.

Ответ 3

Я не вижу, что это возможно из-за разрешений на доступ к файлам;

  • Если в файл записывается один процесс python, тогда при попытке открыть файл другой процесс получит исключение IOError.

Возможно, вы можете написать какой-нибудь умный код, который использует multiprocessing и Queue или Lock для доступа к очереди и доступа к счетчику, но это будет тяжелой работой.

Из интереса, почему это важно, и вы могли бы работать по-другому? Возможно, запись в два файла с отметками времени, а затем сравнение временных меток при последующем анализе?