2009-12-29 3 views
1

Мое приложение python состоит из основной программы и нескольких модулей. Каждый модуль содержитОтдельное имя регистратора для каждого экземпляра приложения

import logging 
log = logging.getLogger('myapp.mymodule') 

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

Теперь я хочу запустить несколько экземпляров приложения (файл конфигурации с именем экземпляра можно указать в качестве параметра командной строки). Возникает вопрос: как передать имя экземпляра каждому импортированному модулю? Я хочу, чтобы имя регистратора выглядело как «myappinstance.mymodule» или «myapp.instance.module». И я не хочу связываться с разбором конфигурационного файла в каждом модуле, потому что для этого потребуется жестко настроенный путь конфигурации.

ответ

0

Ну, описав проблему действительно помогает в решении это :) Просто была идея использования переменных среды для передачи параметров по всем модулям:

main.py:

import os 
os.environ['instance'] = 'blah' 
import a 

a.py:

import os 
import b 
print 'a:', os.environ['instance'] 

b.py:

import os 
print 'b:', os.environ['instance'] 

$ питон main.py

b: blah 
a: blah 

Любые другие идеи или критики для этого?

+0

Я не думаю, что это решит вашу проблему. Существует гоночное условие для передачи имени экземпляра в модули путем установки переменных среды. Что делать, если несколько экземпляров запускаются одновременно? – iamamac

+0

Переменные окружения не являются глобальными (os-wide), они наследуются по дереву процессов. Я могу одновременно запустить два экземпляра main.py, и если каждый из них задает конкретную переменную evnironment, он будет распространяться только на дочерние процессы. – Max

2

Вот решение, я могу думать:

В основной программе, установите форматировщик из регистратора имени myapp

import logging 
logger = logging.getLogger("myapp") 
formatter = logging.Formatter("%(asctime)s - instance_name - %(levelname)s - %(message)s") 
ch = logging.SysLogHandler() 
ch.setFormatter(formatter) 
logger.addHandler(ch) 

Затем все импортированные модуль с помощью регистратора myapp.* будет содержать instance_name в сообщении регистрации ,

0

Просто написать свой собственный протоколирования обертку, который даст вам правильное имя (настройки по мере необходимости, чтобы получить экземпляра имя, которое вы хотите):

def get_logger(obj=None): 
    if isinstance(obj, str): 
     return logging.getLogger(obj) 
    elif obj is not None: 
     logger_name ="%s.%s" % (obj.__class__.__module__, obj.__class__.__name__) 
     return logging.getLogger(logger_name) 
    else: 
     return logging.getLogger() 

class Foo(object): 

    def __init__(self): 
     self._log = get_logger(self) 

Или, если идентификатор процесса достаточно хорошо вы просто использовать, что в вашем форматировщиком:

http://www.python.org/doc/2.5.4/lib/node421.html

formatter = logging.Formatter("%(process)d - %(asctime)s - %(levelname)s - %(message)s") 

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

Смежные вопросы