2013-08-14 2 views
1

Я видел несколько вопросов относительно объединения журналов из разных процессов при использовании модуля многопроцессорности в Python. Я хотел бы сделать обратное, создать отдельные файлы журналов для разных процессов, и они должны регистрировать все, что происходит при вызове других модулей, не будучи искалеченным. В приведенном ниже примере у меня есть основная программа (main.py) и два модуля (module1.py и module2.py), и я хочу, чтобы главный регистратор (mainlog) записывал в stdout, что он делает хорошо. Я также хочу отдельный файл для каждого процесса, включая ведение журнала из модулей1 и module2.Регистрация отдельных файлов для разных процессов в Python

main.py:

import logging 
import multiprocessing as mpr 
import module1 
import sys 

mainlog = logging.getLogger("main") 
h = logging.StreamHandler(sys.stdout) 
mainlog.addHandler(h) 
logging.root.setLevel(logging.DEBUG) 

for i in xrange(0,3): 
    mainlog.info("Starting process ... %s", i) 
    log = logging.getLogger("module1") 
    h = logging.FileHandler("process_{0}.log".format(i)) 
    fmt = logging.Formatter(fmt="%(levelname)-10s:%(filename)-20s:%(message)s") 
    h.setFormatter(fmt) 
    log.addHandler(h) 
    log.setLevel(logging.DEBUG) 
    p = mpr.Process(target=module1.do_something, args=(i,)) 
    p.start() 

module1.py:

import logging 
import module2 

log = logging.getLogger("module1") 

def do_something(i): 

    for j in xrange(0,100): 
     log.debug("do something. process %2s. iteration %2s", i,j) 
     module2.multiply(j,2) 

И module2.py:

import logging 
log = logging.getLogger("module2") 

def multiply(x,y): 
    log.debug("... multiplying %s x %s = %s", x,y, x*y) 
    return x*y 

Вместо этого я получаю следующий вывод:

Starting process ... 0 
Starting process ... 1 
No handlers could be found for logger "module2" 
Starting process ... 2 
No handlers could be found for logger "module2" 
No handlers could be found for logger "module2" 

И 3 отдельных файла регистрации (process_0.log, ...), которые содержат сообщения от всех процессов вместе, а не только один. Ничего из модуля2.py не регистрируется. Что я делаю не так?

ответ

2

Я закончил создание подкласса logging.Logger, чтобы управлять переключением между протоколированием на главный и протоколированием на диск. Теперь я могу переключаться при необходимости внутри процесса:

import logging 
import sys 


class CGLogger(logging.Logger): 
    def __init__(self,name): 
     logging.Logger.__init__(self,name) 
     self.mainhandler = logging.StreamHandler(sys.stdout) 
     self.addHandler(self.mainhandler) 

    def stop_main_logging(self): 
     self.removeHandler(self.mainhandler) 

    def log_to_file(self, fn): 
     self.filehandler = logging.FileHandler(fn) 
     self.addHandler(self.filehandler) 

    def stop_logging_to_file(self): 
     self.removeHandler(self.filehandler) 

    def restart_main_logging(self): 
     self.addHandler(self.mainhandler) 

    def switch_to_file_logging(self, fn): 
     self.stop_main_logging() 
     self.log_to_file(fn) 

    def switch_to_main_logging(self): 
     self.stop_logging_to_file() 
     self.restart_main_logging(fn) 

logging.setLoggerClass(CGLogger) 
1

Необходимо настроить ведение журнала в дочерних процессах. Они начинаются с чистого листа, и регистрация в них не настроена. Вы в Windows, случайно? Почти ничего не наследуется от родительского процесса к дочернему процессу в Windows, тогда как в POSIX, fork() семантика может позволить некоторым вещам наследоваться.