2009-12-29 3 views
1

Mon application python comprend un programme principal et plusieurs modules. Chaque module contientNom de l'enregistreur séparé pour chaque instance d'application

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

au niveau global. Handlers et autres éléments initialisés dans le programme principal, et généralement tous les messages transmis à syslog.

Maintenant je veux lancer plusieurs instances d'application (le fichier de configuration avec le nom d'instance peut être spécifié comme paramètre de ligne de commande). La question est: comment transmettre le nom de l'instance à chaque module importé? Je veux que le nom de l'enregistreur ressemble à "myappinstance.mymodule" ou "myapp.instance.module". Et je ne veux pas jouer avec l'analyse du fichier de configuration dans chaque module, car cela nécessitera un chemin de configuration codé en dur.

Répondre

0

Eh bien, décrivant le problème aide vraiment à résoudre :) Je viens juste d'une idée d'utiliser des variables d'environnement pour passer des paramètres à tous les modules:

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'] 

$ python main.py

b: blah 
a: blah 

D'autres idées ou critiques pour celui-ci?

+0

Je ne pense pas que cela puisse résoudre votre problème. Il y a une condition de course pour passer le nom d'instance aux modules en définissant des variables d'environnement. Que faire si plusieurs instances démarrent en même temps? – iamamac

+0

Les variables d'environnement ne sont pas globales (à l'échelle de l'OS), elles sont héritées dans l'arbre de processus. Je peux lancer simultanément deux instances main.py et si chacune d'elles définit une variable evnironment spécifique, elle ne sera propagée qu'aux processus enfants. – Max

2

Voici une solution que je peux penser à:

Dans le programme principal, définissez le formatter de bûcheron nommé 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) 

Ensuite, tous les modules importés à l'aide enregistreur myapp.* contiendra instance_name dans le message d'enregistrement .

0

Il suffit d'écrire votre propre wrapper d'enregistrement qui vous donnera le nom correct (modifier au besoin pour obtenir le nom instance que vous voulez):

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) 

Ou, si l'ID de processus est assez bon pour vous, utilisez simplement que dans votre formatter:

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

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

de toute évidence, qui Uniquel y identifier chaque processus, mais ne vous donnera rien concernant l'instance.

Questions connexes