2009-12-29 71 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 2009-12-29 18:59:19

+0

環境變量不是全局的(全局的),它們是沿着進程樹繼承的。我可以同時啓動兩個main.py實例,如果每個實例都設置特定的evnironment變量,它將只傳播給子進程。 – Max 2009-12-30 04:59:10

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) 

或者,如果進程id是夠用了您,簡單地使用你的格式:

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

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

顯然,這將uniquel Ÿ確定每個過程,但不會給你任何與實例有關的東西。

相關問題