2014-05-02 27 views
3

我希望能夠使用Python日誌記錄工具在我的代碼中執行簡單而一致的日誌記錄。如何在函數入口處執行日誌記錄,在Python中退出並退出

我能夠做到以下幾點:

  1. 我想所有現有/未來的模塊和功能有「輸入...」和「做......」日誌消息。
  2. 我不想在每個函數定義中添加相同的代碼片段來定義日誌參數(顯示在下面)。
  3. 我希望log.info(...) etc結構在我在項目層次結構中定義的任何函數中工作。

什麼不起作用/我不知道如何做到這一點:

  1. 我想避免的是我寫的每一個現有的/新模塊中定義相同@log裝飾。從我的瓶項目
# don't want to add everywhere 
FORMAT = '%(asctime)s - %(name)-20s - %(levelname)-5s - %(message)s' 
LEVEL = logging.DEBUG 
logging.basicConfig(format=FORMAT, level=LEVEL) 
log = logging.getLogger(__name__) 


示例代碼:

# app/__init__.py 
from a import b # various other imports required for app 
import logging 
FORMAT = '%(asctime)s - %(name)-20s - %(levelname)-5s - %(message)s' 
LEVEL = logging.DEBUG 
logging.basicConfig(format=FORMAT, level=LEVEL) 
log = logging.getLogger(__name__) 
# ... various other app init code 
from app import views, models 
#app/views.py 
from c import d # various other imports required for the module 

def logger(fn): 
    from functools import wraps 
    import inspect 
    @wraps(fn) 
    def wrapper(*args, **kwargs): 
     global log 
     log = logging.getLogger(inspect.stack()[1][3]) 
     log.info('About to run %s' % fn.__name__) 

     out = apply(fn, args, kwargs) 

     log.info('Done running %s' % fn.__name__) 
     # Return the return value 
     return out 
    return wrapper 

    @app.route('/this_func') 
    @logger 
    def this_func(): 
     log.info('I am doing logging without having to do bunch of definitions.') 
     # some more code 

    @app.route('/that_func') 
    @logger 
    def that_func(): 
     log.info('Yet more logging without having to do bunch of definitions.') 
     log.info('I can simply refer to the log object and be done with it.') 
     # some more code 
+1

「理想情況下,我應該能夠做這樣的事」 ......怎麼樣「這個」不工作?你有什麼問題? – darthbith

+0

對,那個log_calls裝飾器看起來好像已經在做這個工作了。 – dano

+0

你正在調用'basicConfig()'很多次。不要這樣做。它應該只從'if __name__ =='__main __''調用一次。 –

回答

4

爲我工作的最終設置爲以下:

# At the beginning of every .py file in the project 
def logger(fn): 
    from functools import wraps 
    import inspect 
    @wraps(fn) 
    def wrapper(*args, **kwargs): 
     log = logging.getLogger(fn.__name__) 
     log.info('About to run %s' % fn.__name__) 

     out = apply(fn, args, kwargs) 

     log.info('Done running %s' % fn.__name__) 
     # Return the return value 
     return out 
    return wrapper 

# Do the following section only in application's app/__init__.py 
# Other files will pick it up from here. 
FORMAT = '%(asctime)s - %(name)s - %(levelname)s - %(funcName)s - %(message)s' 

# Change logging LEVEL according to debugging needs. 
# Probably better to read this from a config or a launch parameter. 
LEVEL = logging.DEBUG 

logging.basicConfig(format=FORMAT, level=LEVEL) 
# Up to here only for app/__init__.py 

# This section again at the beginning of every .py file 
log = logging.getLogger(__name__) 
log.info('Entered module: %s' % __name__) 

現在,添加一個@logger裝飾到每一個函數定義的模塊:

@logger 
def do_something(): 
    print('doing really useful stuff.')